Trying to fix resume_handling for srvsvc_NetShareEnumAll.
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_srvsvc_nt.c
blob6421efdf8f71e26cfd78bb3ea2e95bee955aec9c
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 int count;
38 FILE_INFO_3 *info;
41 struct sess_file_count {
42 struct server_id pid;
43 uid_t uid;
44 int count;
47 /****************************************************************************
48 Count the entries belonging to a service in the connection db.
49 ****************************************************************************/
51 static int pipe_enum_fn( struct db_record *rec, void *p)
53 struct pipe_open_rec prec;
54 struct file_enum_count *fenum = (struct file_enum_count *)p;
55 FILE_INFO_3 *f;
56 int i = fenum->count;
57 char *fullpath = NULL;
58 const char *username;
60 if (rec->value.dsize != sizeof(struct pipe_open_rec))
61 return 0;
63 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
65 if ( !process_exists(prec.pid) ) {
66 return 0;
69 username = uidtoname(prec.uid);
71 if ((fenum->username != NULL)
72 && !strequal(username, fenum->username)) {
73 return 0;
76 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
77 if (!fullpath) {
78 return 1;
81 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
82 if ( !f ) {
83 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
84 return 1;
86 fenum->info = f;
88 init_srv_file_info3(
89 &fenum->info[i],
90 (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
91 (FILE_READ_DATA|FILE_WRITE_DATA),
92 0, username, fullpath);
94 TALLOC_FREE(fullpath);
95 fenum->count++;
97 return 0;
100 /*******************************************************************
101 ********************************************************************/
103 static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username,
104 FILE_INFO_3 **info,
105 uint32 *count, uint32 resume )
107 struct file_enum_count fenum;
109 fenum.ctx = ctx;
110 fenum.username = username;
111 fenum.count = *count;
112 fenum.info = *info;
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 *info = fenum.info;
121 *count = fenum.count;
123 return WERR_OK;
126 /*******************************************************************
127 ********************************************************************/
129 static void enum_file_fn( const struct share_mode_entry *e,
130 const char *sharepath, const char *fname,
131 void *private_data )
133 struct file_enum_count *fenum =
134 (struct file_enum_count *)private_data;
136 FILE_INFO_3 *f;
137 int i = fenum->count;
138 files_struct fsp;
139 struct byte_range_lock *brl;
140 int num_locks = 0;
141 char *fullpath = NULL;
142 uint32 permissions;
143 const char *username;
145 /* If the pid was not found delete the entry from connections.tdb */
147 if ( !process_exists(e->pid) ) {
148 return;
151 username = uidtoname(e->uid);
153 if ((fenum->username != NULL)
154 && !strequal(username, fenum->username)) {
155 return;
158 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 );
159 if ( !f ) {
160 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
161 return;
163 fenum->info = 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 FILE_INFO_3 struct */
190 init_srv_file_info3( &fenum->info[i],
191 e->share_file_id,
192 permissions,
193 num_locks,
194 username,
195 fullpath );
197 TALLOC_FREE(fullpath);
198 fenum->count++;
201 /*******************************************************************
202 ********************************************************************/
204 static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username,
205 FILE_INFO_3 **info,
206 uint32 *count, uint32 resume )
208 struct file_enum_count f_enum_cnt;
210 f_enum_cnt.ctx = ctx;
211 f_enum_cnt.username = username;
212 f_enum_cnt.count = *count;
213 f_enum_cnt.info = *info;
215 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
217 *info = f_enum_cnt.info;
218 *count = f_enum_cnt.count;
220 return WERR_OK;
223 /*******************************************************************
224 Utility function to get the 'type' of a share from an snum.
225 ********************************************************************/
226 static uint32 get_share_type(int snum)
228 /* work out the share type */
229 uint32 type = STYPE_DISKTREE;
231 if (lp_print_ok(snum))
232 type = STYPE_PRINTQ;
233 if (strequal(lp_fstype(snum), "IPC"))
234 type = STYPE_IPC;
235 if (lp_administrative_share(snum))
236 type |= STYPE_HIDDEN;
238 return type;
241 /*******************************************************************
242 Fill in a share info level 0 structure.
243 ********************************************************************/
245 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
247 const char *net_name = lp_servicename(snum);
249 init_srvsvc_NetShareInfo0(r, net_name);
252 /*******************************************************************
253 Fill in a share info level 1 structure.
254 ********************************************************************/
256 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
258 char *net_name = lp_servicename(snum);
259 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
261 if (remark) {
262 remark = standard_sub_conn(p->mem_ctx,
263 p->conn,
264 remark);
267 init_srvsvc_NetShareInfo1(r, net_name,
268 get_share_type(snum),
269 remark ? remark : "");
272 /*******************************************************************
273 Fill in a share info level 2 structure.
274 ********************************************************************/
276 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
278 char *remark = NULL;
279 char *path = NULL;
280 int max_connections = lp_max_connections(snum);
281 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
282 int count = 0;
283 char *net_name = lp_servicename(snum);
285 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
286 if (remark) {
287 remark = standard_sub_conn(p->mem_ctx,
288 p->conn,
289 remark);
291 path = talloc_asprintf(p->mem_ctx,
292 "C:%s", lp_pathname(snum));
294 if (path) {
296 * Change / to \\ so that win2k will see it as a valid path.
297 * This was added to enable use of browsing in win2k add
298 * share dialog.
301 string_replace(path, '/', '\\');
304 count = count_current_connections(net_name, false);
306 init_srvsvc_NetShareInfo2(r, net_name,
307 get_share_type(snum),
308 remark ? remark : "",
310 max_uses,
311 count,
312 path ? path : "",
313 "");
316 /*******************************************************************
317 Map any generic bits to file specific bits.
318 ********************************************************************/
320 static void map_generic_share_sd_bits(SEC_DESC *psd)
322 int i;
323 SEC_ACL *ps_dacl = NULL;
325 if (!psd)
326 return;
328 ps_dacl = psd->dacl;
329 if (!ps_dacl)
330 return;
332 for (i = 0; i < ps_dacl->num_aces; i++) {
333 SEC_ACE *psa = &ps_dacl->aces[i];
334 uint32 orig_mask = psa->access_mask;
336 se_map_generic(&psa->access_mask, &file_generic_mapping);
337 psa->access_mask |= orig_mask;
341 /*******************************************************************
342 Fill in a share info level 501 structure.
343 ********************************************************************/
345 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
347 const char *net_name = lp_servicename(snum);
348 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
350 if (remark) {
351 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
354 init_srvsvc_NetShareInfo501(r, net_name,
355 get_share_type(snum),
356 remark ? remark : "",
357 (lp_csc_policy(snum) << 4));
360 /*******************************************************************
361 Fill in a share info level 502 structure.
362 ********************************************************************/
364 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
366 const char *net_name = lp_servicename(snum);
367 char *path = NULL;
368 SEC_DESC *sd = NULL;
369 size_t sd_size = 0;
370 TALLOC_CTX *ctx = p->mem_ctx;
371 char *remark = talloc_strdup(ctx, lp_comment(snum));;
373 if (remark) {
374 remark = standard_sub_conn(ctx, p->conn, remark);
376 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
377 if (path) {
379 * Change / to \\ so that win2k will see it as a valid path. This was added to
380 * enable use of browsing in win2k add share dialog.
382 string_replace(path, '/', '\\');
385 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
387 init_srvsvc_NetShareInfo502(r, net_name,
388 get_share_type(snum),
389 remark ? remark : "",
391 0xffffffff,
393 path ? path : "",
396 sd);
399 /***************************************************************************
400 Fill in a share info level 1004 structure.
401 ***************************************************************************/
403 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
405 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
407 if (remark) {
408 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
411 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
414 /***************************************************************************
415 Fill in a share info level 1005 structure.
416 ***************************************************************************/
418 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
420 uint32_t dfs_flags = 0;
422 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
423 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
426 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
428 init_srvsvc_NetShareInfo1005(r, dfs_flags);
431 /***************************************************************************
432 Fill in a share info level 1006 structure.
433 ***************************************************************************/
435 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
437 init_srvsvc_NetShareInfo1006(r, 0xffffffff);
440 /***************************************************************************
441 Fill in a share info level 1007 structure.
442 ***************************************************************************/
444 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
446 uint32 flags = 0;
448 init_srvsvc_NetShareInfo1007(r, flags, "");
451 /*******************************************************************
452 Fill in a share info level 1501 structure.
453 ********************************************************************/
455 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
457 SEC_DESC *sd;
458 size_t sd_size;
459 TALLOC_CTX *ctx = p->mem_ctx;
461 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
463 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
466 /*******************************************************************
467 True if it ends in '$'.
468 ********************************************************************/
470 static bool is_hidden_share(int snum)
472 const char *net_name = lp_servicename(snum);
474 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
477 /*******************************************************************
478 Fill in a share info structure.
479 ********************************************************************/
481 static WERROR init_srv_share_info_ctr(pipes_struct *p,
482 struct srvsvc_NetShareInfoCtr *info_ctr,
483 uint32_t *resume_handle_p,
484 uint32_t *total_entries,
485 bool all_shares)
487 int num_entries = 0;
488 int alloc_entries = 0;
489 int num_services = 0;
490 int snum;
491 TALLOC_CTX *ctx = p->mem_ctx;
492 int i = 0;
493 int valid_share_count = 0;
494 union srvsvc_NetShareCtr ctr;
495 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
497 DEBUG(5,("init_srv_share_info_ctr\n"));
499 /* Ensure all the usershares are loaded. */
500 become_root();
501 num_services = load_usershare_shares();
502 load_registry_shares();
503 unbecome_root();
505 /* Count the number of entries. */
506 for (snum = 0; snum < num_services; snum++) {
507 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
508 num_entries++;
512 if (!num_entries || (resume_handle >= num_entries)) {
513 return WERR_OK;
516 /* Calculate alloc entries. */
517 alloc_entries = num_entries - resume_handle;
518 switch (info_ctr->level) {
519 case 0:
520 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
521 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
523 ctr.ctr0->count = alloc_entries;
524 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
525 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
527 for (snum = 0; snum < num_services; snum++) {
528 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
529 (resume_handle <= (i + valid_share_count++)) ) {
530 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
534 break;
536 case 1:
537 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
538 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
540 ctr.ctr1->count = alloc_entries;
541 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
542 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
544 for (snum = 0; snum < num_services; snum++) {
545 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
546 (resume_handle <= (i + valid_share_count++)) ) {
547 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
551 break;
553 case 2:
554 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
555 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
557 ctr.ctr2->count = alloc_entries;
558 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
559 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
561 for (snum = 0; snum < num_services; snum++) {
562 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
563 (resume_handle <= (i + valid_share_count++)) ) {
564 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
568 break;
570 case 501:
571 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
572 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
574 ctr.ctr501->count = alloc_entries;
575 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
576 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
578 for (snum = 0; snum < num_services; snum++) {
579 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
580 (resume_handle <= (i + valid_share_count++)) ) {
581 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
585 break;
587 case 502:
588 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
589 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
591 ctr.ctr502->count = alloc_entries;
592 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
593 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
595 for (snum = 0; snum < num_services; snum++) {
596 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
597 (resume_handle <= (i + valid_share_count++)) ) {
598 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
602 break;
604 case 1004:
605 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
606 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
608 ctr.ctr1004->count = alloc_entries;
609 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
610 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
612 for (snum = 0; snum < num_services; snum++) {
613 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
614 (resume_handle <= (i + valid_share_count++)) ) {
615 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
619 break;
621 case 1005:
622 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
623 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
625 ctr.ctr1005->count = alloc_entries;
626 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
627 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
629 for (snum = 0; snum < num_services; snum++) {
630 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
631 (resume_handle <= (i + valid_share_count++)) ) {
632 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
636 break;
638 case 1006:
639 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
640 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
642 ctr.ctr1006->count = alloc_entries;
643 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
644 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
646 for (snum = 0; snum < num_services; snum++) {
647 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
648 (resume_handle <= (i + valid_share_count++)) ) {
649 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
653 break;
655 case 1007:
656 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
657 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
659 ctr.ctr1007->count = alloc_entries;
660 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
661 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
663 for (snum = 0; snum < num_services; snum++) {
664 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
665 (resume_handle <= (i + valid_share_count++)) ) {
666 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
670 break;
672 case 1501:
673 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
674 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
676 ctr.ctr1501->count = alloc_entries;
677 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
678 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
680 for (snum = 0; snum < num_services; snum++) {
681 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
682 (resume_handle <= (i + valid_share_count++)) ) {
683 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
687 break;
689 default:
690 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
691 info_ctr->level));
692 return WERR_UNKNOWN_LEVEL;
695 *total_entries = alloc_entries;
696 if (resume_handle_p) {
697 if (all_shares) {
698 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
699 } else {
700 *resume_handle_p = num_entries;
704 info_ctr->ctr = ctr;
706 return WERR_OK;
709 /*******************************************************************
710 fill in a sess info level 0 structure.
711 ********************************************************************/
713 static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
715 struct sessionid *session_list;
716 uint32 num_entries = 0;
717 (*stot) = list_sessions(p->mem_ctx, &session_list);
719 if (ss0 == NULL) {
720 if (snum) {
721 (*snum) = 0;
723 return;
726 DEBUG(5,("init_srv_sess_0_ss0\n"));
728 if (snum) {
729 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
730 init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine);
731 num_entries++;
734 ss0->num_entries_read = num_entries;
735 ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
736 ss0->num_entries_read2 = num_entries;
738 if ((*snum) >= (*stot)) {
739 (*snum) = 0;
742 } else {
743 ss0->num_entries_read = 0;
744 ss0->ptr_sess_info = 0;
745 ss0->num_entries_read2 = 0;
749 /*******************************************************************
750 ********************************************************************/
752 static void sess_file_fn( const struct share_mode_entry *e,
753 const char *sharepath, const char *fname,
754 void *data )
756 struct sess_file_count *sess = (struct sess_file_count *)data;
758 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
759 sess->count++;
762 return;
765 /*******************************************************************
766 ********************************************************************/
768 static int net_count_files( uid_t uid, struct server_id pid )
770 struct sess_file_count s_file_cnt;
772 s_file_cnt.count = 0;
773 s_file_cnt.uid = uid;
774 s_file_cnt.pid = pid;
776 share_mode_forall( sess_file_fn, &s_file_cnt );
778 return s_file_cnt.count;
781 /*******************************************************************
782 fill in a sess info level 1 structure.
783 ********************************************************************/
785 static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
787 struct sessionid *session_list;
788 uint32 num_entries = 0;
789 time_t now = time(NULL);
791 if ( !snum ) {
792 ss1->num_entries_read = 0;
793 ss1->ptr_sess_info = 0;
794 ss1->num_entries_read2 = 0;
796 (*stot) = 0;
798 return;
801 if (ss1 == NULL) {
802 (*snum) = 0;
803 return;
806 (*stot) = list_sessions(p->mem_ctx, &session_list);
809 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) {
810 uint32 num_files;
811 uint32 connect_time;
812 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
813 bool guest;
815 if ( !pw ) {
816 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
817 session_list[*snum].username));
818 continue;
821 connect_time = (uint32)(now - session_list[*snum].connect_start);
822 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
823 guest = strequal( session_list[*snum].username, lp_guestaccount() );
825 init_srv_sess_info1( &ss1->info_1[num_entries],
826 session_list[*snum].remote_machine,
827 session_list[*snum].username,
828 num_files,
829 connect_time,
831 guest);
832 num_entries++;
835 ss1->num_entries_read = num_entries;
836 ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
837 ss1->num_entries_read2 = num_entries;
839 if ((*snum) >= (*stot)) {
840 (*snum) = 0;
845 /*******************************************************************
846 makes a SRV_R_NET_SESS_ENUM structure.
847 ********************************************************************/
849 static WERROR init_srv_sess_info_ctr(pipes_struct *p, SRV_SESS_INFO_CTR *ctr,
850 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
852 WERROR status = WERR_OK;
853 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
855 ctr->switch_value = switch_value;
857 switch (switch_value) {
858 case 0:
859 init_srv_sess_info_0(p, &(ctr->sess.info0), resume_hnd, total_entries);
860 ctr->ptr_sess_ctr = 1;
861 break;
862 case 1:
863 init_srv_sess_info_1(p, &(ctr->sess.info1), resume_hnd, total_entries);
864 ctr->ptr_sess_ctr = 1;
865 break;
866 default:
867 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
868 (*resume_hnd) = 0;
869 (*total_entries) = 0;
870 ctr->ptr_sess_ctr = 0;
871 status = WERR_UNKNOWN_LEVEL;
872 break;
875 return status;
878 /*******************************************************************
879 makes a SRV_R_NET_SESS_ENUM structure.
880 ********************************************************************/
882 static void init_srv_r_net_sess_enum(pipes_struct *p, SRV_R_NET_SESS_ENUM *r_n,
883 uint32 resume_hnd, int sess_level, int switch_value)
885 DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
887 r_n->sess_level = sess_level;
889 if (sess_level == -1)
890 r_n->status = WERR_UNKNOWN_LEVEL;
891 else
892 r_n->status = init_srv_sess_info_ctr(p, r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
894 if (!W_ERROR_IS_OK(r_n->status))
895 resume_hnd = 0;
897 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
900 /*******************************************************************
901 fill in a conn info level 0 structure.
902 ********************************************************************/
904 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
906 uint32 num_entries = 0;
907 (*stot) = 1;
909 if (ss0 == NULL) {
910 (*snum) = 0;
911 return;
914 DEBUG(5,("init_srv_conn_0_ss0\n"));
916 if (snum) {
917 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
919 init_srv_conn_info0(&ss0->info_0[num_entries], (*stot));
921 /* move on to creating next connection */
922 /* move on to creating next conn */
923 num_entries++;
926 ss0->num_entries_read = num_entries;
927 ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
928 ss0->num_entries_read2 = num_entries;
930 if ((*snum) >= (*stot)) {
931 (*snum) = 0;
934 } else {
935 ss0->num_entries_read = 0;
936 ss0->ptr_conn_info = 0;
937 ss0->num_entries_read2 = 0;
939 (*stot) = 0;
943 /*******************************************************************
944 fill in a conn info level 1 structure.
945 ********************************************************************/
947 static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
948 uint32 id, uint32 type,
949 uint32 num_opens, uint32 num_users, uint32 open_time,
950 const char *usr_name, const char *net_name)
952 init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
953 init_srv_conn_info1_str(str1, usr_name, net_name);
956 /*******************************************************************
957 fill in a conn info level 1 structure.
958 ********************************************************************/
960 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
962 uint32 num_entries = 0;
963 (*stot) = 1;
965 if (ss1 == NULL) {
966 (*snum) = 0;
967 return;
970 DEBUG(5,("init_srv_conn_1_ss1\n"));
972 if (snum) {
973 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) {
974 init_srv_conn_1_info(&ss1->info_1[num_entries],
975 &ss1->info_1_str[num_entries],
976 (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
978 /* move on to creating next connection */
979 /* move on to creating next conn */
980 num_entries++;
983 ss1->num_entries_read = num_entries;
984 ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
985 ss1->num_entries_read2 = num_entries;
988 if ((*snum) >= (*stot)) {
989 (*snum) = 0;
992 } else {
993 ss1->num_entries_read = 0;
994 ss1->ptr_conn_info = 0;
995 ss1->num_entries_read2 = 0;
997 (*stot) = 0;
1001 /*******************************************************************
1002 makes a SRV_R_NET_CONN_ENUM structure.
1003 ********************************************************************/
1005 static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
1006 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1008 WERROR status = WERR_OK;
1009 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1011 ctr->switch_value = switch_value;
1013 switch (switch_value) {
1014 case 0:
1015 init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries);
1016 ctr->ptr_conn_ctr = 1;
1017 break;
1018 case 1:
1019 init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries);
1020 ctr->ptr_conn_ctr = 1;
1021 break;
1022 default:
1023 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1024 (*resume_hnd = 0);
1025 (*total_entries) = 0;
1026 ctr->ptr_conn_ctr = 0;
1027 status = WERR_UNKNOWN_LEVEL;
1028 break;
1031 return status;
1034 /*******************************************************************
1035 makes a SRV_R_NET_CONN_ENUM structure.
1036 ********************************************************************/
1038 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
1039 uint32 resume_hnd, int conn_level, int switch_value)
1041 DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
1043 r_n->conn_level = conn_level;
1044 if (conn_level == -1)
1045 r_n->status = WERR_UNKNOWN_LEVEL;
1046 else
1047 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
1049 if (!W_ERROR_IS_OK(r_n->status))
1050 resume_hnd = 0;
1052 init_enum_hnd(&r_n->enum_hnd, resume_hnd);
1055 /*******************************************************************
1056 makes a SRV_R_NET_FILE_ENUM structure.
1057 ********************************************************************/
1059 static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r,
1060 uint32 resume_hnd )
1062 TALLOC_CTX *ctx = talloc_tos();
1063 SRV_FILE_INFO_CTR *ctr = &r->ctr;
1065 /* TODO -- Windows enumerates
1066 (b) active pipes
1067 (c) open directories and files */
1069 r->status = net_enum_files( ctx, username, &ctr->file.info3,
1070 &ctr->num_entries, resume_hnd );
1071 if ( !W_ERROR_IS_OK(r->status))
1072 goto done;
1074 r->status = net_enum_pipes( ctx, username, &ctr->file.info3,
1075 &ctr->num_entries, resume_hnd );
1076 if ( !W_ERROR_IS_OK(r->status))
1077 goto done;
1079 r->level = ctr->level = 3;
1080 r->total_entries = ctr->num_entries;
1081 /* ctr->num_entries = r->total_entries - resume_hnd; */
1082 ctr->num_entries2 = ctr->num_entries;
1083 ctr->ptr_file_info = 1;
1085 r->status = WERR_OK;
1087 done:
1088 if ( ctr->num_entries > 0 )
1089 ctr->ptr_entries = 1;
1091 init_enum_hnd(&r->enum_hnd, 0);
1093 return r->status;
1096 /*******************************************************************
1097 *******************************************************************/
1099 WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
1101 const char *username = NULL;
1103 switch ( q_u->level ) {
1104 case 3:
1105 if (q_u->username) {
1106 username = rpcstr_pull_unistr2_talloc(
1107 p->mem_ctx, q_u->username);
1108 if (!username) {
1109 return WERR_NOMEM;
1113 return net_file_enum_3(username, r_u,
1114 get_enum_hnd(&q_u->enum_hnd));
1115 default:
1116 return WERR_UNKNOWN_LEVEL;
1119 return WERR_OK;
1122 /*******************************************************************
1123 _srvsvc_NetSrvGetInfo
1124 ********************************************************************/
1126 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1127 struct srvsvc_NetSrvGetInfo *r)
1129 WERROR status = WERR_OK;
1131 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1133 if (!pipe_access_check(p)) {
1134 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1135 return WERR_ACCESS_DENIED;
1138 switch (r->in.level) {
1140 /* Technically level 102 should only be available to
1141 Administrators but there isn't anything super-secret
1142 here, as most of it is made up. */
1144 case 102: {
1145 struct srvsvc_NetSrvInfo102 *info102;
1147 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1148 if (!info102) {
1149 return WERR_NOMEM;
1152 init_srvsvc_NetSrvInfo102(info102,
1153 PLATFORM_ID_NT,
1154 global_myname(),
1155 lp_major_announce_version(),
1156 lp_minor_announce_version(),
1157 lp_default_server_announce(),
1158 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1159 0xffffffff, /* users */
1160 0xf, /* disc */
1161 0, /* hidden */
1162 240, /* announce */
1163 3000, /* announce delta */
1164 100000, /* licenses */
1165 "c:\\"); /* user path */
1166 r->out.info->info102 = info102;
1167 break;
1169 case 101: {
1170 struct srvsvc_NetSrvInfo101 *info101;
1172 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1173 if (!info101) {
1174 return WERR_NOMEM;
1177 init_srvsvc_NetSrvInfo101(info101,
1178 PLATFORM_ID_NT,
1179 global_myname(),
1180 lp_major_announce_version(),
1181 lp_minor_announce_version(),
1182 lp_default_server_announce(),
1183 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1184 r->out.info->info101 = info101;
1185 break;
1187 case 100: {
1188 struct srvsvc_NetSrvInfo100 *info100;
1190 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1191 if (!info100) {
1192 return WERR_NOMEM;
1195 init_srvsvc_NetSrvInfo100(info100,
1196 PLATFORM_ID_NT,
1197 global_myname());
1198 r->out.info->info100 = info100;
1200 break;
1202 default:
1203 status = WERR_UNKNOWN_LEVEL;
1204 break;
1207 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1209 return status;
1212 /*******************************************************************
1213 _srvsvc_NetSrvSetInfo
1214 ********************************************************************/
1216 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1217 struct srvsvc_NetSrvSetInfo *r)
1219 WERROR status = WERR_OK;
1221 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1223 /* Set up the net server set info structure. */
1225 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1227 return status;
1230 /*******************************************************************
1231 net conn enum
1232 ********************************************************************/
1234 WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
1236 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1238 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR);
1239 if (!r_u->ctr)
1240 return WERR_NOMEM;
1242 ZERO_STRUCTP(r_u->ctr);
1244 /* set up the */
1245 init_srv_r_net_conn_enum(r_u,
1246 get_enum_hnd(&q_u->enum_hnd),
1247 q_u->conn_level,
1248 q_u->ctr->switch_value);
1250 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1252 return r_u->status;
1255 /*******************************************************************
1256 net sess enum
1257 ********************************************************************/
1259 WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
1261 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1263 r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR);
1264 if (!r_u->ctr)
1265 return WERR_NOMEM;
1267 ZERO_STRUCTP(r_u->ctr);
1269 /* set up the */
1270 init_srv_r_net_sess_enum(p, r_u,
1271 get_enum_hnd(&q_u->enum_hnd),
1272 q_u->sess_level,
1273 q_u->ctr->switch_value);
1275 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1277 return r_u->status;
1280 /*******************************************************************
1281 _srvsvc_NetSessDel
1282 ********************************************************************/
1284 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1285 struct srvsvc_NetSessDel *r)
1287 struct sessionid *session_list;
1288 struct current_user user;
1289 int num_sessions, snum;
1290 const char *username;
1291 const char *machine;
1292 bool not_root = False;
1293 WERROR werr;
1295 username = r->in.user;
1296 machine = r->in.client;
1298 /* strip leading backslashes if any */
1299 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1300 machine += 2;
1303 num_sessions = list_sessions(p->mem_ctx, &session_list);
1305 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1307 werr = WERR_ACCESS_DENIED;
1309 get_current_user(&user, p);
1311 /* fail out now if you are not root or not a domain admin */
1313 if ((user.ut.uid != sec_initial_uid()) &&
1314 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1316 goto done;
1319 for (snum = 0; snum < num_sessions; snum++) {
1321 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1322 strequal(session_list[snum].remote_machine, machine)) {
1324 NTSTATUS ntstat;
1326 if (user.ut.uid != sec_initial_uid()) {
1327 not_root = True;
1328 become_root();
1331 ntstat = messaging_send(smbd_messaging_context(),
1332 session_list[snum].pid,
1333 MSG_SHUTDOWN, &data_blob_null);
1335 if (NT_STATUS_IS_OK(ntstat))
1336 werr = WERR_OK;
1338 if (not_root)
1339 unbecome_root();
1343 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1345 done:
1347 return werr;
1350 /*******************************************************************
1351 _srvsvc_NetShareEnumAll
1352 ********************************************************************/
1354 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1355 struct srvsvc_NetShareEnumAll *r)
1357 WERROR werr;
1359 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1361 if (!pipe_access_check(p)) {
1362 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1363 return WERR_ACCESS_DENIED;
1366 /* Create the list of shares for the response. */
1367 werr = init_srv_share_info_ctr(p,
1368 r->in.info_ctr,
1369 r->in.resume_handle,
1370 r->out.totalentries,
1371 true);
1373 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1375 return werr;
1378 /*******************************************************************
1379 _srvsvc_NetShareEnum
1380 ********************************************************************/
1382 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1383 struct srvsvc_NetShareEnum *r)
1385 WERROR werr;
1387 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1389 if (!pipe_access_check(p)) {
1390 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1391 return WERR_ACCESS_DENIED;
1394 /* Create the list of shares for the response. */
1395 werr = init_srv_share_info_ctr(p,
1396 r->in.info_ctr,
1397 r->in.resume_handle,
1398 r->out.totalentries,
1399 false);
1401 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1403 return werr;
1406 /*******************************************************************
1407 _srvsvc_NetShareGetInfo
1408 ********************************************************************/
1410 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1411 struct srvsvc_NetShareGetInfo *r)
1413 WERROR status = WERR_OK;
1414 fstring share_name;
1415 int snum;
1416 union srvsvc_NetShareInfo *info = r->out.info;
1418 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1420 fstrcpy(share_name, r->in.share_name);
1422 snum = find_service(share_name);
1423 if (snum < 0) {
1424 return WERR_INVALID_NAME;
1427 switch (r->in.level) {
1428 case 0:
1429 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1430 W_ERROR_HAVE_NO_MEMORY(info->info0);
1431 init_srv_share_info_0(p, info->info0, snum);
1432 break;
1433 case 1:
1434 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1435 W_ERROR_HAVE_NO_MEMORY(info->info1);
1436 init_srv_share_info_1(p, info->info1, snum);
1437 break;
1438 case 2:
1439 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1440 W_ERROR_HAVE_NO_MEMORY(info->info2);
1441 init_srv_share_info_2(p, info->info2, snum);
1442 break;
1443 case 501:
1444 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1445 W_ERROR_HAVE_NO_MEMORY(info->info501);
1446 init_srv_share_info_501(p, info->info501, snum);
1447 break;
1448 case 502:
1449 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1450 W_ERROR_HAVE_NO_MEMORY(info->info502);
1451 init_srv_share_info_502(p, info->info502, snum);
1452 break;
1453 case 1004:
1454 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1455 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1456 init_srv_share_info_1004(p, info->info1004, snum);
1457 break;
1458 case 1005:
1459 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1460 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1461 init_srv_share_info_1005(p, info->info1005, snum);
1462 break;
1463 case 1006:
1464 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1465 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1466 init_srv_share_info_1006(p, info->info1006, snum);
1467 break;
1468 case 1007:
1469 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1470 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1471 init_srv_share_info_1007(p, info->info1007, snum);
1472 break;
1473 case 1501:
1474 init_srv_share_info_1501(p, info->info1501, snum);
1475 break;
1476 default:
1477 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1478 r->in.level));
1479 status = WERR_UNKNOWN_LEVEL;
1480 break;
1483 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1485 return status;
1488 /*******************************************************************
1489 Check a given DOS pathname is valid for a share.
1490 ********************************************************************/
1492 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1494 char *ptr = NULL;
1496 if (!dos_pathname) {
1497 return NULL;
1500 ptr = talloc_strdup(ctx, dos_pathname);
1501 if (!ptr) {
1502 return NULL;
1504 /* Convert any '\' paths to '/' */
1505 unix_format(ptr);
1506 ptr = unix_clean_name(ctx, ptr);
1507 if (!ptr) {
1508 return NULL;
1511 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1512 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1513 ptr += 2;
1515 /* Only absolute paths allowed. */
1516 if (*ptr != '/')
1517 return NULL;
1519 return ptr;
1522 /*******************************************************************
1523 _srvsvc_NetShareSetInfo. Modify share details.
1524 ********************************************************************/
1526 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1527 struct srvsvc_NetShareSetInfo *r)
1529 struct current_user user;
1530 char *command = NULL;
1531 char *share_name = NULL;
1532 char *comment = NULL;
1533 const char *pathname = NULL;
1534 int type;
1535 int snum;
1536 int ret;
1537 char *path = NULL;
1538 SEC_DESC *psd = NULL;
1539 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1540 bool is_disk_op = False;
1541 int max_connections = 0;
1542 TALLOC_CTX *ctx = p->mem_ctx;
1543 union srvsvc_NetShareInfo *info = r->in.info;
1545 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1547 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1548 if (!share_name) {
1549 return WERR_NOMEM;
1552 *r->out.parm_error = 0;
1554 if ( strequal(share_name,"IPC$")
1555 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1556 || strequal(share_name,"global") )
1558 return WERR_ACCESS_DENIED;
1561 snum = find_service(share_name);
1563 /* Does this share exist ? */
1564 if (snum < 0)
1565 return WERR_NET_NAME_NOT_FOUND;
1567 /* No change to printer shares. */
1568 if (lp_print_ok(snum))
1569 return WERR_ACCESS_DENIED;
1571 get_current_user(&user,p);
1573 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1575 /* fail out now if you are not root and not a disk op */
1577 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1578 return WERR_ACCESS_DENIED;
1580 switch (r->in.level) {
1581 case 1:
1582 pathname = talloc_strdup(ctx, lp_pathname(snum));
1583 comment = talloc_strdup(ctx, info->info2->comment);
1584 type = info->info2->type;
1585 psd = NULL;
1586 break;
1587 case 2:
1588 comment = talloc_strdup(ctx, info->info2->comment);
1589 pathname = info->info2->path;
1590 type = info->info2->type;
1591 max_connections = (info->info2->max_users == 0xffffffff) ?
1592 0 : info->info2->max_users;
1593 psd = NULL;
1594 break;
1595 #if 0
1596 /* not supported on set but here for completeness */
1597 case 501:
1598 comment = talloc_strdup(ctx, info->info501->comment);
1599 type = info->info501->type;
1600 psd = NULL;
1601 break;
1602 #endif
1603 case 502:
1604 comment = talloc_strdup(ctx, info->info502->comment);
1605 pathname = info->info502->path;
1606 type = info->info502->type;
1607 psd = info->info502->sd;
1608 map_generic_share_sd_bits(psd);
1609 break;
1610 case 1004:
1611 pathname = talloc_strdup(ctx, lp_pathname(snum));
1612 comment = talloc_strdup(ctx, info->info1004->comment);
1613 type = STYPE_DISKTREE;
1614 break;
1615 case 1005:
1616 /* XP re-sets the csc policy even if it wasn't changed by the
1617 user, so we must compare it to see if it's what is set in
1618 smb.conf, so that we can contine other ops like setting
1619 ACLs on a share */
1620 if (((info->info1005->dfs_flags &
1621 SHARE_1005_CSC_POLICY_MASK) >>
1622 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1623 return WERR_OK;
1624 else {
1625 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1626 return WERR_ACCESS_DENIED;
1628 case 1006:
1629 case 1007:
1630 return WERR_ACCESS_DENIED;
1631 case 1501:
1632 pathname = talloc_strdup(ctx, lp_pathname(snum));
1633 comment = talloc_strdup(ctx, lp_comment(snum));
1634 psd = info->info1501->sd;
1635 map_generic_share_sd_bits(psd);
1636 type = STYPE_DISKTREE;
1637 break;
1638 default:
1639 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1640 r->in.level));
1641 return WERR_UNKNOWN_LEVEL;
1644 /* We can only modify disk shares. */
1645 if (type != STYPE_DISKTREE)
1646 return WERR_ACCESS_DENIED;
1648 /* Check if the pathname is valid. */
1649 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1650 return WERR_OBJECT_PATH_INVALID;
1652 /* Ensure share name, pathname and comment don't contain '"' characters. */
1653 string_replace(share_name, '"', ' ');
1654 string_replace(path, '"', ' ');
1655 if (comment) {
1656 string_replace(comment, '"', ' ');
1659 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1660 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1662 /* Only call modify function if something changed. */
1664 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1665 || (lp_max_connections(snum) != max_connections)) {
1666 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1667 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1668 return WERR_ACCESS_DENIED;
1671 command = talloc_asprintf(p->mem_ctx,
1672 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1673 lp_change_share_cmd(),
1674 get_dyn_CONFIGFILE(),
1675 share_name,
1676 path,
1677 comment ? comment : "",
1678 max_connections);
1679 if (!command) {
1680 return WERR_NOMEM;
1683 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1685 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1687 if (is_disk_op)
1688 become_root();
1690 if ( (ret = smbrun(command, NULL)) == 0 ) {
1691 /* Tell everyone we updated smb.conf. */
1692 message_send_all(smbd_messaging_context(),
1693 MSG_SMB_CONF_UPDATED, NULL, 0,
1694 NULL);
1697 if ( is_disk_op )
1698 unbecome_root();
1700 /********* END SeDiskOperatorPrivilege BLOCK *********/
1702 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1703 command, ret ));
1705 TALLOC_FREE(command);
1707 if ( ret != 0 )
1708 return WERR_ACCESS_DENIED;
1709 } else {
1710 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1711 share_name ));
1714 /* Replace SD if changed. */
1715 if (psd) {
1716 SEC_DESC *old_sd;
1717 size_t sd_size;
1719 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1721 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1722 if (!set_share_security(share_name, psd))
1723 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1724 share_name ));
1728 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1730 return WERR_OK;
1733 /*******************************************************************
1734 _srvsvc_NetShareAdd.
1735 Call 'add_share_command "sharename" "pathname"
1736 "comment" "max connections = "
1737 ********************************************************************/
1739 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1740 struct srvsvc_NetShareAdd *r)
1742 struct current_user user;
1743 char *command = NULL;
1744 char *share_name = NULL;
1745 char *comment = NULL;
1746 char *pathname = NULL;
1747 int type;
1748 int snum;
1749 int ret;
1750 char *path;
1751 SEC_DESC *psd = NULL;
1752 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1753 bool is_disk_op;
1754 int max_connections = 0;
1755 TALLOC_CTX *ctx = p->mem_ctx;
1757 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1759 *r->out.parm_error = 0;
1761 get_current_user(&user,p);
1763 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1765 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1766 return WERR_ACCESS_DENIED;
1768 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1769 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1770 return WERR_ACCESS_DENIED;
1773 switch (r->in.level) {
1774 case 0:
1775 /* No path. Not enough info in a level 0 to do anything. */
1776 return WERR_ACCESS_DENIED;
1777 case 1:
1778 /* Not enough info in a level 1 to do anything. */
1779 return WERR_ACCESS_DENIED;
1780 case 2:
1781 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1782 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1783 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1784 max_connections = (r->in.info->info2->max_users == 0xffffffff) ?
1785 0 : r->in.info->info2->max_users;
1786 type = r->in.info->info2->type;
1787 break;
1788 case 501:
1789 /* No path. Not enough info in a level 501 to do anything. */
1790 return WERR_ACCESS_DENIED;
1791 case 502:
1792 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1793 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1794 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1795 max_connections = (r->in.info->info502->max_users == 0xffffffff) ?
1796 0 : r->in.info->info502->max_users;
1797 type = r->in.info->info502->type;
1798 psd = r->in.info->info502->sd;
1799 map_generic_share_sd_bits(psd);
1800 break;
1802 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1804 case 1004:
1805 case 1005:
1806 case 1006:
1807 case 1007:
1808 return WERR_ACCESS_DENIED;
1809 case 1501:
1810 /* DFS only level. */
1811 return WERR_ACCESS_DENIED;
1812 default:
1813 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1814 r->in.level));
1815 return WERR_UNKNOWN_LEVEL;
1818 /* check for invalid share names */
1820 if (!share_name || !validate_net_name(share_name,
1821 INVALID_SHARENAME_CHARS,
1822 strlen(share_name))) {
1823 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1824 share_name ? share_name : ""));
1825 return WERR_INVALID_NAME;
1828 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1829 || (lp_enable_asu_support() &&
1830 strequal(share_name,"ADMIN$"))) {
1831 return WERR_ACCESS_DENIED;
1834 snum = find_service(share_name);
1836 /* Share already exists. */
1837 if (snum >= 0) {
1838 return WERR_ALREADY_EXISTS;
1841 /* We can only add disk shares. */
1842 if (type != STYPE_DISKTREE) {
1843 return WERR_ACCESS_DENIED;
1846 /* Check if the pathname is valid. */
1847 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1848 return WERR_OBJECT_PATH_INVALID;
1851 /* Ensure share name, pathname and comment don't contain '"' characters. */
1852 string_replace(share_name, '"', ' ');
1853 string_replace(path, '"', ' ');
1854 if (comment) {
1855 string_replace(comment, '"', ' ');
1858 command = talloc_asprintf(ctx,
1859 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1860 lp_add_share_cmd(),
1861 get_dyn_CONFIGFILE(),
1862 share_name,
1863 path,
1864 comment ? comment : "",
1865 max_connections);
1866 if (!command) {
1867 return WERR_NOMEM;
1870 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1872 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1874 if ( is_disk_op )
1875 become_root();
1877 /* FIXME: use libnetconf here - gd */
1879 if ( (ret = smbrun(command, NULL)) == 0 ) {
1880 /* Tell everyone we updated smb.conf. */
1881 message_send_all(smbd_messaging_context(),
1882 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1885 if ( is_disk_op )
1886 unbecome_root();
1888 /********* END SeDiskOperatorPrivilege BLOCK *********/
1890 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1891 command, ret ));
1893 TALLOC_FREE(command);
1895 if ( ret != 0 )
1896 return WERR_ACCESS_DENIED;
1898 if (psd) {
1899 if (!set_share_security(share_name, psd)) {
1900 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1901 share_name ));
1906 * We don't call reload_services() here, the message will
1907 * cause this to be done before the next packet is read
1908 * from the client. JRA.
1911 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1913 return WERR_OK;
1916 /*******************************************************************
1917 _srvsvc_NetShareDel
1918 Call "delete share command" with the share name as
1919 a parameter.
1920 ********************************************************************/
1922 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1923 struct srvsvc_NetShareDel *r)
1925 struct current_user user;
1926 char *command = NULL;
1927 char *share_name = NULL;
1928 int ret;
1929 int snum;
1930 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1931 bool is_disk_op;
1932 struct share_params *params;
1933 TALLOC_CTX *ctx = p->mem_ctx;
1935 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1937 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1938 if (!share_name) {
1939 return WERR_NET_NAME_NOT_FOUND;
1941 if ( strequal(share_name,"IPC$")
1942 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1943 || strequal(share_name,"global") )
1945 return WERR_ACCESS_DENIED;
1948 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1949 return WERR_NO_SUCH_SHARE;
1952 snum = find_service(share_name);
1954 /* No change to printer shares. */
1955 if (lp_print_ok(snum))
1956 return WERR_ACCESS_DENIED;
1958 get_current_user(&user,p);
1960 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1962 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1963 return WERR_ACCESS_DENIED;
1965 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1966 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1967 return WERR_ACCESS_DENIED;
1970 command = talloc_asprintf(ctx,
1971 "%s \"%s\" \"%s\"",
1972 lp_delete_share_cmd(),
1973 get_dyn_CONFIGFILE(),
1974 lp_servicename(snum));
1975 if (!command) {
1976 return WERR_NOMEM;
1979 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1981 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1983 if ( is_disk_op )
1984 become_root();
1986 if ( (ret = smbrun(command, NULL)) == 0 ) {
1987 /* Tell everyone we updated smb.conf. */
1988 message_send_all(smbd_messaging_context(),
1989 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1992 if ( is_disk_op )
1993 unbecome_root();
1995 /********* END SeDiskOperatorPrivilege BLOCK *********/
1997 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1999 if ( ret != 0 )
2000 return WERR_ACCESS_DENIED;
2002 /* Delete the SD in the database. */
2003 delete_share_security(lp_servicename(params->service));
2005 lp_killservice(params->service);
2007 return WERR_OK;
2010 /*******************************************************************
2011 _srvsvc_NetShareDelSticky
2012 ********************************************************************/
2014 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
2015 struct srvsvc_NetShareDelSticky *r)
2017 struct srvsvc_NetShareDel q;
2019 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
2021 q.in.server_unc = r->in.server_unc;
2022 q.in.share_name = r->in.share_name;
2023 q.in.reserved = r->in.reserved;
2025 return _srvsvc_NetShareDel(p, &q);
2028 /*******************************************************************
2029 _srvsvc_NetRemoteTOD
2030 ********************************************************************/
2032 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2033 struct srvsvc_NetRemoteTOD *r)
2035 struct srvsvc_NetRemoteTODInfo *tod;
2036 struct tm *t;
2037 time_t unixdate = time(NULL);
2039 /* We do this call first as if we do it *after* the gmtime call
2040 it overwrites the pointed-to values. JRA */
2042 uint32 zone = get_time_zone(unixdate)/60;
2044 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2046 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2047 return WERR_NOMEM;
2049 *r->out.info = tod;
2051 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2053 t = gmtime(&unixdate);
2055 /* set up the */
2056 init_srvsvc_NetRemoteTODInfo(tod,
2057 unixdate,
2059 t->tm_hour,
2060 t->tm_min,
2061 t->tm_sec,
2063 zone,
2064 10000,
2065 t->tm_mday,
2066 t->tm_mon + 1,
2067 1900+t->tm_year,
2068 t->tm_wday);
2070 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2072 return WERR_OK;
2075 /***********************************************************************************
2076 _srvsvc_NetGetFileSecurity
2077 Win9x NT tools get security descriptor.
2078 ***********************************************************************************/
2080 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2081 struct srvsvc_NetGetFileSecurity *r)
2083 SEC_DESC *psd = NULL;
2084 size_t sd_size;
2085 DATA_BLOB null_pw;
2086 char *filename_in = NULL;
2087 char *filename = NULL;
2088 char *qualname = NULL;
2089 SMB_STRUCT_STAT st;
2090 NTSTATUS nt_status;
2091 WERROR werr;
2092 struct current_user user;
2093 connection_struct *conn = NULL;
2094 bool became_user = False;
2095 TALLOC_CTX *ctx = p->mem_ctx;
2096 struct sec_desc_buf *sd_buf;
2098 ZERO_STRUCT(st);
2100 werr = WERR_OK;
2102 qualname = talloc_strdup(ctx, r->in.share);
2103 if (!qualname) {
2104 werr = WERR_ACCESS_DENIED;
2105 goto error_exit;
2108 /* Null password is ok - we are already an authenticated user... */
2109 null_pw = data_blob_null;
2111 get_current_user(&user, p);
2113 become_root();
2114 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2115 unbecome_root();
2117 if (conn == NULL) {
2118 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2119 qualname));
2120 werr = ntstatus_to_werror(nt_status);
2121 goto error_exit;
2124 if (!become_user(conn, conn->vuid)) {
2125 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2126 werr = WERR_ACCESS_DENIED;
2127 goto error_exit;
2129 became_user = True;
2131 filename_in = talloc_strdup(ctx, r->in.file);
2132 if (!filename_in) {
2133 werr = WERR_ACCESS_DENIED;
2134 goto error_exit;
2137 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2138 if (!NT_STATUS_IS_OK(nt_status)) {
2139 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2140 filename));
2141 werr = WERR_ACCESS_DENIED;
2142 goto error_exit;
2145 nt_status = check_name(conn, filename);
2146 if (!NT_STATUS_IS_OK(nt_status)) {
2147 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2148 filename));
2149 werr = WERR_ACCESS_DENIED;
2150 goto error_exit;
2153 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2154 (OWNER_SECURITY_INFORMATION
2155 |GROUP_SECURITY_INFORMATION
2156 |DACL_SECURITY_INFORMATION), &psd);
2158 if (!NT_STATUS_IS_OK(nt_status)) {
2159 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2160 filename));
2161 werr = ntstatus_to_werror(nt_status);
2162 goto error_exit;
2165 sd_size = ndr_size_security_descriptor(psd, 0);
2167 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2168 if (!sd_buf) {
2169 werr = WERR_NOMEM;
2170 goto error_exit;
2173 sd_buf->sd_size = sd_size;
2174 sd_buf->sd = psd;
2176 *r->out.sd_buf = sd_buf;
2178 psd->dacl->revision = NT4_ACL_REVISION;
2180 unbecome_user();
2181 close_cnum(conn, user.vuid);
2182 return werr;
2184 error_exit:
2186 if (became_user)
2187 unbecome_user();
2189 if (conn)
2190 close_cnum(conn, user.vuid);
2192 return werr;
2195 /***********************************************************************************
2196 _srvsvc_NetSetFileSecurity
2197 Win9x NT tools set security descriptor.
2198 ***********************************************************************************/
2200 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2201 struct srvsvc_NetSetFileSecurity *r)
2203 char *filename_in = NULL;
2204 char *filename = NULL;
2205 char *qualname = NULL;
2206 DATA_BLOB null_pw;
2207 files_struct *fsp = NULL;
2208 SMB_STRUCT_STAT st;
2209 NTSTATUS nt_status;
2210 WERROR werr;
2211 struct current_user user;
2212 connection_struct *conn = NULL;
2213 bool became_user = False;
2214 TALLOC_CTX *ctx = p->mem_ctx;
2216 ZERO_STRUCT(st);
2218 werr = WERR_OK;
2220 qualname = talloc_strdup(ctx, r->in.share);
2221 if (!qualname) {
2222 werr = WERR_ACCESS_DENIED;
2223 goto error_exit;
2226 /* Null password is ok - we are already an authenticated user... */
2227 null_pw = data_blob_null;
2229 get_current_user(&user, p);
2231 become_root();
2232 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2233 unbecome_root();
2235 if (conn == NULL) {
2236 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2237 werr = ntstatus_to_werror(nt_status);
2238 goto error_exit;
2241 if (!become_user(conn, conn->vuid)) {
2242 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2243 werr = WERR_ACCESS_DENIED;
2244 goto error_exit;
2246 became_user = True;
2248 filename_in = talloc_strdup(ctx, r->in.file);
2249 if (!filename_in) {
2250 werr = WERR_ACCESS_DENIED;
2251 goto error_exit;
2254 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2255 if (!NT_STATUS_IS_OK(nt_status)) {
2256 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2257 werr = WERR_ACCESS_DENIED;
2258 goto error_exit;
2261 nt_status = check_name(conn, filename);
2262 if (!NT_STATUS_IS_OK(nt_status)) {
2263 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2264 werr = WERR_ACCESS_DENIED;
2265 goto error_exit;
2268 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2270 if ( !NT_STATUS_IS_OK(nt_status) ) {
2271 /* Perhaps it is a directory */
2272 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2273 nt_status = open_directory(conn, NULL, filename, &st,
2274 FILE_READ_ATTRIBUTES,
2275 FILE_SHARE_READ|FILE_SHARE_WRITE,
2276 FILE_OPEN,
2278 FILE_ATTRIBUTE_DIRECTORY,
2279 NULL, &fsp);
2281 if ( !NT_STATUS_IS_OK(nt_status) ) {
2282 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2283 werr = ntstatus_to_werror(nt_status);
2284 goto error_exit;
2288 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2289 r->in.securityinformation,
2290 r->in.sd_buf->sd);
2292 if (!NT_STATUS_IS_OK(nt_status) ) {
2293 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2294 werr = WERR_ACCESS_DENIED;
2295 goto error_exit;
2298 close_file(fsp, NORMAL_CLOSE);
2299 unbecome_user();
2300 close_cnum(conn, user.vuid);
2301 return werr;
2303 error_exit:
2305 if(fsp) {
2306 close_file(fsp, NORMAL_CLOSE);
2309 if (became_user) {
2310 unbecome_user();
2313 if (conn) {
2314 close_cnum(conn, user.vuid);
2317 return werr;
2320 /***********************************************************************************
2321 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2322 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2323 These disks would the disks listed by this function.
2324 Users could then create shares relative to these disks. Watch out for moving these disks around.
2325 "Nigel Williams" <nigel@veritas.com>.
2326 ***********************************************************************************/
2328 static const char *server_disks[] = {"C:"};
2330 static uint32 get_server_disk_count(void)
2332 return sizeof(server_disks)/sizeof(server_disks[0]);
2335 static uint32 init_server_disk_enum(uint32 *resume)
2337 uint32 server_disk_count = get_server_disk_count();
2339 /*resume can be an offset into the list for now*/
2341 if(*resume & 0x80000000)
2342 *resume = 0;
2344 if(*resume > server_disk_count)
2345 *resume = server_disk_count;
2347 return server_disk_count - *resume;
2350 static const char *next_server_disk_enum(uint32 *resume)
2352 const char *disk;
2354 if(init_server_disk_enum(resume) == 0)
2355 return NULL;
2357 disk = server_disks[*resume];
2359 (*resume)++;
2361 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2363 return disk;
2366 /********************************************************************
2367 _srvsvc_NetDiskEnum
2368 ********************************************************************/
2370 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2371 struct srvsvc_NetDiskEnum *r)
2373 uint32 i;
2374 const char *disk_name;
2375 TALLOC_CTX *ctx = p->mem_ctx;
2376 WERROR werr;
2377 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2379 werr = WERR_OK;
2381 *r->out.totalentries = init_server_disk_enum(&resume);
2383 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2384 MAX_SERVER_DISK_ENTRIES);
2385 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2387 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2389 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2391 r->out.info->count++;
2393 /*copy disk name into a unicode string*/
2395 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2396 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2399 /* add a terminating null string. Is this there if there is more data to come? */
2401 r->out.info->count++;
2403 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2404 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2406 if (r->out.resume_handle) {
2407 *r->out.resume_handle = resume;
2410 return werr;
2413 /********************************************************************
2414 _srvsvc_NetNameValidate
2415 ********************************************************************/
2417 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2418 struct srvsvc_NetNameValidate *r)
2420 switch (r->in.name_type) {
2421 case 0x9:
2422 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2423 strlen_m(r->in.name)))
2425 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2426 r->in.name));
2427 return WERR_INVALID_NAME;
2429 break;
2431 default:
2432 return WERR_UNKNOWN_LEVEL;
2435 return WERR_OK;
2438 /********************************************************************
2439 ********************************************************************/
2441 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2443 return WERR_ACCESS_DENIED;
2447 /********************************************************************
2448 ********************************************************************/
2450 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2452 p->rng_fault_state = True;
2453 return WERR_NOT_SUPPORTED;
2456 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2458 p->rng_fault_state = True;
2459 return WERR_NOT_SUPPORTED;
2462 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2464 p->rng_fault_state = True;
2465 return WERR_NOT_SUPPORTED;
2468 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2470 p->rng_fault_state = True;
2471 return WERR_NOT_SUPPORTED;
2474 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2476 p->rng_fault_state = True;
2477 return WERR_NOT_SUPPORTED;
2480 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2482 p->rng_fault_state = True;
2483 return WERR_NOT_SUPPORTED;
2486 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2488 p->rng_fault_state = True;
2489 return WERR_NOT_SUPPORTED;
2492 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2494 p->rng_fault_state = True;
2495 return WERR_NOT_SUPPORTED;
2498 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
2500 p->rng_fault_state = True;
2501 return WERR_NOT_SUPPORTED;
2504 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
2506 p->rng_fault_state = True;
2507 return WERR_NOT_SUPPORTED;
2510 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2512 p->rng_fault_state = True;
2513 return WERR_NOT_SUPPORTED;
2516 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
2518 p->rng_fault_state = True;
2519 return WERR_NOT_SUPPORTED;
2522 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2524 p->rng_fault_state = True;
2525 return WERR_NOT_SUPPORTED;
2528 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2530 p->rng_fault_state = True;
2531 return WERR_NOT_SUPPORTED;
2534 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2536 p->rng_fault_state = True;
2537 return WERR_NOT_SUPPORTED;
2540 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2542 p->rng_fault_state = True;
2543 return WERR_NOT_SUPPORTED;
2546 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2548 p->rng_fault_state = True;
2549 return WERR_NOT_SUPPORTED;
2552 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2554 p->rng_fault_state = True;
2555 return WERR_NOT_SUPPORTED;
2558 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2560 p->rng_fault_state = True;
2561 return WERR_NOT_SUPPORTED;
2564 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2566 p->rng_fault_state = True;
2567 return WERR_NOT_SUPPORTED;
2570 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2572 p->rng_fault_state = True;
2573 return WERR_NOT_SUPPORTED;
2576 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2578 p->rng_fault_state = True;
2579 return WERR_NOT_SUPPORTED;
2582 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2584 p->rng_fault_state = True;
2585 return WERR_NOT_SUPPORTED;
2588 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2590 p->rng_fault_state = True;
2591 return WERR_NOT_SUPPORTED;
2594 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2596 p->rng_fault_state = True;
2597 return WERR_NOT_SUPPORTED;
2600 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2602 p->rng_fault_state = True;
2603 return WERR_NOT_SUPPORTED;
2606 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2608 p->rng_fault_state = True;
2609 return WERR_NOT_SUPPORTED;
2612 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2614 p->rng_fault_state = True;
2615 return WERR_NOT_SUPPORTED;
2618 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2620 p->rng_fault_state = True;
2621 return WERR_NOT_SUPPORTED;
2624 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2626 p->rng_fault_state = True;
2627 return WERR_NOT_SUPPORTED;
2630 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2632 p->rng_fault_state = True;
2633 return WERR_NOT_SUPPORTED;
2636 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2638 p->rng_fault_state = True;
2639 return WERR_NOT_SUPPORTED;
2642 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2644 p->rng_fault_state = True;
2645 return WERR_NOT_SUPPORTED;
2648 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2650 p->rng_fault_state = True;
2651 return WERR_NOT_SUPPORTED;
2654 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2656 p->rng_fault_state = True;
2657 return WERR_NOT_SUPPORTED;
2660 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2662 p->rng_fault_state = True;
2663 return WERR_NOT_SUPPORTED;
2666 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2668 p->rng_fault_state = True;
2669 return WERR_NOT_SUPPORTED;
2672 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2674 p->rng_fault_state = True;
2675 return WERR_NOT_SUPPORTED;