r25484: Fix srvsrc_NetFileEnum listing only for one user
[Samba/nascimento.git] / source3 / rpc_server / srv_srvsvc_nt.c
blob503ecc1d1c255e203b80ada589cf4df3d1964c6f
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Jelmer Vernooij 2006.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
26 #include "includes.h"
28 #define MAX_SERVER_DISK_ENTRIES 15
30 extern struct generic_mapping file_generic_mapping;
31 extern userdom_struct current_user_info;
33 #undef DBGC_CLASS
34 #define DBGC_CLASS DBGC_RPC_SRV
36 /* Use for enumerating connections, pipes, & files */
38 struct file_enum_count {
39 TALLOC_CTX *ctx;
40 const char *username;
41 uint32 count;
42 struct srvsvc_NetFileInfo3 *info;
45 struct sess_file_count {
46 struct server_id pid;
47 uid_t uid;
48 int count;
51 /****************************************************************************
52 Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
55 static int pipe_enum_fn( struct db_record *rec, void *p)
57 struct pipe_open_rec prec;
58 struct file_enum_count *fenum = (struct file_enum_count *)p;
59 struct srvsvc_NetFileInfo3 *f;
60 int i = fenum->count;
61 pstring fullpath;
62 const char *username;
64 if (rec->value.dsize != sizeof(struct pipe_open_rec))
65 return 0;
67 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
69 if ( !process_exists(prec.pid) ) {
70 return 0;
73 username = uidtoname(prec.uid);
75 if ((fenum->username != NULL)
76 && !strequal(username, fenum->username)) {
77 return 0;
80 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
82 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info,
83 struct srvsvc_NetFileInfo3, i+1 );
84 if ( !f ) {
85 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
86 return 1;
89 fenum->info = f;
91 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
92 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
93 fenum->info[i].num_locks = 0;
94 fenum->info[i].user = talloc_move(fenum->ctx, &username);
95 if (!(fenum->info[i].path = talloc_strdup(
96 fenum->ctx, fullpath))) {
97 /* There's not much we can do here. */
98 fenum->info[i].path = "";
101 fenum->count++;
103 return 0;
106 /*******************************************************************
107 ********************************************************************/
109 static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username,
110 struct srvsvc_NetFileInfo3 **info,
111 uint32 *count, uint32 *resume )
113 struct file_enum_count fenum;
115 fenum.ctx = ctx;
116 fenum.username = username;
117 fenum.info = *info;
118 fenum.count = *count;
120 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
121 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
122 "failed\n"));
123 return WERR_NOMEM;
126 *info = fenum.info;
127 *count = fenum.count;
129 return WERR_OK;
132 /*******************************************************************
133 ********************************************************************/
135 static void enum_file_fn( const struct share_mode_entry *e,
136 const char *sharepath, const char *fname,
137 void *private_data )
139 struct file_enum_count *fenum =
140 (struct file_enum_count *)private_data;
142 struct srvsvc_NetFileInfo3 *f;
143 int i = fenum->count;
144 files_struct fsp;
145 struct byte_range_lock *brl;
146 int num_locks = 0;
147 pstring fullpath;
148 uint32 permissions;
149 const char *username;
151 /* If the pid was not found delete the entry from connections.tdb */
153 if (!process_exists(e->pid)) {
154 return;
157 username = uidtoname(e->uid);
159 if ((fenum->username != NULL)
160 && !strequal(username, fenum->username)) {
161 return;
164 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info,
165 struct srvsvc_NetFileInfo3, i+1 );
166 if ( !f ) {
167 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
168 return;
170 fenum->info = f;
172 /* need to count the number of locks on a file */
174 ZERO_STRUCT( fsp );
175 fsp.file_id = e->id;
177 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
178 num_locks = brl->num_locks;
179 TALLOC_FREE( brl );
182 if ( strcmp( fname, "." ) == 0 ) {
183 pstr_sprintf( fullpath, "C:%s", sharepath );
184 } else {
185 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
187 string_replace( fullpath, '/', '\\' );
189 /* mask out create (what ever that is) */
190 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
192 fenum->info[i].fid = e->share_file_id;
193 fenum->info[i].permissions = permissions;
194 fenum->info[i].num_locks = num_locks;
195 fenum->info[i].user = talloc_move(fenum->ctx, &username);
196 if (!(fenum->info[i].path = talloc_strdup(
197 fenum->ctx, fullpath))) {
198 /* There's not much we can do here. */
199 fenum->info[i].path = "";
202 fenum->count++;
205 /*******************************************************************
206 ********************************************************************/
208 static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username,
209 struct srvsvc_NetFileInfo3 **info,
210 uint32 *count, uint32 *resume )
212 struct file_enum_count f_enum_cnt;
214 f_enum_cnt.ctx = ctx;
215 f_enum_cnt.username = username;
216 f_enum_cnt.count = *count;
217 f_enum_cnt.info = *info;
219 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
221 *info = f_enum_cnt.info;
222 *count = f_enum_cnt.count;
224 return WERR_OK;
227 /*******************************************************************
228 Utility function to get the 'type' of a share from a share definition.
229 ********************************************************************/
230 static uint32 get_share_type(const struct share_params *params)
232 char *net_name = lp_servicename(params->service);
233 int len_net_name = strlen(net_name);
235 /* work out the share type */
236 uint32 type = STYPE_DISKTREE;
238 if (lp_print_ok(params->service))
239 type = STYPE_PRINTQ;
240 if (strequal(lp_fstype(params->service), "IPC"))
241 type = STYPE_IPC;
242 if (net_name[len_net_name-1] == '$')
243 type |= STYPE_HIDDEN;
245 return type;
248 /*******************************************************************
249 Fill in a share info level 0 structure.
250 ********************************************************************/
252 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
253 const struct share_params *params)
255 sh0->name = lp_servicename(params->service);
258 /*******************************************************************
259 Fill in a share info level 1 structure.
260 ********************************************************************/
262 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
263 const struct share_params *params)
265 connection_struct *conn = p->conn;
267 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
268 conn->user, conn->connectpath, conn->gid,
269 get_current_username(),
270 current_user_info.domain,
271 lp_comment(params->service));
273 sh1->name = lp_servicename(params->service);
274 sh1->type = get_share_type(params);
277 /*******************************************************************
278 Fill in a share info level 2 structure.
279 ********************************************************************/
281 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
282 const struct share_params *params)
284 connection_struct *conn = p->conn;
285 char *remark;
286 char *path;
287 int max_connections = lp_max_connections(params->service);
288 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
289 int count = 0;
290 char *net_name = lp_servicename(params->service);
292 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
293 conn->user, conn->connectpath, conn->gid,
294 get_current_username(),
295 current_user_info.domain,
296 lp_comment(params->service));
297 path = talloc_asprintf(p->mem_ctx, "C:%s",
298 lp_pathname(params->service));
301 * Change / to \\ so that win2k will see it as a valid path. This was
302 * added to enable use of browsing in win2k add share dialog.
305 string_replace(path, '/', '\\');
307 count = count_current_connections( net_name, False );
308 sh2->name = net_name;
309 sh2->type = get_share_type(params);
310 sh2->comment = remark;
311 sh2->permissions = 0;
312 sh2->max_users = max_uses;
313 sh2->current_users = count;
314 sh2->path = path;
315 sh2->password = "";
318 /*******************************************************************
319 Map any generic bits to file specific bits.
320 ********************************************************************/
322 static void map_generic_share_sd_bits(SEC_DESC *psd)
324 int i;
325 SEC_ACL *ps_dacl = NULL;
327 if (!psd)
328 return;
330 ps_dacl = psd->dacl;
331 if (!ps_dacl)
332 return;
334 for (i = 0; i < ps_dacl->num_aces; i++) {
335 SEC_ACE *psa = &ps_dacl->aces[i];
336 uint32 orig_mask = psa->access_mask;
338 se_map_generic(&psa->access_mask, &file_generic_mapping);
339 psa->access_mask |= orig_mask;
343 /*******************************************************************
344 Fill in a share info level 501 structure.
345 ********************************************************************/
347 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
348 const struct share_params *params)
350 connection_struct *conn = p->conn;
351 char *remark;
352 const char *net_name = lp_servicename(params->service);
354 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
355 conn->user, conn->connectpath, conn->gid,
356 get_current_username(),
357 current_user_info.domain,
358 lp_comment(params->service));
361 sh501->name = net_name;
362 sh501->type = get_share_type(params);
363 sh501->comment = remark;
364 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
367 /*******************************************************************
368 Fill in a share info level 502 structure.
369 ********************************************************************/
371 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
372 const struct share_params *params)
374 int max_connections = lp_max_connections(params->service);
375 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
376 connection_struct *conn = p->conn;
377 int count;
378 char *net_name;
379 char *remark;
380 char *path;
381 SEC_DESC *sd;
382 size_t sd_size;
383 TALLOC_CTX *ctx = p->mem_ctx;
386 ZERO_STRUCTP(sh502);
388 net_name = lp_servicename(params->service);
389 count = count_current_connections( net_name, False );
391 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
392 conn->user, conn->connectpath, conn->gid,
393 get_current_username(),
394 current_user_info.domain,
395 lp_comment(params->service));
397 path = talloc_asprintf(p->mem_ctx, "C:%s",
398 lp_pathname(params->service));
401 * Change / to \\ so that win2k will see it as a valid path. This was
402 * added to enable use of browsing in win2k add share dialog.
405 string_replace(path, '/', '\\');
407 sd = get_share_security(ctx, lp_servicename(params->service),
408 &sd_size);
410 sh502->name = net_name;
411 sh502->type = get_share_type(params);
412 sh502->comment = remark;
413 sh502->path = path;
414 sh502->password = "";
415 sh502->sd = sd;
416 sh502->permissions = 0;
417 sh502->max_users = max_uses;
418 sh502->current_users = count;
419 sh502->unknown = 1;
422 /***************************************************************************
423 Fill in a share info level 1004 structure.
424 ***************************************************************************/
426 static void init_srv_share_info_1004(pipes_struct *p,
427 struct srvsvc_NetShareInfo1004* sh1004,
428 const struct share_params *params)
430 connection_struct *conn = p->conn;
431 char *remark;
433 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
434 conn->user, conn->connectpath, conn->gid,
435 get_current_username(),
436 current_user_info.domain,
437 lp_comment(params->service));
439 ZERO_STRUCTP(sh1004);
441 sh1004->comment = remark;
444 /***************************************************************************
445 Fill in a share info level 1005 structure.
446 ***************************************************************************/
448 static void init_srv_share_info_1005(pipes_struct *p,
449 struct srvsvc_NetShareInfo1005* sh1005,
450 const struct share_params *params)
452 sh1005->dfs_flags = 0;
454 if(lp_host_msdfs() && lp_msdfs_root(params->service))
455 sh1005->dfs_flags |=
456 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
457 sh1005->dfs_flags |=
458 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
460 /***************************************************************************
461 Fill in a share info level 1006 structure.
462 ***************************************************************************/
464 static void init_srv_share_info_1006(pipes_struct *p,
465 struct srvsvc_NetShareInfo1006* sh1006,
466 const struct share_params *params)
468 sh1006->max_users = -1;
471 /***************************************************************************
472 Fill in a share info level 1007 structure.
473 ***************************************************************************/
475 static void init_srv_share_info_1007(pipes_struct *p,
476 struct srvsvc_NetShareInfo1007* sh1007,
477 const struct share_params *params)
479 uint32 flags = 0;
481 ZERO_STRUCTP(sh1007);
483 sh1007->flags = flags;
484 sh1007->alternate_directory_name = "";
487 /*******************************************************************
488 Fill in a share info level 1501 structure.
489 ********************************************************************/
491 static void init_srv_share_info_1501(pipes_struct *p,
492 struct sec_desc_buf *sh1501,
493 const struct share_params *params)
495 SEC_DESC *sd;
496 size_t sd_size;
497 TALLOC_CTX *ctx = p->mem_ctx;
499 ZERO_STRUCTP(sh1501);
501 sd = get_share_security(ctx, lp_servicename(params->service),
502 &sd_size);
504 sh1501->sd = sd;
507 /*******************************************************************
508 True if it ends in '$'.
509 ********************************************************************/
511 static BOOL is_hidden_share(const struct share_params *params)
513 const char *net_name = lp_servicename(params->service);
515 return (net_name[strlen(net_name) - 1] == '$');
518 /*******************************************************************
519 Fill in a share info structure.
520 ********************************************************************/
522 static WERROR init_srv_share_info_ctr(pipes_struct *p,
523 union srvsvc_NetShareCtr *ctr,
524 uint32 info_level, uint32 *resume_hnd,
525 uint32 *total_entries, BOOL all_shares)
527 TALLOC_CTX *ctx = p->mem_ctx;
528 struct share_iterator *shares;
529 struct share_params *share;
530 WERROR result = WERR_NOMEM;
532 DEBUG(5,("init_srv_share_info_ctr\n"));
534 ZERO_STRUCTP(ctr);
536 if (resume_hnd) {
537 *resume_hnd = 0;
540 /* Ensure all the usershares are loaded. */
541 become_root();
542 load_usershare_shares();
543 load_registry_shares();
544 unbecome_root();
546 *total_entries = 0;
548 if (!(shares = share_list_all(ctx))) {
549 DEBUG(5, ("Could not list shares\n"));
550 return WERR_ACCESS_DENIED;
553 switch (info_level) {
554 case 0:
555 if (!(ctr->ctr0 = TALLOC_ZERO_P(
556 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
557 goto done;
559 break;
560 case 1:
561 if (!(ctr->ctr1 = TALLOC_ZERO_P(
562 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
563 goto done;
565 break;
566 case 2:
567 if (!(ctr->ctr2 = TALLOC_ZERO_P(
568 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
569 goto done;
571 break;
572 case 501:
573 if (!(ctr->ctr501 = TALLOC_ZERO_P(
574 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
575 goto done;
577 break;
578 case 502:
579 if (!(ctr->ctr502 = TALLOC_ZERO_P(
580 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
581 goto done;
583 break;
584 case 1004:
585 if (!(ctr->ctr1004 = TALLOC_ZERO_P(
586 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
587 goto done;
589 break;
590 case 1005:
591 if (!(ctr->ctr1005 = TALLOC_ZERO_P(
592 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
593 goto done;
595 break;
596 case 1006:
597 if (!(ctr->ctr1006 = TALLOC_ZERO_P(
598 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
599 goto done;
601 break;
602 case 1007:
603 if (!(ctr->ctr1007 = TALLOC_ZERO_P(
604 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
605 goto done;
607 break;
608 case 1501:
609 if (!(ctr->ctr1501 = TALLOC_ZERO_P(
610 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
611 goto done;
613 break;
614 default:
615 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
616 "value %d\n", info_level));
617 return WERR_UNKNOWN_LEVEL;
620 while ((share = next_share(shares)) != NULL) {
621 if (!lp_browseable(share->service)) {
622 continue;
624 if (!all_shares && is_hidden_share(share)) {
625 continue;
628 switch (info_level) {
629 case 0:
631 struct srvsvc_NetShareInfo0 i;
632 init_srv_share_info_0(p, &i, share);
633 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
634 &ctr->ctr0->array, &ctr->ctr0->count);
635 if (ctr->ctr0->array == NULL) {
636 return WERR_NOMEM;
638 *total_entries = ctr->ctr0->count;
639 break;
642 case 1:
644 struct srvsvc_NetShareInfo1 i;
645 init_srv_share_info_1(p, &i, share);
646 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
647 &ctr->ctr1->array, &ctr->ctr1->count);
648 if (ctr->ctr1->array == NULL) {
649 return WERR_NOMEM;
651 *total_entries = ctr->ctr1->count;
652 break;
655 case 2:
657 struct srvsvc_NetShareInfo2 i;
658 init_srv_share_info_2(p, &i, share);
659 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
660 &ctr->ctr2->array, &ctr->ctr2->count);
661 if (ctr->ctr2->array == NULL) {
662 return WERR_NOMEM;
664 *total_entries = ctr->ctr2->count;
665 break;
668 case 501:
670 struct srvsvc_NetShareInfo501 i;
671 init_srv_share_info_501(p, &i, share);
672 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
673 &ctr->ctr501->array, &ctr->ctr501->count);
674 if (ctr->ctr501->array == NULL) {
675 return WERR_NOMEM;
677 *total_entries = ctr->ctr501->count;
678 break;
681 case 502:
683 struct srvsvc_NetShareInfo502 i;
684 init_srv_share_info_502(p, &i, share);
685 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
686 &ctr->ctr502->array, &ctr->ctr502->count);
687 if (ctr->ctr502->array == NULL) {
688 return WERR_NOMEM;
690 *total_entries = ctr->ctr502->count;
691 break;
694 /* here for completeness but not currently used with enum
695 * (1004 - 1501)*/
697 case 1004:
699 struct srvsvc_NetShareInfo1004 i;
700 init_srv_share_info_1004(p, &i, share);
701 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
702 &ctr->ctr1004->array, &ctr->ctr1004->count);
703 if (ctr->ctr1004->array == NULL) {
704 return WERR_NOMEM;
706 *total_entries = ctr->ctr1004->count;
707 break;
710 case 1005:
712 struct srvsvc_NetShareInfo1005 i;
713 init_srv_share_info_1005(p, &i, share);
714 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
715 &ctr->ctr1005->array, &ctr->ctr1005->count);
716 if (ctr->ctr1005->array == NULL) {
717 return WERR_NOMEM;
719 *total_entries = ctr->ctr1005->count;
720 break;
723 case 1006:
725 struct srvsvc_NetShareInfo1006 i;
726 init_srv_share_info_1006(p, &i, share);
727 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
728 &ctr->ctr1006->array, &ctr->ctr1006->count);
729 if (ctr->ctr1006->array == NULL) {
730 return WERR_NOMEM;
732 *total_entries = ctr->ctr1006->count;
733 break;
736 case 1007:
738 struct srvsvc_NetShareInfo1007 i;
739 init_srv_share_info_1007(p, &i, share);
740 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
741 &ctr->ctr1007->array, &ctr->ctr1007->count);
742 if (ctr->ctr1007->array == NULL) {
743 return WERR_NOMEM;
745 *total_entries = ctr->ctr1007->count;
746 break;
749 case 1501:
751 struct sec_desc_buf i;
752 init_srv_share_info_1501(p, &i, share);
753 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
754 &ctr->ctr1501->array, &ctr->ctr1501->count);
755 if (ctr->ctr1501->array == NULL) {
756 return WERR_NOMEM;
758 *total_entries = ctr->ctr1501->count;
759 break;
763 TALLOC_FREE(share);
766 result = WERR_OK;
767 done:
768 TALLOC_FREE(shares);
769 return result;
772 /*******************************************************************
773 fill in a sess info level 0 structure.
774 ********************************************************************/
776 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
778 struct sessionid *session_list;
779 uint32 num_entries = 0;
780 (*stot) = list_sessions(p->mem_ctx, &session_list);
782 if (ss0 == NULL) {
783 if (snum) {
784 (*snum) = 0;
786 return;
789 DEBUG(5,("init_srv_sess_0_ss0\n"));
791 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
793 if (snum) {
794 for (; (*snum) < (*stot); (*snum)++) {
795 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
796 num_entries++;
799 ss0->count = num_entries;
801 if ((*snum) >= (*stot)) {
802 (*snum) = 0;
805 } else {
806 ss0->array = NULL;
807 ss0->count = 0;
811 /*******************************************************************
812 ********************************************************************/
814 static void sess_file_fn( const struct share_mode_entry *e,
815 const char *sharepath, const char *fname,
816 void *private_data )
818 struct sess_file_count *sess = (struct sess_file_count *)private_data;
820 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
821 sess->count++;
824 return;
827 /*******************************************************************
828 ********************************************************************/
830 static int net_count_files( uid_t uid, struct server_id pid )
832 struct sess_file_count s_file_cnt;
834 s_file_cnt.count = 0;
835 s_file_cnt.uid = uid;
836 s_file_cnt.pid = pid;
838 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
840 return s_file_cnt.count;
843 /*******************************************************************
844 fill in a sess info level 1 structure.
845 ********************************************************************/
847 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
849 struct sessionid *session_list;
850 uint32 num_entries = 0;
851 time_t now = time(NULL);
853 if ( !snum ) {
854 ss1->count = 0;
855 ss1->array = NULL;
857 (*stot) = 0;
859 return;
862 if (ss1 == NULL) {
863 if (snum != NULL)
864 (*snum) = 0;
865 return;
868 (*stot) = list_sessions(p->mem_ctx, &session_list);
870 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
872 for (; (*snum) < (*stot); (*snum)++) {
873 uint32 num_files;
874 uint32 connect_time;
875 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
876 BOOL guest;
878 if ( !pw ) {
879 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
880 session_list[*snum].username));
881 continue;
884 connect_time = (uint32)(now - session_list[*snum].connect_start);
885 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
886 guest = strequal( session_list[*snum].username, lp_guestaccount() );
888 if (!(ss1->array[num_entries].client = talloc_strdup(
889 ss1->array, session_list[*snum].remote_machine))) {
890 ss1->array[num_entries].client = "";
892 if (!(ss1->array[num_entries].user = talloc_strdup(
893 ss1->array, session_list[*snum].username))) {
894 ss1->array[num_entries].user = "";
896 ss1->array[num_entries].num_open = num_files;
897 ss1->array[num_entries].time = connect_time;
898 ss1->array[num_entries].idle_time = 0;
899 ss1->array[num_entries].user_flags = guest;
901 num_entries++;
904 ss1->count = num_entries;
906 if ((*snum) >= (*stot)) {
907 (*snum) = 0;
911 /*******************************************************************
912 makes a SRV_R_NET_SESS_ENUM structure.
913 ********************************************************************/
915 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
916 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
918 WERROR status = WERR_OK;
919 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
921 switch (switch_value) {
922 case 0:
923 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
924 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
925 break;
926 case 1:
927 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
928 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
929 break;
930 default:
931 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
932 if (resume_hnd != NULL)
933 (*resume_hnd) = 0;
934 (*total_entries) = 0;
935 ctr->ctr0 = NULL;
936 status = WERR_UNKNOWN_LEVEL;
937 break;
940 return status;
943 /*******************************************************************
944 fill in a conn info level 0 structure.
945 ********************************************************************/
947 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
949 uint32 num_entries = 0;
950 (*stot) = 1;
952 if (ss0 == NULL) {
953 if (snum != NULL)
954 (*snum) = 0;
955 return;
958 DEBUG(5,("init_srv_conn_0_ss0\n"));
960 if (snum) {
961 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
962 for (; (*snum) < (*stot); (*snum)++) {
964 ss0->array[num_entries].conn_id = (*stot);
966 /* move on to creating next connection */
967 /* move on to creating next conn */
968 num_entries++;
971 ss0->count = num_entries;
973 if ((*snum) >= (*stot)) {
974 (*snum) = 0;
977 } else {
978 ss0->array = NULL;
979 ss0->count = 0;
981 (*stot) = 0;
985 /*******************************************************************
986 fill in a conn info level 1 structure.
987 ********************************************************************/
989 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
991 uint32 num_entries = 0;
992 (*stot) = 1;
994 if (ss1 == NULL) {
995 if (snum != NULL)
996 (*snum) = 0;
997 return;
1000 DEBUG(5,("init_srv_conn_1_ss1\n"));
1002 if (snum) {
1003 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
1004 for (; (*snum) < (*stot); (*snum)++) {
1005 ss1->array[num_entries].conn_id = (*stot);
1006 ss1->array[num_entries].conn_type = 0x3;
1007 ss1->array[num_entries].num_open = 1;
1008 ss1->array[num_entries].num_users = 1;
1009 ss1->array[num_entries].conn_time = 3;
1010 ss1->array[num_entries].user = "dummy_user";
1011 ss1->array[num_entries].share = "IPC$";
1013 /* move on to creating next connection */
1014 /* move on to creating next conn */
1015 num_entries++;
1018 ss1->count = num_entries;
1020 if ((*snum) >= (*stot)) {
1021 (*snum) = 0;
1024 } else {
1025 ss1->count = 0;
1026 ss1->array = NULL;
1028 (*stot) = 0;
1032 /*******************************************************************
1033 makes a SRV_R_NET_CONN_ENUM structure.
1034 ********************************************************************/
1036 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1037 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1039 WERROR status = WERR_OK;
1040 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1042 switch (switch_value) {
1043 case 0:
1044 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1045 break;
1046 case 1:
1047 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1048 break;
1049 default:
1050 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1051 ctr->ctr0 = NULL;
1052 (*resume_hnd) = 0;
1053 (*total_entries) = 0;
1054 status = WERR_UNKNOWN_LEVEL;
1055 break;
1058 return status;
1061 /*******************************************************************
1062 makes a SRV_R_NET_FILE_ENUM structure.
1063 ********************************************************************/
1065 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr,
1066 uint32 *resume_hnd, const char *username,
1067 uint32 *num_entries )
1069 WERROR status;
1071 /* TODO -- Windows enumerates
1072 (b) active pipes
1073 (c) open directories and files */
1075 ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3);
1077 status = net_enum_files(p->mem_ctx, username, &ctr->ctr3->array,
1078 num_entries, resume_hnd );
1079 if ( !W_ERROR_IS_OK(status))
1080 return status;
1082 status = net_enum_pipes(p->mem_ctx, username, &ctr->ctr3->array,
1083 num_entries, resume_hnd );
1084 if ( !W_ERROR_IS_OK(status))
1085 return status;
1087 ctr->ctr3->count = *num_entries;
1089 return WERR_OK;
1092 /*******************************************************************
1093 *******************************************************************/
1095 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1097 switch ( *r->in.level ) {
1098 case 3:
1099 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle,
1100 r->in.user, r->out.totalentries );
1101 default:
1102 return WERR_UNKNOWN_LEVEL;
1105 return WERR_OK;
1108 /*******************************************************************
1109 net server get info
1110 ********************************************************************/
1112 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1114 WERROR status = WERR_OK;
1116 ZERO_STRUCTP(r->out.info);
1118 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1120 if (!pipe_access_check(p)) {
1121 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1122 return WERR_ACCESS_DENIED;
1125 switch (r->in.level) {
1127 /* Technically level 102 should only be available to
1128 Administrators but there isn't anything super-secret
1129 here, as most of it is made up. */
1131 case 102:
1132 r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1134 r->out.info->info102->platform_id = 500;
1135 r->out.info->info102->version_major = lp_major_announce_version();
1136 r->out.info->info102->version_minor = lp_minor_announce_version();
1137 r->out.info->info102->server_name = global_myname();
1138 r->out.info->info102->server_type = lp_default_server_announce();
1139 r->out.info->info102->userpath = "C:\\";
1140 r->out.info->info102->licenses = 10000;
1141 r->out.info->info102->anndelta = 3000;
1142 r->out.info->info102->disc = 0xf;
1143 r->out.info->info102->users = 0xffffffff;
1144 r->out.info->info102->hidden = 0;
1145 r->out.info->info102->announce = 240;
1146 r->out.info->info102->comment = lp_serverstring();
1147 break;
1148 case 101:
1149 r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1150 r->out.info->info101->platform_id = 500;
1151 r->out.info->info101->server_name = global_myname();
1152 r->out.info->info101->version_major = lp_major_announce_version();
1153 r->out.info->info101->version_minor = lp_minor_announce_version();
1154 r->out.info->info101->server_type = lp_default_server_announce();
1155 r->out.info->info101->comment = lp_serverstring();
1156 break;
1157 case 100:
1158 r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1159 r->out.info->info100->platform_id = 500;
1160 r->out.info->info100->server_name = global_myname();
1161 break;
1162 default:
1163 return WERR_UNKNOWN_LEVEL;
1164 break;
1167 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1169 return status;
1172 /*******************************************************************
1173 net server set info
1174 ********************************************************************/
1176 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1178 /* Set up the net server set info structure. */
1179 if (r->out.parm_error) {
1180 *r->out.parm_error = 0;
1182 return WERR_OK;
1185 /*******************************************************************
1186 net conn enum
1187 ********************************************************************/
1189 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1191 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1193 ZERO_STRUCTP(r->out.ctr);
1195 /* set up the */
1196 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1199 /*******************************************************************
1200 net sess enum
1201 ********************************************************************/
1203 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1205 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1207 ZERO_STRUCTP(r->out.ctr);
1209 /* set up the */
1210 return init_srv_sess_info_ctr(p, r->out.ctr,
1211 *r->in.level,
1212 r->in.resume_handle,
1213 r->out.totalentries);
1216 /*******************************************************************
1217 net sess del
1218 ********************************************************************/
1220 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1222 struct sessionid *session_list;
1223 int num_sessions, snum;
1224 WERROR status;
1226 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1228 /* strip leading backslashes if any */
1229 while (machine[0] == '\\') {
1230 memmove(machine, &machine[1], strlen(machine));
1233 num_sessions = list_sessions(p->mem_ctx, &session_list);
1235 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1237 status = WERR_ACCESS_DENIED;
1239 /* fail out now if you are not root or not a domain admin */
1241 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1242 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1244 goto done;
1247 for (snum = 0; snum < num_sessions; snum++) {
1249 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1250 strequal(session_list[snum].remote_machine, machine)) {
1251 NTSTATUS ntstat;
1253 ntstat = messaging_send(smbd_messaging_context(),
1254 session_list[snum].pid,
1255 MSG_SHUTDOWN, &data_blob_null);
1257 if (NT_STATUS_IS_OK(ntstat))
1258 status = WERR_OK;
1262 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1264 done:
1265 return status;
1268 /*******************************************************************
1269 Net share enum all.
1270 ********************************************************************/
1272 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1274 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1276 if (!pipe_access_check(p)) {
1277 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1278 return WERR_ACCESS_DENIED;
1281 /* Create the list of shares for the response. */
1282 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1283 r->in.resume_handle, r->out.totalentries, True);
1286 /*******************************************************************
1287 Net share enum.
1288 ********************************************************************/
1290 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
1292 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1294 if (!pipe_access_check(p)) {
1295 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1296 return WERR_ACCESS_DENIED;
1299 /* Create the list of shares for the response. */
1300 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1301 r->in.resume_handle, r->out.totalentries, False);
1304 /*******************************************************************
1305 Net share get info.
1306 ********************************************************************/
1308 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1310 const struct share_params *params;
1312 params = get_share_params(p->mem_ctx, r->in.share_name);
1314 if (params != NULL) {
1315 switch (r->in.level) {
1316 case 0:
1317 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1318 init_srv_share_info_0(p, r->out.info->info0, params);
1319 break;
1320 case 1:
1321 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1322 init_srv_share_info_1(p, r->out.info->info1, params);
1323 break;
1324 case 2:
1325 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1326 init_srv_share_info_2(p, r->out.info->info2, params);
1327 break;
1328 case 501:
1329 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1330 init_srv_share_info_501(p, r->out.info->info501, params);
1331 break;
1332 case 502:
1333 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1334 init_srv_share_info_502(p, r->out.info->info502, params);
1335 break;
1337 /* here for completeness */
1338 case 1004:
1339 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1340 init_srv_share_info_1004(p, r->out.info->info1004, params);
1341 break;
1342 case 1005:
1343 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1344 init_srv_share_info_1005(p, r->out.info->info1005, params);
1345 break;
1347 /* here for completeness 1006 - 1501 */
1348 case 1006:
1349 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1350 init_srv_share_info_1006(p, r->out.info->info1006,
1351 params);
1352 break;
1353 case 1007:
1354 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1355 init_srv_share_info_1007(p, r->out.info->info1007,
1356 params);
1357 break;
1358 case 1501:
1359 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1360 init_srv_share_info_1501(p, r->out.info->info1501,
1361 params);
1362 break;
1363 default:
1364 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1365 "switch value %d\n", r->in.level));
1366 return WERR_UNKNOWN_LEVEL;
1367 break;
1369 } else {
1370 return WERR_INVALID_NAME;
1373 return WERR_OK;
1376 /*******************************************************************
1377 Check a given DOS pathname is valid for a share.
1378 ********************************************************************/
1380 char *valid_share_pathname(char *dos_pathname)
1382 char *ptr;
1384 /* Convert any '\' paths to '/' */
1385 unix_format(dos_pathname);
1386 unix_clean_name(dos_pathname);
1388 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1389 ptr = dos_pathname;
1390 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1391 ptr += 2;
1393 /* Only absolute paths allowed. */
1394 if (*ptr != '/')
1395 return NULL;
1397 return ptr;
1400 static void setval_helper(struct registry_key *key, const char *name,
1401 const char *value, WERROR *err)
1403 struct registry_value val;
1405 if (!W_ERROR_IS_OK(*err)) {
1406 return;
1409 ZERO_STRUCT(val);
1410 val.type = REG_SZ;
1411 val.v.sz.str = CONST_DISCARD(char *, value);
1412 val.v.sz.len = strlen(value)+1;
1414 *err = reg_setvalue(key, name, &val);
1417 static WERROR add_share(const char *share_name, const char *path,
1418 const char *comment, uint32 max_connections,
1419 const struct nt_user_token *token,
1420 BOOL is_disk_op)
1422 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1423 char *command;
1424 int ret;
1426 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1427 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1428 path, comment, max_connections) == -1) {
1429 return WERR_NOMEM;
1432 DEBUG(10,("add_share: Running [%s]\n", command ));
1434 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1436 if ( is_disk_op )
1437 become_root();
1439 if ( (ret = smbrun(command, NULL)) == 0 ) {
1440 /* Tell everyone we updated smb.conf. */
1441 message_send_all(smbd_messaging_context(),
1442 MSG_SMB_CONF_UPDATED,
1443 NULL, 0, NULL);
1446 if ( is_disk_op )
1447 unbecome_root();
1449 /********* END SeDiskOperatorPrivilege BLOCK *********/
1451 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1452 command, ret ));
1455 * No fallback to registry shares, the user did define a add
1456 * share command, so fail here.
1459 SAFE_FREE(command);
1460 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1463 if (lp_registry_shares()) {
1464 char *keyname;
1465 struct registry_key *key;
1466 enum winreg_CreateAction action;
1467 WERROR err;
1468 TALLOC_CTX *mem_ctx;
1470 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1471 share_name))) {
1472 return WERR_NOMEM;
1475 mem_ctx = (TALLOC_CTX *)keyname;
1477 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1478 is_disk_op ? get_root_nt_token():token,
1479 &action, &key);
1481 if (action != REG_CREATED_NEW_KEY) {
1482 err = WERR_ALREADY_EXISTS;
1485 if (!W_ERROR_IS_OK(err)) {
1486 TALLOC_FREE(mem_ctx);
1487 return err;
1490 setval_helper(key, "path", path, &err);
1491 if ((comment != NULL) && (comment[0] != '\0')) {
1492 setval_helper(key, "comment", comment, &err);
1494 if (max_connections != 0) {
1495 char tmp[16];
1496 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1497 setval_helper(key, "max connections", tmp, &err);
1500 if (!W_ERROR_IS_OK(err)) {
1502 * Hmmmm. We'd need transactions on the registry to
1503 * get this right....
1505 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1506 keyname);
1508 TALLOC_FREE(mem_ctx);
1509 return err;
1512 return WERR_ACCESS_DENIED;
1515 static WERROR delete_share(const char *sharename,
1516 const struct nt_user_token *token,
1517 BOOL is_disk_op)
1519 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1520 char *command;
1521 int ret;
1523 if (asprintf(&command, "%s \"%s\" \"%s\"",
1524 lp_delete_share_cmd(), dyn_CONFIGFILE,
1525 sharename)) {
1526 return WERR_NOMEM;
1529 DEBUG(10,("delete_share: Running [%s]\n", command ));
1531 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1533 if ( is_disk_op )
1534 become_root();
1536 if ( (ret = smbrun(command, NULL)) == 0 ) {
1537 /* Tell everyone we updated smb.conf. */
1538 message_send_all(smbd_messaging_context(),
1539 MSG_SMB_CONF_UPDATED,
1540 NULL, 0, NULL);
1543 if ( is_disk_op )
1544 unbecome_root();
1546 /********* END SeDiskOperatorPrivilege BLOCK *********/
1548 SAFE_FREE(command);
1550 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1551 command, ret ));
1552 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1555 if (lp_registry_shares()) {
1556 char *keyname;
1557 WERROR err;
1559 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1560 sharename) == -1) {
1561 return WERR_NOMEM;
1564 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1565 keyname);
1566 SAFE_FREE(keyname);
1567 return err;
1570 return WERR_ACCESS_DENIED;
1573 static WERROR change_share(const char *share_name, const char *path,
1574 const char *comment, uint32 max_connections,
1575 const struct nt_user_token *token,
1576 BOOL is_disk_op)
1578 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1579 char *command;
1580 int ret;
1582 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1583 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1584 path, comment, max_connections) == -1) {
1585 return WERR_NOMEM;
1588 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1590 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1592 if ( is_disk_op )
1593 become_root();
1595 if ( (ret = smbrun(command, NULL)) == 0 ) {
1596 /* Tell everyone we updated smb.conf. */
1597 message_send_all(smbd_messaging_context(),
1598 MSG_SMB_CONF_UPDATED,
1599 NULL, 0, NULL);
1602 if ( is_disk_op )
1603 unbecome_root();
1605 /********* END SeDiskOperatorPrivilege BLOCK *********/
1607 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1608 "(%d)\n", command, ret ));
1610 SAFE_FREE(command);
1612 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1615 if (lp_registry_shares()) {
1616 char *keyname;
1617 struct registry_key *key;
1618 WERROR err;
1619 TALLOC_CTX *mem_ctx;
1621 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1622 share_name))) {
1623 return WERR_NOMEM;
1626 mem_ctx = (TALLOC_CTX *)keyname;
1628 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1629 is_disk_op ? get_root_nt_token():token,
1630 &key);
1631 if (!W_ERROR_IS_OK(err)) {
1632 TALLOC_FREE(mem_ctx);
1633 return err;
1636 setval_helper(key, "path", path, &err);
1638 reg_deletevalue(key, "comment");
1639 if ((comment != NULL) && (comment[0] != '\0')) {
1640 setval_helper(key, "comment", comment, &err);
1643 reg_deletevalue(key, "max connections");
1644 if (max_connections != 0) {
1645 char tmp[16];
1646 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1647 setval_helper(key, "max connections", tmp, &err);
1650 TALLOC_FREE(mem_ctx);
1651 return err;
1654 return WERR_ACCESS_DENIED;
1657 /*******************************************************************
1658 Net share set info. Modify share details.
1659 ********************************************************************/
1661 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1663 pstring comment;
1664 pstring pathname;
1665 int type;
1666 int snum;
1667 char *path;
1668 SEC_DESC *psd = NULL;
1669 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1670 BOOL is_disk_op = False;
1671 int max_connections = 0;
1672 fstring tmp_share_name;
1674 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1676 if (r->out.parm_error) {
1677 *r->out.parm_error = 0;
1680 if ( strequal(r->in.share_name,"IPC$")
1681 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1682 || strequal(r->in.share_name,"global") )
1684 return WERR_ACCESS_DENIED;
1687 fstrcpy(tmp_share_name, r->in.share_name);
1688 snum = find_service(tmp_share_name);
1690 /* Does this share exist ? */
1691 if (snum < 0)
1692 return WERR_NET_NAME_NOT_FOUND;
1694 /* No change to printer shares. */
1695 if (lp_print_ok(snum))
1696 return WERR_ACCESS_DENIED;
1698 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1699 &se_diskop );
1701 /* fail out now if you are not root and not a disk op */
1703 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1704 return WERR_ACCESS_DENIED;
1706 switch (r->in.level) {
1707 case 1:
1708 pstrcpy(pathname, lp_pathname(snum));
1709 pstrcpy(comment, r->in.info.info1->comment);
1710 type = r->in.info.info1->type;
1711 psd = NULL;
1712 break;
1713 case 2:
1714 pstrcpy(comment, r->in.info.info2->comment);
1715 pstrcpy(pathname, r->in.info.info2->path);
1716 type = r->in.info.info2->type;
1717 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1718 0 : r->in.info.info2->max_users;
1719 psd = NULL;
1720 break;
1721 case 502:
1722 pstrcpy(comment, r->in.info.info502->comment);
1723 pstrcpy(pathname, r->in.info.info502->path);
1724 type = r->in.info.info502->type;
1725 psd = r->in.info.info502->sd;
1726 map_generic_share_sd_bits(psd);
1727 break;
1728 case 1004:
1729 pstrcpy(pathname, lp_pathname(snum));
1730 pstrcpy(comment, r->in.info.info1004->comment);
1731 type = STYPE_DISKTREE;
1732 break;
1733 case 1005:
1734 /* XP re-sets the csc policy even if it wasn't changed by the
1735 user, so we must compare it to see if it's what is set in
1736 smb.conf, so that we can contine other ops like setting
1737 ACLs on a share */
1738 if (((r->in.info.info1005->dfs_flags &
1739 SHARE_1005_CSC_POLICY_MASK) >>
1740 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1741 return WERR_OK;
1742 else {
1743 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1744 "to change csc policy from the network; "
1745 "must be done with smb.conf\n"));
1746 return WERR_ACCESS_DENIED;
1748 case 1006:
1749 case 1007:
1750 return WERR_ACCESS_DENIED;
1751 case 1501:
1752 pstrcpy(pathname, lp_pathname(snum));
1753 pstrcpy(comment, lp_comment(snum));
1754 psd = r->in.info.info1501->sd;
1755 map_generic_share_sd_bits(psd);
1756 type = STYPE_DISKTREE;
1757 break;
1758 default:
1759 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1760 "%d\n", r->in.level));
1761 return WERR_UNKNOWN_LEVEL;
1764 /* We can only modify disk shares. */
1765 if (type != STYPE_DISKTREE)
1766 return WERR_ACCESS_DENIED;
1768 /* Check if the pathname is valid. */
1769 if (!(path = valid_share_pathname( pathname )))
1770 return WERR_OBJECT_PATH_INVALID;
1772 /* Ensure share name, pathname and comment don't contain '"'
1773 * characters. */
1774 string_replace(tmp_share_name, '"', ' ');
1775 string_replace(path, '"', ' ');
1776 string_replace(comment, '"', ' ');
1778 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1779 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1781 /* Only call modify function if something changed. */
1783 if (strcmp(path, lp_pathname(snum))
1784 || strcmp(comment, lp_comment(snum))
1785 || (lp_max_connections(snum) != max_connections) ) {
1786 WERROR err;
1788 err = change_share(tmp_share_name, path, comment,
1789 max_connections, p->pipe_user.nt_user_token,
1790 is_disk_op);
1792 if (!W_ERROR_IS_OK(err)) {
1793 return err;
1797 /* Replace SD if changed. */
1798 if (psd) {
1799 SEC_DESC *old_sd;
1800 size_t sd_size;
1802 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1803 &sd_size);
1805 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1806 if (!set_share_security(r->in.share_name, psd)) {
1807 DEBUG(0,("_srv_net_share_set_info: Failed to "
1808 "change security info in share %s.\n",
1809 r->in.share_name ));
1814 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1816 return WERR_OK;
1820 /*******************************************************************
1821 Net share add. Call 'add_share_command "sharename" "pathname"
1822 "comment" "max connections = "
1823 ********************************************************************/
1825 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1827 pstring share_name;
1828 pstring comment;
1829 pstring pathname;
1830 char *path;
1831 int type;
1832 SEC_DESC *psd = NULL;
1833 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1834 BOOL is_disk_op;
1835 uint32 max_connections = 0;
1836 WERROR err;
1838 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1840 if (r->out.parm_error) {
1841 *r->out.parm_error = 0;
1844 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1845 &se_diskop );
1847 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1848 return WERR_ACCESS_DENIED;
1850 switch (r->in.level) {
1851 case 0:
1852 /* No path. Not enough info in a level 0 to do anything. */
1853 return WERR_ACCESS_DENIED;
1854 case 1:
1855 /* Not enough info in a level 1 to do anything. */
1856 return WERR_ACCESS_DENIED;
1857 case 2:
1858 pstrcpy(share_name, r->in.info.info2->name);
1859 pstrcpy(comment, r->in.info.info2->comment);
1860 pstrcpy(pathname, r->in.info.info2->path);
1861 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1862 0 : r->in.info.info2->max_users;
1863 type = r->in.info.info2->type;
1864 break;
1865 case 501:
1866 /* No path. Not enough info in a level 501 to do anything. */
1867 return WERR_ACCESS_DENIED;
1868 case 502:
1869 pstrcpy(share_name, r->in.info.info502->name);
1870 pstrcpy(comment, r->in.info.info502->comment);
1871 pstrcpy(pathname, r->in.info.info502->path);
1872 type = r->in.info.info502->type;
1873 psd = r->in.info.info502->sd;
1874 map_generic_share_sd_bits(psd);
1875 break;
1877 /* none of the following contain share names. NetShareAdd
1878 * does not have a separate parameter for the share name */
1880 case 1004:
1881 case 1005:
1882 case 1006:
1883 case 1007:
1884 return WERR_ACCESS_DENIED;
1885 case 1501:
1886 /* DFS only level. */
1887 return WERR_ACCESS_DENIED;
1888 default:
1889 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1890 r->in.level));
1891 return WERR_UNKNOWN_LEVEL;
1894 /* check for invalid share names */
1896 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1897 sizeof(share_name) ) ) {
1898 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1899 share_name));
1900 return WERR_INVALID_NAME;
1903 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1904 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1906 return WERR_ACCESS_DENIED;
1909 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1910 /* Share already exists. */
1911 return WERR_ALREADY_EXISTS;
1914 /* We can only add disk shares. */
1915 if (type != STYPE_DISKTREE)
1916 return WERR_ACCESS_DENIED;
1918 /* Check if the pathname is valid. */
1919 if (!(path = valid_share_pathname( pathname )))
1920 return WERR_OBJECT_PATH_INVALID;
1922 /* Ensure share name, pathname and comment don't contain '"'
1923 * characters. */
1925 string_replace(share_name, '"', ' ');
1926 string_replace(path, '"', ' ');
1927 string_replace(comment, '"', ' ');
1929 err = add_share(share_name, path, comment, max_connections,
1930 p->pipe_user.nt_user_token, is_disk_op);
1932 if (!W_ERROR_IS_OK(err)) {
1933 return err;
1936 if (psd) {
1937 if (!set_share_security(share_name, psd)) {
1938 DEBUG(0,("_srv_net_share_add: Failed to add security "
1939 "info to share %s.\n", share_name ));
1944 * We don't call reload_services() here, the message will
1945 * cause this to be done before the next packet is read
1946 * from the client. JRA.
1949 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1951 return WERR_OK;
1954 /*******************************************************************
1955 Net share delete. Call "delete share command" with the share name as
1956 a parameter.
1957 ********************************************************************/
1959 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1961 struct share_params *params;
1962 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1963 BOOL is_disk_op;
1964 WERROR err;
1966 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1968 if ( strequal(r->in.share_name, "IPC$")
1969 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1970 || strequal(r->in.share_name, "global") )
1972 return WERR_ACCESS_DENIED;
1975 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1976 return WERR_NO_SUCH_SHARE;
1979 /* No change to printer shares. */
1980 if (lp_print_ok(params->service))
1981 return WERR_ACCESS_DENIED;
1983 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1984 &se_diskop );
1986 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1987 return WERR_ACCESS_DENIED;
1989 err = delete_share(lp_servicename(params->service),
1990 p->pipe_user.nt_user_token, is_disk_op);
1992 if (!W_ERROR_IS_OK(err)) {
1993 return err;
1996 /* Delete the SD in the database. */
1997 delete_share_security(params);
1999 lp_killservice(params->service);
2001 return WERR_OK;
2004 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
2006 struct srvsvc_NetShareDel s;
2008 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
2010 s.in.server_unc = r->in.server_unc;
2011 s.in.share_name = r->in.share_name;
2012 s.in.reserved = r->in.reserved;
2014 return _srvsvc_NetShareDel(p, &s);
2017 /*******************************************************************
2018 time of day
2019 ********************************************************************/
2021 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
2023 struct tm *t;
2024 time_t unixdate = time(NULL);
2025 WERROR status = WERR_OK;
2027 /* We do this call first as if we do it *after* the gmtime call
2028 it overwrites the pointed-to values. JRA */
2030 uint32 zone = get_time_zone(unixdate)/60;
2032 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2034 t = gmtime(&unixdate);
2036 /* set up the */
2037 r->out.info->elapsed = unixdate;
2038 r->out.info->msecs = 0;
2039 r->out.info->hours = t->tm_hour;
2040 r->out.info->mins = t->tm_min;
2041 r->out.info->secs = t->tm_sec;
2042 r->out.info->hunds = 0;
2043 r->out.info->timezone = zone;
2044 r->out.info->tinterval = 10000;
2045 r->out.info->day = t->tm_mday;
2046 r->out.info->month = t->tm_mon + 1;
2047 r->out.info->year = 1900+t->tm_year;
2048 r->out.info->weekday = t->tm_wday;
2050 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2052 return status;
2055 /***********************************************************************************
2056 Win9x NT tools get security descriptor.
2057 ***********************************************************************************/
2059 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2061 SEC_DESC *psd = NULL;
2062 size_t sd_size;
2063 DATA_BLOB null_pw;
2064 files_struct *fsp = NULL;
2065 SMB_STRUCT_STAT st;
2066 NTSTATUS nt_status;
2067 connection_struct *conn = NULL;
2068 BOOL became_user = False;
2069 WERROR status = WERR_OK;
2070 char *tmp_file = NULL;
2071 TALLOC_CTX *ctx = talloc_tos();
2073 ZERO_STRUCT(st);
2076 /* Null password is ok - we are already an authenticated user... */
2077 null_pw = data_blob_null;
2079 become_root();
2080 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2081 unbecome_root();
2083 if (conn == NULL) {
2084 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2085 status = ntstatus_to_werror(nt_status);
2086 goto error_exit;
2089 if (!become_user(conn, conn->vuid)) {
2090 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2091 status = WERR_ACCESS_DENIED;
2092 goto error_exit;
2094 became_user = True;
2096 if (!r->in.file) {
2097 status = WERR_INVALID_PARAM;
2098 goto error_exit;
2100 nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st);
2101 if (!NT_STATUS_IS_OK(nt_status)) {
2102 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2103 status = WERR_ACCESS_DENIED;
2104 goto error_exit;
2107 nt_status = check_name(conn, tmp_file);
2108 if (!NT_STATUS_IS_OK(nt_status)) {
2109 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", tmp_file));
2110 status = WERR_ACCESS_DENIED;
2111 goto error_exit;
2114 nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
2115 if (!NT_STATUS_IS_OK(nt_status)) {
2116 /* Perhaps it is a directory */
2117 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2118 nt_status = open_directory(conn, NULL, tmp_file, &st,
2119 READ_CONTROL_ACCESS,
2120 FILE_SHARE_READ|FILE_SHARE_WRITE,
2121 FILE_OPEN,
2123 FILE_ATTRIBUTE_DIRECTORY,
2124 NULL, &fsp);
2126 if (!NT_STATUS_IS_OK(nt_status)) {
2127 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", tmp_file));
2128 status = WERR_ACCESS_DENIED;
2129 goto error_exit;
2133 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2135 if (sd_size == 0) {
2136 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", tmp_file));
2137 status = WERR_ACCESS_DENIED;
2138 goto error_exit;
2141 r->out.sd_buf->sd_size= sd_size;
2142 r->out.sd_buf->sd = psd;
2144 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2146 close_file(fsp, NORMAL_CLOSE);
2147 unbecome_user();
2148 close_cnum(conn, p->pipe_user.vuid);
2149 return status;
2151 error_exit:
2153 if(fsp) {
2154 close_file(fsp, NORMAL_CLOSE);
2157 if (became_user)
2158 unbecome_user();
2160 if (conn)
2161 close_cnum(conn, p->pipe_user.vuid);
2163 return status;
2166 /***********************************************************************************
2167 Win9x NT tools set security descriptor.
2168 ***********************************************************************************/
2170 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2172 DATA_BLOB null_pw;
2173 files_struct *fsp = NULL;
2174 SMB_STRUCT_STAT st;
2175 NTSTATUS nt_status;
2176 connection_struct *conn = NULL;
2177 BOOL became_user = False;
2178 WERROR status = WERR_OK;
2179 char *tmp_file = NULL;
2180 TALLOC_CTX *ctx = talloc_tos();
2182 ZERO_STRUCT(st);
2184 /* Null password is ok - we are already an authenticated user... */
2185 null_pw = data_blob_null;
2187 become_root();
2188 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2189 unbecome_root();
2191 if (conn == NULL) {
2192 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2193 status = ntstatus_to_werror(nt_status);
2194 goto error_exit;
2197 if (!become_user(conn, conn->vuid)) {
2198 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2199 status = WERR_ACCESS_DENIED;
2200 goto error_exit;
2202 became_user = True;
2204 if (!r->in.file) {
2205 status = WERR_INVALID_PARAM;
2206 goto error_exit;
2208 nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st);
2209 if (!NT_STATUS_IS_OK(nt_status)) {
2210 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2211 status = WERR_ACCESS_DENIED;
2212 goto error_exit;
2215 nt_status = check_name(conn, tmp_file);
2216 if (!NT_STATUS_IS_OK(nt_status)) {
2217 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", tmp_file));
2218 status = WERR_ACCESS_DENIED;
2219 goto error_exit;
2223 nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp);
2225 if (!NT_STATUS_IS_OK(nt_status)) {
2226 /* Perhaps it is a directory */
2227 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2228 nt_status = open_directory(conn, NULL, tmp_file, &st,
2229 FILE_READ_ATTRIBUTES,
2230 FILE_SHARE_READ|FILE_SHARE_WRITE,
2231 FILE_OPEN,
2233 FILE_ATTRIBUTE_DIRECTORY,
2234 NULL, &fsp);
2236 if (!NT_STATUS_IS_OK(nt_status)) {
2237 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", tmp_file));
2238 status = WERR_ACCESS_DENIED;
2239 goto error_exit;
2243 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2245 if (!NT_STATUS_IS_OK(nt_status)) {
2246 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", tmp_file));
2247 status = WERR_ACCESS_DENIED;
2248 goto error_exit;
2251 close_file(fsp, NORMAL_CLOSE);
2252 unbecome_user();
2253 close_cnum(conn, p->pipe_user.vuid);
2254 return status;
2256 error_exit:
2258 if(fsp) {
2259 close_file(fsp, NORMAL_CLOSE);
2262 if (became_user) {
2263 unbecome_user();
2266 if (conn) {
2267 close_cnum(conn, p->pipe_user.vuid);
2270 return status;
2273 /***********************************************************************************
2274 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2275 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2276 These disks would the disks listed by this function.
2277 Users could then create shares relative to these disks. Watch out for moving these disks around.
2278 "Nigel Williams" <nigel@veritas.com>.
2279 ***********************************************************************************/
2281 static const char *server_disks[] = {"C:"};
2283 static uint32 get_server_disk_count(void)
2285 return sizeof(server_disks)/sizeof(server_disks[0]);
2288 static uint32 init_server_disk_enum(uint32 *resume)
2290 uint32 server_disk_count = get_server_disk_count();
2292 /*resume can be an offset into the list for now*/
2294 if(*resume & 0x80000000)
2295 *resume = 0;
2297 if(*resume > server_disk_count)
2298 *resume = server_disk_count;
2300 return server_disk_count - *resume;
2303 static const char *next_server_disk_enum(uint32 *resume)
2305 const char *disk;
2307 if(init_server_disk_enum(resume) == 0)
2308 return NULL;
2310 disk = server_disks[*resume];
2312 (*resume)++;
2314 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2316 return disk;
2319 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2321 uint32 i;
2322 const char *disk_name;
2324 WERROR status = WERR_OK;
2326 *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2327 r->out.info->count = 0;
2329 if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2330 return WERR_NOMEM;
2333 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2335 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2337 r->out.info->count++;
2338 (*r->out.totalentries)++;
2340 /*copy disk name into a unicode string*/
2342 r->out.info->disks[i].disk = disk_name;
2345 /* add a terminating null string. Is this there if there is more data to come? */
2347 r->out.info->count++;
2348 (*r->out.totalentries)++;
2350 r->out.info->disks[i].disk = "";
2352 return status;
2355 /********************************************************************
2356 ********************************************************************/
2358 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2360 int len;
2362 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2363 return WERR_INVALID_PARAM;
2366 switch ( r->in.name_type ) {
2367 case 0x9:
2368 len = strlen_m(r->in.name);
2370 if ((r->in.flags == 0x0) && (len > 81)) {
2371 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2372 return WERR_INVALID_NAME;
2374 if ((r->in.flags == 0x80000000) && (len > 13)) {
2375 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2376 return WERR_INVALID_NAME;
2379 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2380 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2381 return WERR_INVALID_NAME;
2383 break;
2385 default:
2386 return WERR_UNKNOWN_LEVEL;
2389 return WERR_OK;
2393 /********************************************************************
2394 ********************************************************************/
2396 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2398 return WERR_ACCESS_DENIED;
2401 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2403 p->rng_fault_state = True;
2404 return WERR_NOT_SUPPORTED;
2407 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2409 p->rng_fault_state = True;
2410 return WERR_NOT_SUPPORTED;
2413 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2415 p->rng_fault_state = True;
2416 return WERR_NOT_SUPPORTED;
2419 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2421 p->rng_fault_state = True;
2422 return WERR_NOT_SUPPORTED;
2425 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2427 p->rng_fault_state = True;
2428 return WERR_NOT_SUPPORTED;
2431 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2433 p->rng_fault_state = True;
2434 return WERR_NOT_SUPPORTED;
2437 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2439 p->rng_fault_state = True;
2440 return WERR_NOT_SUPPORTED;
2443 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2445 p->rng_fault_state = True;
2446 return WERR_NOT_SUPPORTED;
2449 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2451 p->rng_fault_state = True;
2452 return WERR_NOT_SUPPORTED;
2455 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2457 p->rng_fault_state = True;
2458 return WERR_NOT_SUPPORTED;
2461 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2463 p->rng_fault_state = True;
2464 return WERR_NOT_SUPPORTED;
2467 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2469 p->rng_fault_state = True;
2470 return WERR_NOT_SUPPORTED;
2473 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2475 p->rng_fault_state = True;
2476 return WERR_NOT_SUPPORTED;
2479 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2481 p->rng_fault_state = True;
2482 return WERR_NOT_SUPPORTED;
2485 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2487 p->rng_fault_state = True;
2488 return WERR_NOT_SUPPORTED;
2491 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2493 p->rng_fault_state = True;
2494 return WERR_NOT_SUPPORTED;
2497 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2499 p->rng_fault_state = True;
2500 return WERR_NOT_SUPPORTED;
2503 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2505 p->rng_fault_state = True;
2506 return WERR_NOT_SUPPORTED;
2509 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2511 p->rng_fault_state = True;
2512 return WERR_NOT_SUPPORTED;
2515 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2517 p->rng_fault_state = True;
2518 return WERR_NOT_SUPPORTED;
2521 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2523 p->rng_fault_state = True;
2524 return WERR_NOT_SUPPORTED;
2527 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2529 p->rng_fault_state = True;
2530 return WERR_NOT_SUPPORTED;
2533 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2535 p->rng_fault_state = True;
2536 return WERR_NOT_SUPPORTED;
2539 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2541 p->rng_fault_state = True;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2547 p->rng_fault_state = True;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2553 p->rng_fault_state = True;
2554 return WERR_NOT_SUPPORTED;
2557 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2559 p->rng_fault_state = True;
2560 return WERR_NOT_SUPPORTED;
2563 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;
2569 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2571 p->rng_fault_state = True;
2572 return WERR_NOT_SUPPORTED;
2575 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2577 p->rng_fault_state = True;
2578 return WERR_NOT_SUPPORTED;
2581 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2583 p->rng_fault_state = True;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2589 p->rng_fault_state = True;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2595 p->rng_fault_state = True;
2596 return WERR_NOT_SUPPORTED;
2599 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2601 p->rng_fault_state = True;
2602 return WERR_NOT_SUPPORTED;
2605 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2607 p->rng_fault_state = True;
2608 return WERR_NOT_SUPPORTED;