r25068: Older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for every opcode on the
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob1d370d3847b3182cb26d430a3b09c93f5e7163ea
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 2 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, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* This is the implementation of the srvsvc pipe. */
27 #include "includes.h"
29 #define MAX_SERVER_DISK_ENTRIES 15
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 /* Use for enumerating connections, pipes, & files */
39 struct file_enum_count {
40 TALLOC_CTX *ctx;
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;
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 struct srvsvc_NetFileInfo3 *f;
67 int i = fenum->count;
68 pstring fullpath;
70 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
72 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
73 if ( !f ) {
74 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
75 return 1;
78 fenum->info = f;
80 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82 fenum->info[i].num_locks = 0;
83 if (!(fenum->info[i].user = talloc_strdup(
84 fenum->ctx, uidtoname(prec.uid)))) {
85 /* There's not much we can do here. */
86 fenum->info[i].user = "";
88 if (!(fenum->info[i].path = talloc_strdup(
89 fenum->ctx, fullpath))) {
90 /* There's not much we can do here. */
91 fenum->info[i].path = "";
94 fenum->count++;
97 return 0;
100 /*******************************************************************
101 ********************************************************************/
103 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
104 uint32 *count, uint32 *resume )
106 struct file_enum_count fenum;
108 fenum.ctx = ctx;
109 fenum.info = *info;
110 fenum.count = *count;
112 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
113 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
114 "failed\n"));
115 return WERR_NOMEM;
118 *info = fenum.info;
119 *count = fenum.count;
121 return WERR_OK;
124 /*******************************************************************
125 ********************************************************************/
127 static void enum_file_fn( const struct share_mode_entry *e,
128 const char *sharepath, const char *fname,
129 void *private_data )
131 struct file_enum_count *fenum =
132 (struct file_enum_count *)&private_data;
134 /* If the pid was not found delete the entry from connections.tdb */
136 if ( process_exists(e->pid) ) {
137 struct srvsvc_NetFileInfo3 *f;
138 int i = fenum->count;
139 files_struct fsp;
140 struct byte_range_lock *brl;
141 int num_locks = 0;
142 pstring fullpath;
143 uint32 permissions;
145 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
146 if ( !f ) {
147 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
148 return;
150 fenum->info = f;
152 /* need to count the number of locks on a file */
154 ZERO_STRUCT( fsp );
155 fsp.file_id = e->id;
157 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158 num_locks = brl->num_locks;
159 TALLOC_FREE( brl );
162 if ( strcmp( fname, "." ) == 0 ) {
163 pstr_sprintf( fullpath, "C:%s", sharepath );
164 } else {
165 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
167 string_replace( fullpath, '/', '\\' );
169 /* mask out create (what ever that is) */
170 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
172 fenum->info[i].fid = e->share_file_id;
173 fenum->info[i].permissions = permissions;
174 fenum->info[i].num_locks = num_locks;
175 if (!(fenum->info[i].user = talloc_strdup(
176 fenum->ctx, uidtoname(e->uid)))) {
177 /* There's not much we can do here. */
178 fenum->info[i].user = "";
180 if (!(fenum->info[i].path = talloc_strdup(
181 fenum->ctx, fullpath))) {
182 /* There's not much we can do here. */
183 fenum->info[i].path = "";
186 fenum->count++;
189 return;
193 /*******************************************************************
194 ********************************************************************/
196 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
197 uint32 *count, uint32 *resume )
199 struct file_enum_count f_enum_cnt;
201 f_enum_cnt.ctx = ctx;
202 f_enum_cnt.count = *count;
203 f_enum_cnt.info = *info;
205 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
207 *info = f_enum_cnt.info;
208 *count = f_enum_cnt.count;
210 return WERR_OK;
213 /*******************************************************************
214 Utility function to get the 'type' of a share from a share definition.
215 ********************************************************************/
216 static uint32 get_share_type(const struct share_params *params)
218 char *net_name = lp_servicename(params->service);
219 int len_net_name = strlen(net_name);
221 /* work out the share type */
222 uint32 type = STYPE_DISKTREE;
224 if (lp_print_ok(params->service))
225 type = STYPE_PRINTQ;
226 if (strequal(lp_fstype(params->service), "IPC"))
227 type = STYPE_IPC;
228 if (net_name[len_net_name-1] == '$')
229 type |= STYPE_HIDDEN;
231 return type;
234 /*******************************************************************
235 Fill in a share info level 0 structure.
236 ********************************************************************/
238 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
239 const struct share_params *params)
241 sh0->name = lp_servicename(params->service);
244 /*******************************************************************
245 Fill in a share info level 1 structure.
246 ********************************************************************/
248 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
249 const struct share_params *params)
251 connection_struct *conn = p->conn;
253 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
254 conn->user, conn->connectpath, conn->gid,
255 get_current_username(),
256 current_user_info.domain,
257 lp_comment(params->service));
259 sh1->name = lp_servicename(params->service);
260 sh1->type = get_share_type(params);
263 /*******************************************************************
264 Fill in a share info level 2 structure.
265 ********************************************************************/
267 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
268 const struct share_params *params)
270 connection_struct *conn = p->conn;
271 char *remark;
272 char *path;
273 int max_connections = lp_max_connections(params->service);
274 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
275 int count = 0;
276 char *net_name = lp_servicename(params->service);
278 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
279 conn->user, conn->connectpath, conn->gid,
280 get_current_username(),
281 current_user_info.domain,
282 lp_comment(params->service));
283 path = talloc_asprintf(p->mem_ctx, "C:%s",
284 lp_pathname(params->service));
287 * Change / to \\ so that win2k will see it as a valid path. This was
288 * added to enable use of browsing in win2k add share dialog.
291 string_replace(path, '/', '\\');
293 count = count_current_connections( net_name, False );
294 sh2->name = net_name;
295 sh2->type = get_share_type(params);
296 sh2->comment = remark;
297 sh2->permissions = 0;
298 sh2->max_users = max_uses;
299 sh2->current_users = count;
300 sh2->path = path;
301 sh2->password = "";
304 /*******************************************************************
305 Map any generic bits to file specific bits.
306 ********************************************************************/
308 static void map_generic_share_sd_bits(SEC_DESC *psd)
310 int i;
311 SEC_ACL *ps_dacl = NULL;
313 if (!psd)
314 return;
316 ps_dacl = psd->dacl;
317 if (!ps_dacl)
318 return;
320 for (i = 0; i < ps_dacl->num_aces; i++) {
321 SEC_ACE *psa = &ps_dacl->aces[i];
322 uint32 orig_mask = psa->access_mask;
324 se_map_generic(&psa->access_mask, &file_generic_mapping);
325 psa->access_mask |= orig_mask;
329 /*******************************************************************
330 Fill in a share info level 501 structure.
331 ********************************************************************/
333 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
334 const struct share_params *params)
336 connection_struct *conn = p->conn;
337 char *remark;
338 const char *net_name = lp_servicename(params->service);
340 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
341 conn->user, conn->connectpath, conn->gid,
342 get_current_username(),
343 current_user_info.domain,
344 lp_comment(params->service));
347 sh501->name = net_name;
348 sh501->type = get_share_type(params);
349 sh501->comment = remark;
350 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
353 /*******************************************************************
354 Fill in a share info level 502 structure.
355 ********************************************************************/
357 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
358 const struct share_params *params)
360 int max_connections = lp_max_connections(params->service);
361 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
362 connection_struct *conn = p->conn;
363 int count;
364 char *net_name;
365 char *remark;
366 char *path;
367 SEC_DESC *sd;
368 size_t sd_size;
369 TALLOC_CTX *ctx = p->mem_ctx;
372 ZERO_STRUCTP(sh502);
374 net_name = lp_servicename(params->service);
375 count = count_current_connections( net_name, False );
377 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
378 conn->user, conn->connectpath, conn->gid,
379 get_current_username(),
380 current_user_info.domain,
381 lp_comment(params->service));
383 path = talloc_asprintf(p->mem_ctx, "C:%s",
384 lp_pathname(params->service));
387 * Change / to \\ so that win2k will see it as a valid path. This was
388 * added to enable use of browsing in win2k add share dialog.
391 string_replace(path, '/', '\\');
393 sd = get_share_security(ctx, lp_servicename(params->service),
394 &sd_size);
396 sh502->name = net_name;
397 sh502->type = get_share_type(params);
398 sh502->comment = remark;
399 sh502->path = path;
400 sh502->password = "";
401 sh502->sd = sd;
402 sh502->permissions = 0;
403 sh502->max_users = max_uses;
404 sh502->current_users = count;
405 sh502->unknown = 1;
408 /***************************************************************************
409 Fill in a share info level 1004 structure.
410 ***************************************************************************/
412 static void init_srv_share_info_1004(pipes_struct *p,
413 struct srvsvc_NetShareInfo1004* sh1004,
414 const struct share_params *params)
416 connection_struct *conn = p->conn;
417 char *remark;
419 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
420 conn->user, conn->connectpath, conn->gid,
421 get_current_username(),
422 current_user_info.domain,
423 lp_comment(params->service));
425 ZERO_STRUCTP(sh1004);
427 sh1004->comment = remark;
430 /***************************************************************************
431 Fill in a share info level 1005 structure.
432 ***************************************************************************/
434 static void init_srv_share_info_1005(pipes_struct *p,
435 struct srvsvc_NetShareInfo1005* sh1005,
436 const struct share_params *params)
438 sh1005->dfs_flags = 0;
440 if(lp_host_msdfs() && lp_msdfs_root(params->service))
441 sh1005->dfs_flags |=
442 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
443 sh1005->dfs_flags |=
444 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
446 /***************************************************************************
447 Fill in a share info level 1006 structure.
448 ***************************************************************************/
450 static void init_srv_share_info_1006(pipes_struct *p,
451 struct srvsvc_NetShareInfo1006* sh1006,
452 const struct share_params *params)
454 sh1006->max_users = -1;
457 /***************************************************************************
458 Fill in a share info level 1007 structure.
459 ***************************************************************************/
461 static void init_srv_share_info_1007(pipes_struct *p,
462 struct srvsvc_NetShareInfo1007* sh1007,
463 const struct share_params *params)
465 uint32 flags = 0;
467 ZERO_STRUCTP(sh1007);
469 sh1007->flags = flags;
470 sh1007->alternate_directory_name = "";
473 /*******************************************************************
474 Fill in a share info level 1501 structure.
475 ********************************************************************/
477 static void init_srv_share_info_1501(pipes_struct *p,
478 struct sec_desc_buf *sh1501,
479 const struct share_params *params)
481 SEC_DESC *sd;
482 size_t sd_size;
483 TALLOC_CTX *ctx = p->mem_ctx;
485 ZERO_STRUCTP(sh1501);
487 sd = get_share_security(ctx, lp_servicename(params->service),
488 &sd_size);
490 sh1501->sd = sd;
493 /*******************************************************************
494 True if it ends in '$'.
495 ********************************************************************/
497 static BOOL is_hidden_share(const struct share_params *params)
499 const char *net_name = lp_servicename(params->service);
501 return (net_name[strlen(net_name) - 1] == '$');
504 /*******************************************************************
505 Fill in a share info structure.
506 ********************************************************************/
508 static WERROR init_srv_share_info_ctr(pipes_struct *p,
509 union srvsvc_NetShareCtr *ctr,
510 uint32 info_level, uint32 *resume_hnd,
511 uint32 *total_entries, BOOL all_shares)
513 TALLOC_CTX *ctx = p->mem_ctx;
514 struct share_iterator *shares;
515 struct share_params *share;
516 WERROR result = WERR_NOMEM;
518 DEBUG(5,("init_srv_share_info_ctr\n"));
520 ZERO_STRUCTP(ctr);
522 if (resume_hnd) {
523 *resume_hnd = 0;
526 /* Ensure all the usershares are loaded. */
527 become_root();
528 load_usershare_shares();
529 load_registry_shares();
530 unbecome_root();
532 *total_entries = 0;
534 if (!(shares = share_list_all(ctx))) {
535 DEBUG(5, ("Could not list shares\n"));
536 return WERR_ACCESS_DENIED;
539 switch (info_level) {
540 case 0:
541 if (!(ctr->ctr0 = TALLOC_ZERO_P(
542 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
543 goto done;
545 break;
546 case 1:
547 if (!(ctr->ctr1 = TALLOC_ZERO_P(
548 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
549 goto done;
551 break;
552 case 2:
553 if (!(ctr->ctr2 = TALLOC_ZERO_P(
554 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
555 goto done;
557 break;
558 case 501:
559 if (!(ctr->ctr501 = TALLOC_ZERO_P(
560 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
561 goto done;
563 break;
564 case 502:
565 if (!(ctr->ctr502 = TALLOC_ZERO_P(
566 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
567 goto done;
569 break;
570 case 1004:
571 if (!(ctr->ctr1004 = TALLOC_ZERO_P(
572 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
573 goto done;
575 break;
576 case 1005:
577 if (!(ctr->ctr1005 = TALLOC_ZERO_P(
578 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
579 goto done;
581 break;
582 case 1006:
583 if (!(ctr->ctr1006 = TALLOC_ZERO_P(
584 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
585 goto done;
587 break;
588 case 1007:
589 if (!(ctr->ctr1007 = TALLOC_ZERO_P(
590 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
591 goto done;
593 break;
594 case 1501:
595 if (!(ctr->ctr1501 = TALLOC_ZERO_P(
596 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
597 goto done;
599 break;
600 default:
601 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
602 "value %d\n", info_level));
603 return WERR_UNKNOWN_LEVEL;
606 while ((share = next_share(shares)) != NULL) {
607 if (!lp_browseable(share->service)) {
608 continue;
610 if (!all_shares && is_hidden_share(share)) {
611 continue;
614 switch (info_level) {
615 case 0:
617 struct srvsvc_NetShareInfo0 i;
618 init_srv_share_info_0(p, &i, share);
619 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
620 &ctr->ctr0->array, &ctr->ctr0->count);
621 if (ctr->ctr0->array == NULL) {
622 return WERR_NOMEM;
624 *total_entries = ctr->ctr0->count;
625 break;
628 case 1:
630 struct srvsvc_NetShareInfo1 i;
631 init_srv_share_info_1(p, &i, share);
632 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
633 &ctr->ctr1->array, &ctr->ctr1->count);
634 if (ctr->ctr1->array == NULL) {
635 return WERR_NOMEM;
637 *total_entries = ctr->ctr1->count;
638 break;
641 case 2:
643 struct srvsvc_NetShareInfo2 i;
644 init_srv_share_info_2(p, &i, share);
645 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
646 &ctr->ctr2->array, &ctr->ctr2->count);
647 if (ctr->ctr2->array == NULL) {
648 return WERR_NOMEM;
650 *total_entries = ctr->ctr2->count;
651 break;
654 case 501:
656 struct srvsvc_NetShareInfo501 i;
657 init_srv_share_info_501(p, &i, share);
658 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
659 &ctr->ctr501->array, &ctr->ctr501->count);
660 if (ctr->ctr501->array == NULL) {
661 return WERR_NOMEM;
663 *total_entries = ctr->ctr501->count;
664 break;
667 case 502:
669 struct srvsvc_NetShareInfo502 i;
670 init_srv_share_info_502(p, &i, share);
671 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
672 &ctr->ctr502->array, &ctr->ctr502->count);
673 if (ctr->ctr502->array == NULL) {
674 return WERR_NOMEM;
676 *total_entries = ctr->ctr502->count;
677 break;
680 /* here for completeness but not currently used with enum
681 * (1004 - 1501)*/
683 case 1004:
685 struct srvsvc_NetShareInfo1004 i;
686 init_srv_share_info_1004(p, &i, share);
687 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
688 &ctr->ctr1004->array, &ctr->ctr1004->count);
689 if (ctr->ctr1004->array == NULL) {
690 return WERR_NOMEM;
692 *total_entries = ctr->ctr1004->count;
693 break;
696 case 1005:
698 struct srvsvc_NetShareInfo1005 i;
699 init_srv_share_info_1005(p, &i, share);
700 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
701 &ctr->ctr1005->array, &ctr->ctr1005->count);
702 if (ctr->ctr1005->array == NULL) {
703 return WERR_NOMEM;
705 *total_entries = ctr->ctr1005->count;
706 break;
709 case 1006:
711 struct srvsvc_NetShareInfo1006 i;
712 init_srv_share_info_1006(p, &i, share);
713 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
714 &ctr->ctr1006->array, &ctr->ctr1006->count);
715 if (ctr->ctr1006->array == NULL) {
716 return WERR_NOMEM;
718 *total_entries = ctr->ctr1006->count;
719 break;
722 case 1007:
724 struct srvsvc_NetShareInfo1007 i;
725 init_srv_share_info_1007(p, &i, share);
726 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
727 &ctr->ctr1007->array, &ctr->ctr1007->count);
728 if (ctr->ctr1007->array == NULL) {
729 return WERR_NOMEM;
731 *total_entries = ctr->ctr1007->count;
732 break;
735 case 1501:
737 struct sec_desc_buf i;
738 init_srv_share_info_1501(p, &i, share);
739 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
740 &ctr->ctr1501->array, &ctr->ctr1501->count);
741 if (ctr->ctr1501->array == NULL) {
742 return WERR_NOMEM;
744 *total_entries = ctr->ctr1501->count;
745 break;
749 TALLOC_FREE(share);
752 result = WERR_OK;
753 done:
754 TALLOC_FREE(shares);
755 return result;
758 /*******************************************************************
759 fill in a sess info level 0 structure.
760 ********************************************************************/
762 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
764 struct sessionid *session_list;
765 uint32 num_entries = 0;
766 (*stot) = list_sessions(p->mem_ctx, &session_list);
768 if (ss0 == NULL) {
769 if (snum) {
770 (*snum) = 0;
772 return;
775 DEBUG(5,("init_srv_sess_0_ss0\n"));
777 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
779 if (snum) {
780 for (; (*snum) < (*stot); (*snum)++) {
781 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
782 num_entries++;
785 ss0->count = num_entries;
787 if ((*snum) >= (*stot)) {
788 (*snum) = 0;
791 } else {
792 ss0->array = NULL;
793 ss0->count = 0;
797 /*******************************************************************
798 ********************************************************************/
800 static void sess_file_fn( const struct share_mode_entry *e,
801 const char *sharepath, const char *fname,
802 void *private_data )
804 struct sess_file_count *sess = (struct sess_file_count *)private_data;
806 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
807 sess->count++;
810 return;
813 /*******************************************************************
814 ********************************************************************/
816 static int net_count_files( uid_t uid, struct server_id pid )
818 struct sess_file_count s_file_cnt;
820 s_file_cnt.count = 0;
821 s_file_cnt.uid = uid;
822 s_file_cnt.pid = pid;
824 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
826 return s_file_cnt.count;
829 /*******************************************************************
830 fill in a sess info level 1 structure.
831 ********************************************************************/
833 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
835 struct sessionid *session_list;
836 uint32 num_entries = 0;
837 time_t now = time(NULL);
839 if ( !snum ) {
840 ss1->count = 0;
841 ss1->array = NULL;
843 (*stot) = 0;
845 return;
848 if (ss1 == NULL) {
849 if (snum != NULL)
850 (*snum) = 0;
851 return;
854 (*stot) = list_sessions(p->mem_ctx, &session_list);
856 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
858 for (; (*snum) < (*stot); (*snum)++) {
859 uint32 num_files;
860 uint32 connect_time;
861 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
862 BOOL guest;
864 if ( !pw ) {
865 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
866 session_list[*snum].username));
867 continue;
870 connect_time = (uint32)(now - session_list[*snum].connect_start);
871 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
872 guest = strequal( session_list[*snum].username, lp_guestaccount() );
874 if (!(ss1->array[num_entries].client = talloc_strdup(
875 ss1->array, session_list[*snum].remote_machine))) {
876 ss1->array[num_entries].client = "";
878 if (!(ss1->array[num_entries].user = talloc_strdup(
879 ss1->array, session_list[*snum].username))) {
880 ss1->array[num_entries].user = "";
882 ss1->array[num_entries].num_open = num_files;
883 ss1->array[num_entries].time = connect_time;
884 ss1->array[num_entries].idle_time = 0;
885 ss1->array[num_entries].user_flags = guest;
887 num_entries++;
890 ss1->count = num_entries;
892 if ((*snum) >= (*stot)) {
893 (*snum) = 0;
897 /*******************************************************************
898 makes a SRV_R_NET_SESS_ENUM structure.
899 ********************************************************************/
901 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
902 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
904 WERROR status = WERR_OK;
905 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
907 switch (switch_value) {
908 case 0:
909 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
910 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
911 break;
912 case 1:
913 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
914 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
915 break;
916 default:
917 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
918 if (resume_hnd != NULL)
919 (*resume_hnd) = 0;
920 (*total_entries) = 0;
921 ctr->ctr0 = NULL;
922 status = WERR_UNKNOWN_LEVEL;
923 break;
926 return status;
929 /*******************************************************************
930 fill in a conn info level 0 structure.
931 ********************************************************************/
933 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
935 uint32 num_entries = 0;
936 (*stot) = 1;
938 if (ss0 == NULL) {
939 if (snum != NULL)
940 (*snum) = 0;
941 return;
944 DEBUG(5,("init_srv_conn_0_ss0\n"));
946 if (snum) {
947 ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
948 for (; (*snum) < (*stot); (*snum)++) {
950 ss0->array[num_entries].conn_id = (*stot);
952 /* move on to creating next connection */
953 /* move on to creating next conn */
954 num_entries++;
957 ss0->count = num_entries;
959 if ((*snum) >= (*stot)) {
960 (*snum) = 0;
963 } else {
964 ss0->array = NULL;
965 ss0->count = 0;
967 (*stot) = 0;
971 /*******************************************************************
972 fill in a conn info level 1 structure.
973 ********************************************************************/
975 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
977 uint32 num_entries = 0;
978 (*stot) = 1;
980 if (ss1 == NULL) {
981 if (snum != NULL)
982 (*snum) = 0;
983 return;
986 DEBUG(5,("init_srv_conn_1_ss1\n"));
988 if (snum) {
989 ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
990 for (; (*snum) < (*stot); (*snum)++) {
991 ss1->array[num_entries].conn_id = (*stot);
992 ss1->array[num_entries].conn_type = 0x3;
993 ss1->array[num_entries].num_open = 1;
994 ss1->array[num_entries].num_users = 1;
995 ss1->array[num_entries].conn_time = 3;
996 ss1->array[num_entries].user = "dummy_user";
997 ss1->array[num_entries].share = "IPC$";
999 /* move on to creating next connection */
1000 /* move on to creating next conn */
1001 num_entries++;
1004 ss1->count = num_entries;
1006 if ((*snum) >= (*stot)) {
1007 (*snum) = 0;
1010 } else {
1011 ss1->count = 0;
1012 ss1->array = NULL;
1014 (*stot) = 0;
1018 /*******************************************************************
1019 makes a SRV_R_NET_CONN_ENUM structure.
1020 ********************************************************************/
1022 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1023 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1025 WERROR status = WERR_OK;
1026 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1028 switch (switch_value) {
1029 case 0:
1030 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1031 break;
1032 case 1:
1033 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1034 break;
1035 default:
1036 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1037 ctr->ctr0 = NULL;
1038 (*resume_hnd) = 0;
1039 (*total_entries) = 0;
1040 status = WERR_UNKNOWN_LEVEL;
1041 break;
1044 return status;
1047 /*******************************************************************
1048 makes a SRV_R_NET_FILE_ENUM structure.
1049 ********************************************************************/
1051 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1053 TALLOC_CTX *ctx = get_talloc_ctx();
1054 WERROR status;
1056 /* TODO -- Windows enumerates
1057 (b) active pipes
1058 (c) open directories and files */
1060 ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3);
1062 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1063 if ( !W_ERROR_IS_OK(status))
1064 return status;
1066 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1067 if ( !W_ERROR_IS_OK(status))
1068 return status;
1070 ctr->ctr3->count = *num_entries;
1072 return WERR_OK;
1075 /*******************************************************************
1076 *******************************************************************/
1078 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1080 switch ( *r->in.level ) {
1081 case 3:
1082 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, r->out.totalentries );
1083 default:
1084 return WERR_UNKNOWN_LEVEL;
1087 return WERR_OK;
1090 /*******************************************************************
1091 net server get info
1092 ********************************************************************/
1094 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1096 WERROR status = WERR_OK;
1098 ZERO_STRUCTP(r->out.info);
1100 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1102 if (!pipe_access_check(p)) {
1103 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1104 return WERR_ACCESS_DENIED;
1107 switch (r->in.level) {
1109 /* Technically level 102 should only be available to
1110 Administrators but there isn't anything super-secret
1111 here, as most of it is made up. */
1113 case 102:
1114 r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1116 r->out.info->info102->platform_id = 500;
1117 r->out.info->info102->version_major = lp_major_announce_version();
1118 r->out.info->info102->version_minor = lp_minor_announce_version();
1119 r->out.info->info102->server_name = global_myname();
1120 r->out.info->info102->server_type = lp_default_server_announce();
1121 r->out.info->info102->userpath = "C:\\";
1122 r->out.info->info102->licenses = 10000;
1123 r->out.info->info102->anndelta = 3000;
1124 r->out.info->info102->disc = 0xf;
1125 r->out.info->info102->users = 0xffffffff;
1126 r->out.info->info102->hidden = 0;
1127 r->out.info->info102->announce = 240;
1128 r->out.info->info102->comment = lp_serverstring();
1129 break;
1130 case 101:
1131 r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1132 r->out.info->info101->platform_id = 500;
1133 r->out.info->info101->server_name = global_myname();
1134 r->out.info->info101->version_major = lp_major_announce_version();
1135 r->out.info->info101->version_minor = lp_minor_announce_version();
1136 r->out.info->info101->server_type = lp_default_server_announce();
1137 r->out.info->info101->comment = lp_serverstring();
1138 break;
1139 case 100:
1140 r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1141 r->out.info->info100->platform_id = 500;
1142 r->out.info->info100->server_name = global_myname();
1143 break;
1144 default:
1145 return WERR_UNKNOWN_LEVEL;
1146 break;
1149 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1151 return status;
1154 /*******************************************************************
1155 net server set info
1156 ********************************************************************/
1158 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1160 /* Set up the net server set info structure. */
1161 if (r->out.parm_error) {
1162 *r->out.parm_error = 0;
1164 return WERR_OK;
1167 /*******************************************************************
1168 net conn enum
1169 ********************************************************************/
1171 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1173 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1175 ZERO_STRUCTP(r->out.ctr);
1177 /* set up the */
1178 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1181 /*******************************************************************
1182 net sess enum
1183 ********************************************************************/
1185 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1187 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1189 ZERO_STRUCTP(r->out.ctr);
1191 /* set up the */
1192 return init_srv_sess_info_ctr(p, r->out.ctr,
1193 *r->in.level,
1194 r->in.resume_handle,
1195 r->out.totalentries);
1198 /*******************************************************************
1199 net sess del
1200 ********************************************************************/
1202 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1204 struct sessionid *session_list;
1205 int num_sessions, snum;
1206 WERROR status;
1208 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1210 /* strip leading backslashes if any */
1211 while (machine[0] == '\\') {
1212 memmove(machine, &machine[1], strlen(machine));
1215 num_sessions = list_sessions(p->mem_ctx, &session_list);
1217 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1219 status = WERR_ACCESS_DENIED;
1221 /* fail out now if you are not root or not a domain admin */
1223 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1224 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1226 goto done;
1229 for (snum = 0; snum < num_sessions; snum++) {
1231 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1232 strequal(session_list[snum].remote_machine, machine)) {
1233 NTSTATUS ntstat;
1235 ntstat = messaging_send(smbd_messaging_context(),
1236 session_list[snum].pid,
1237 MSG_SHUTDOWN, &data_blob_null);
1239 if (NT_STATUS_IS_OK(ntstat))
1240 status = WERR_OK;
1244 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1246 done:
1247 return status;
1250 /*******************************************************************
1251 Net share enum all.
1252 ********************************************************************/
1254 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1256 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1258 if (!pipe_access_check(p)) {
1259 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1260 return WERR_ACCESS_DENIED;
1263 /* Create the list of shares for the response. */
1264 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1265 r->in.resume_handle, r->out.totalentries, True);
1268 /*******************************************************************
1269 Net share enum.
1270 ********************************************************************/
1272 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *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\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, False);
1286 /*******************************************************************
1287 Net share get info.
1288 ********************************************************************/
1290 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1292 const struct share_params *params;
1294 params = get_share_params(p->mem_ctx, r->in.share_name);
1296 if (params != NULL) {
1297 switch (r->in.level) {
1298 case 0:
1299 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1300 init_srv_share_info_0(p, r->out.info->info0, params);
1301 break;
1302 case 1:
1303 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1304 init_srv_share_info_1(p, r->out.info->info1, params);
1305 break;
1306 case 2:
1307 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1308 init_srv_share_info_2(p, r->out.info->info2, params);
1309 break;
1310 case 501:
1311 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1312 init_srv_share_info_501(p, r->out.info->info501, params);
1313 break;
1314 case 502:
1315 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1316 init_srv_share_info_502(p, r->out.info->info502, params);
1317 break;
1319 /* here for completeness */
1320 case 1004:
1321 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1322 init_srv_share_info_1004(p, r->out.info->info1004, params);
1323 break;
1324 case 1005:
1325 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1326 init_srv_share_info_1005(p, r->out.info->info1005, params);
1327 break;
1329 /* here for completeness 1006 - 1501 */
1330 case 1006:
1331 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1332 init_srv_share_info_1006(p, r->out.info->info1006,
1333 params);
1334 break;
1335 case 1007:
1336 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1337 init_srv_share_info_1007(p, r->out.info->info1007,
1338 params);
1339 break;
1340 case 1501:
1341 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1342 init_srv_share_info_1501(p, r->out.info->info1501,
1343 params);
1344 break;
1345 default:
1346 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1347 "switch value %d\n", r->in.level));
1348 return WERR_UNKNOWN_LEVEL;
1349 break;
1351 } else {
1352 return WERR_INVALID_NAME;
1355 return WERR_OK;
1358 /*******************************************************************
1359 Check a given DOS pathname is valid for a share.
1360 ********************************************************************/
1362 char *valid_share_pathname(char *dos_pathname)
1364 char *ptr;
1366 /* Convert any '\' paths to '/' */
1367 unix_format(dos_pathname);
1368 unix_clean_name(dos_pathname);
1370 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1371 ptr = dos_pathname;
1372 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1373 ptr += 2;
1375 /* Only absolute paths allowed. */
1376 if (*ptr != '/')
1377 return NULL;
1379 return ptr;
1382 static void setval_helper(struct registry_key *key, const char *name,
1383 const char *value, WERROR *err)
1385 struct registry_value val;
1387 if (!W_ERROR_IS_OK(*err)) {
1388 return;
1391 ZERO_STRUCT(val);
1392 val.type = REG_SZ;
1393 val.v.sz.str = CONST_DISCARD(char *, value);
1394 val.v.sz.len = strlen(value)+1;
1396 *err = reg_setvalue(key, name, &val);
1399 static WERROR add_share(const char *share_name, const char *path,
1400 const char *comment, uint32 max_connections,
1401 const struct nt_user_token *token,
1402 BOOL is_disk_op)
1404 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1405 char *command;
1406 int ret;
1408 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1409 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1410 path, comment, max_connections) == -1) {
1411 return WERR_NOMEM;
1414 DEBUG(10,("add_share: Running [%s]\n", command ));
1416 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1418 if ( is_disk_op )
1419 become_root();
1421 if ( (ret = smbrun(command, NULL)) == 0 ) {
1422 /* Tell everyone we updated smb.conf. */
1423 message_send_all(smbd_messaging_context(),
1424 MSG_SMB_CONF_UPDATED,
1425 NULL, 0, NULL);
1428 if ( is_disk_op )
1429 unbecome_root();
1431 /********* END SeDiskOperatorPrivilege BLOCK *********/
1433 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1434 command, ret ));
1437 * No fallback to registry shares, the user did define a add
1438 * share command, so fail here.
1441 SAFE_FREE(command);
1442 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1445 if (lp_registry_shares()) {
1446 char *keyname;
1447 struct registry_key *key;
1448 enum winreg_CreateAction action;
1449 WERROR err;
1450 TALLOC_CTX *mem_ctx;
1452 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1453 share_name))) {
1454 return WERR_NOMEM;
1457 mem_ctx = (TALLOC_CTX *)keyname;
1459 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1460 is_disk_op ? get_root_nt_token():token,
1461 &action, &key);
1463 if (action != REG_CREATED_NEW_KEY) {
1464 err = WERR_ALREADY_EXISTS;
1467 if (!W_ERROR_IS_OK(err)) {
1468 TALLOC_FREE(mem_ctx);
1469 return err;
1472 setval_helper(key, "path", path, &err);
1473 if ((comment != NULL) && (comment[0] != '\0')) {
1474 setval_helper(key, "comment", comment, &err);
1476 if (max_connections != 0) {
1477 char tmp[16];
1478 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1479 setval_helper(key, "max connections", tmp, &err);
1482 if (!W_ERROR_IS_OK(err)) {
1484 * Hmmmm. We'd need transactions on the registry to
1485 * get this right....
1487 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1488 keyname);
1490 TALLOC_FREE(mem_ctx);
1491 return err;
1494 return WERR_ACCESS_DENIED;
1497 static WERROR delete_share(const char *sharename,
1498 const struct nt_user_token *token,
1499 BOOL is_disk_op)
1501 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1502 char *command;
1503 int ret;
1505 if (asprintf(&command, "%s \"%s\" \"%s\"",
1506 lp_delete_share_cmd(), dyn_CONFIGFILE,
1507 sharename)) {
1508 return WERR_NOMEM;
1511 DEBUG(10,("delete_share: Running [%s]\n", command ));
1513 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1515 if ( is_disk_op )
1516 become_root();
1518 if ( (ret = smbrun(command, NULL)) == 0 ) {
1519 /* Tell everyone we updated smb.conf. */
1520 message_send_all(smbd_messaging_context(),
1521 MSG_SMB_CONF_UPDATED,
1522 NULL, 0, NULL);
1525 if ( is_disk_op )
1526 unbecome_root();
1528 /********* END SeDiskOperatorPrivilege BLOCK *********/
1530 SAFE_FREE(command);
1532 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1533 command, ret ));
1534 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1537 if (lp_registry_shares()) {
1538 char *keyname;
1539 WERROR err;
1541 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1542 sharename) == -1) {
1543 return WERR_NOMEM;
1546 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1547 keyname);
1548 SAFE_FREE(keyname);
1549 return err;
1552 return WERR_ACCESS_DENIED;
1555 static WERROR change_share(const char *share_name, const char *path,
1556 const char *comment, uint32 max_connections,
1557 const struct nt_user_token *token,
1558 BOOL is_disk_op)
1560 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1561 char *command;
1562 int ret;
1564 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1565 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1566 path, comment, max_connections) == -1) {
1567 return WERR_NOMEM;
1570 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1572 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1574 if ( is_disk_op )
1575 become_root();
1577 if ( (ret = smbrun(command, NULL)) == 0 ) {
1578 /* Tell everyone we updated smb.conf. */
1579 message_send_all(smbd_messaging_context(),
1580 MSG_SMB_CONF_UPDATED,
1581 NULL, 0, NULL);
1584 if ( is_disk_op )
1585 unbecome_root();
1587 /********* END SeDiskOperatorPrivilege BLOCK *********/
1589 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1590 "(%d)\n", command, ret ));
1592 SAFE_FREE(command);
1594 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1597 if (lp_registry_shares()) {
1598 char *keyname;
1599 struct registry_key *key;
1600 WERROR err;
1601 TALLOC_CTX *mem_ctx;
1603 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1604 share_name))) {
1605 return WERR_NOMEM;
1608 mem_ctx = (TALLOC_CTX *)keyname;
1610 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1611 is_disk_op ? get_root_nt_token():token,
1612 &key);
1613 if (!W_ERROR_IS_OK(err)) {
1614 TALLOC_FREE(mem_ctx);
1615 return err;
1618 setval_helper(key, "path", path, &err);
1620 reg_deletevalue(key, "comment");
1621 if ((comment != NULL) && (comment[0] != '\0')) {
1622 setval_helper(key, "comment", comment, &err);
1625 reg_deletevalue(key, "max connections");
1626 if (max_connections != 0) {
1627 char tmp[16];
1628 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1629 setval_helper(key, "max connections", tmp, &err);
1632 TALLOC_FREE(mem_ctx);
1633 return err;
1636 return WERR_ACCESS_DENIED;
1639 /*******************************************************************
1640 Net share set info. Modify share details.
1641 ********************************************************************/
1643 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1645 pstring comment;
1646 pstring pathname;
1647 int type;
1648 int snum;
1649 char *path;
1650 SEC_DESC *psd = NULL;
1651 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1652 BOOL is_disk_op = False;
1653 int max_connections = 0;
1654 fstring tmp_share_name;
1656 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1658 if (r->out.parm_error) {
1659 *r->out.parm_error = 0;
1662 if ( strequal(r->in.share_name,"IPC$")
1663 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1664 || strequal(r->in.share_name,"global") )
1666 return WERR_ACCESS_DENIED;
1669 fstrcpy(tmp_share_name, r->in.share_name);
1670 snum = find_service(tmp_share_name);
1672 /* Does this share exist ? */
1673 if (snum < 0)
1674 return WERR_NET_NAME_NOT_FOUND;
1676 /* No change to printer shares. */
1677 if (lp_print_ok(snum))
1678 return WERR_ACCESS_DENIED;
1680 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1681 &se_diskop );
1683 /* fail out now if you are not root and not a disk op */
1685 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1686 return WERR_ACCESS_DENIED;
1688 switch (r->in.level) {
1689 case 1:
1690 pstrcpy(pathname, lp_pathname(snum));
1691 pstrcpy(comment, r->in.info.info1->comment);
1692 type = r->in.info.info1->type;
1693 psd = NULL;
1694 break;
1695 case 2:
1696 pstrcpy(comment, r->in.info.info2->comment);
1697 pstrcpy(pathname, r->in.info.info2->path);
1698 type = r->in.info.info2->type;
1699 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1700 0 : r->in.info.info2->max_users;
1701 psd = NULL;
1702 break;
1703 case 502:
1704 pstrcpy(comment, r->in.info.info502->comment);
1705 pstrcpy(pathname, r->in.info.info502->path);
1706 type = r->in.info.info502->type;
1707 psd = r->in.info.info502->sd;
1708 map_generic_share_sd_bits(psd);
1709 break;
1710 case 1004:
1711 pstrcpy(pathname, lp_pathname(snum));
1712 pstrcpy(comment, r->in.info.info1004->comment);
1713 type = STYPE_DISKTREE;
1714 break;
1715 case 1005:
1716 /* XP re-sets the csc policy even if it wasn't changed by the
1717 user, so we must compare it to see if it's what is set in
1718 smb.conf, so that we can contine other ops like setting
1719 ACLs on a share */
1720 if (((r->in.info.info1005->dfs_flags &
1721 SHARE_1005_CSC_POLICY_MASK) >>
1722 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1723 return WERR_OK;
1724 else {
1725 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1726 "to change csc policy from the network; "
1727 "must be done with smb.conf\n"));
1728 return WERR_ACCESS_DENIED;
1730 case 1006:
1731 case 1007:
1732 return WERR_ACCESS_DENIED;
1733 case 1501:
1734 pstrcpy(pathname, lp_pathname(snum));
1735 pstrcpy(comment, lp_comment(snum));
1736 psd = r->in.info.info1501->sd;
1737 map_generic_share_sd_bits(psd);
1738 type = STYPE_DISKTREE;
1739 break;
1740 default:
1741 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1742 "%d\n", r->in.level));
1743 return WERR_UNKNOWN_LEVEL;
1746 /* We can only modify disk shares. */
1747 if (type != STYPE_DISKTREE)
1748 return WERR_ACCESS_DENIED;
1750 /* Check if the pathname is valid. */
1751 if (!(path = valid_share_pathname( pathname )))
1752 return WERR_OBJECT_PATH_INVALID;
1754 /* Ensure share name, pathname and comment don't contain '"'
1755 * characters. */
1756 string_replace(tmp_share_name, '"', ' ');
1757 string_replace(path, '"', ' ');
1758 string_replace(comment, '"', ' ');
1760 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1761 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1763 /* Only call modify function if something changed. */
1765 if (strcmp(path, lp_pathname(snum))
1766 || strcmp(comment, lp_comment(snum))
1767 || (lp_max_connections(snum) != max_connections) ) {
1768 WERROR err;
1770 err = change_share(tmp_share_name, path, comment,
1771 max_connections, p->pipe_user.nt_user_token,
1772 is_disk_op);
1774 if (!W_ERROR_IS_OK(err)) {
1775 return err;
1779 /* Replace SD if changed. */
1780 if (psd) {
1781 SEC_DESC *old_sd;
1782 size_t sd_size;
1784 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1785 &sd_size);
1787 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1788 if (!set_share_security(r->in.share_name, psd)) {
1789 DEBUG(0,("_srv_net_share_set_info: Failed to "
1790 "change security info in share %s.\n",
1791 r->in.share_name ));
1796 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1798 return WERR_OK;
1802 /*******************************************************************
1803 Net share add. Call 'add_share_command "sharename" "pathname"
1804 "comment" "max connections = "
1805 ********************************************************************/
1807 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1809 pstring share_name;
1810 pstring comment;
1811 pstring pathname;
1812 char *path;
1813 int type;
1814 SEC_DESC *psd = NULL;
1815 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1816 BOOL is_disk_op;
1817 uint32 max_connections = 0;
1818 WERROR err;
1820 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1822 if (r->out.parm_error) {
1823 *r->out.parm_error = 0;
1826 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1827 &se_diskop );
1829 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1830 return WERR_ACCESS_DENIED;
1832 switch (r->in.level) {
1833 case 0:
1834 /* No path. Not enough info in a level 0 to do anything. */
1835 return WERR_ACCESS_DENIED;
1836 case 1:
1837 /* Not enough info in a level 1 to do anything. */
1838 return WERR_ACCESS_DENIED;
1839 case 2:
1840 pstrcpy(share_name, r->in.info.info2->name);
1841 pstrcpy(comment, r->in.info.info2->comment);
1842 pstrcpy(pathname, r->in.info.info2->path);
1843 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1844 0 : r->in.info.info2->max_users;
1845 type = r->in.info.info2->type;
1846 break;
1847 case 501:
1848 /* No path. Not enough info in a level 501 to do anything. */
1849 return WERR_ACCESS_DENIED;
1850 case 502:
1851 pstrcpy(share_name, r->in.info.info502->name);
1852 pstrcpy(comment, r->in.info.info502->comment);
1853 pstrcpy(pathname, r->in.info.info502->path);
1854 type = r->in.info.info502->type;
1855 psd = r->in.info.info502->sd;
1856 map_generic_share_sd_bits(psd);
1857 break;
1859 /* none of the following contain share names. NetShareAdd
1860 * does not have a separate parameter for the share name */
1862 case 1004:
1863 case 1005:
1864 case 1006:
1865 case 1007:
1866 return WERR_ACCESS_DENIED;
1867 case 1501:
1868 /* DFS only level. */
1869 return WERR_ACCESS_DENIED;
1870 default:
1871 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1872 r->in.level));
1873 return WERR_UNKNOWN_LEVEL;
1876 /* check for invalid share names */
1878 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1879 sizeof(share_name) ) ) {
1880 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1881 share_name));
1882 return WERR_INVALID_NAME;
1885 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1886 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1888 return WERR_ACCESS_DENIED;
1891 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1892 /* Share already exists. */
1893 return WERR_ALREADY_EXISTS;
1896 /* We can only add disk shares. */
1897 if (type != STYPE_DISKTREE)
1898 return WERR_ACCESS_DENIED;
1900 /* Check if the pathname is valid. */
1901 if (!(path = valid_share_pathname( pathname )))
1902 return WERR_OBJECT_PATH_INVALID;
1904 /* Ensure share name, pathname and comment don't contain '"'
1905 * characters. */
1907 string_replace(share_name, '"', ' ');
1908 string_replace(path, '"', ' ');
1909 string_replace(comment, '"', ' ');
1911 err = add_share(share_name, path, comment, max_connections,
1912 p->pipe_user.nt_user_token, is_disk_op);
1914 if (!W_ERROR_IS_OK(err)) {
1915 return err;
1918 if (psd) {
1919 if (!set_share_security(share_name, psd)) {
1920 DEBUG(0,("_srv_net_share_add: Failed to add security "
1921 "info to share %s.\n", share_name ));
1926 * We don't call reload_services() here, the message will
1927 * cause this to be done before the next packet is read
1928 * from the client. JRA.
1931 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1933 return WERR_OK;
1936 /*******************************************************************
1937 Net share delete. Call "delete share command" with the share name as
1938 a parameter.
1939 ********************************************************************/
1941 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1943 struct share_params *params;
1944 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1945 BOOL is_disk_op;
1946 WERROR err;
1948 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1950 if ( strequal(r->in.share_name, "IPC$")
1951 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1952 || strequal(r->in.share_name, "global") )
1954 return WERR_ACCESS_DENIED;
1957 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1958 return WERR_NO_SUCH_SHARE;
1961 /* No change to printer shares. */
1962 if (lp_print_ok(params->service))
1963 return WERR_ACCESS_DENIED;
1965 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1966 &se_diskop );
1968 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1969 return WERR_ACCESS_DENIED;
1971 err = delete_share(lp_servicename(params->service),
1972 p->pipe_user.nt_user_token, is_disk_op);
1974 if (!W_ERROR_IS_OK(err)) {
1975 return err;
1978 /* Delete the SD in the database. */
1979 delete_share_security(params);
1981 lp_killservice(params->service);
1983 return WERR_OK;
1986 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
1988 struct srvsvc_NetShareDel s;
1990 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1992 s.in.server_unc = r->in.server_unc;
1993 s.in.share_name = r->in.share_name;
1994 s.in.reserved = r->in.reserved;
1996 return _srvsvc_NetShareDel(p, &s);
1999 /*******************************************************************
2000 time of day
2001 ********************************************************************/
2003 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
2005 struct tm *t;
2006 time_t unixdate = time(NULL);
2007 WERROR status = WERR_OK;
2009 /* We do this call first as if we do it *after* the gmtime call
2010 it overwrites the pointed-to values. JRA */
2012 uint32 zone = get_time_zone(unixdate)/60;
2014 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2016 t = gmtime(&unixdate);
2018 /* set up the */
2019 r->out.info->elapsed = unixdate;
2020 r->out.info->msecs = 0;
2021 r->out.info->hours = t->tm_hour;
2022 r->out.info->mins = t->tm_min;
2023 r->out.info->secs = t->tm_sec;
2024 r->out.info->hunds = 0;
2025 r->out.info->timezone = zone;
2026 r->out.info->tinterval = 10000;
2027 r->out.info->day = t->tm_mday;
2028 r->out.info->month = t->tm_mon + 1;
2029 r->out.info->year = 1900+t->tm_year;
2030 r->out.info->weekday = t->tm_wday;
2032 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2034 return status;
2037 /***********************************************************************************
2038 Win9x NT tools get security descriptor.
2039 ***********************************************************************************/
2041 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2043 SEC_DESC *psd = NULL;
2044 size_t sd_size;
2045 DATA_BLOB null_pw;
2046 files_struct *fsp = NULL;
2047 SMB_STRUCT_STAT st;
2048 NTSTATUS nt_status;
2049 connection_struct *conn = NULL;
2050 BOOL became_user = False;
2051 WERROR status = WERR_OK;
2052 pstring tmp_file;
2054 ZERO_STRUCT(st);
2057 /* Null password is ok - we are already an authenticated user... */
2058 null_pw = data_blob_null;
2060 become_root();
2061 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2062 unbecome_root();
2064 if (conn == NULL) {
2065 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2066 status = ntstatus_to_werror(nt_status);
2067 goto error_exit;
2070 if (!become_user(conn, conn->vuid)) {
2071 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2072 status = WERR_ACCESS_DENIED;
2073 goto error_exit;
2075 became_user = True;
2077 pstrcpy(tmp_file, r->in.file);
2078 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2079 if (!NT_STATUS_IS_OK(nt_status)) {
2080 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2081 status = WERR_ACCESS_DENIED;
2082 goto error_exit;
2085 nt_status = check_name(conn, r->in.file);
2086 if (!NT_STATUS_IS_OK(nt_status)) {
2087 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", r->in.file));
2088 status = WERR_ACCESS_DENIED;
2089 goto error_exit;
2092 nt_status = open_file_stat(conn, NULL, r->in.file, &st, &fsp);
2093 if (!NT_STATUS_IS_OK(nt_status)) {
2094 /* Perhaps it is a directory */
2095 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2096 nt_status = open_directory(conn, NULL, r->in.file, &st,
2097 READ_CONTROL_ACCESS,
2098 FILE_SHARE_READ|FILE_SHARE_WRITE,
2099 FILE_OPEN,
2101 FILE_ATTRIBUTE_DIRECTORY,
2102 NULL, &fsp);
2104 if (!NT_STATUS_IS_OK(nt_status)) {
2105 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", r->in.file));
2106 status = WERR_ACCESS_DENIED;
2107 goto error_exit;
2111 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2113 if (sd_size == 0) {
2114 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", r->in.file));
2115 status = WERR_ACCESS_DENIED;
2116 goto error_exit;
2119 r->out.sd_buf->sd_size= sd_size;
2120 r->out.sd_buf->sd = psd;
2122 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2124 close_file(fsp, NORMAL_CLOSE);
2125 unbecome_user();
2126 close_cnum(conn, p->pipe_user.vuid);
2127 return status;
2129 error_exit:
2131 if(fsp) {
2132 close_file(fsp, NORMAL_CLOSE);
2135 if (became_user)
2136 unbecome_user();
2138 if (conn)
2139 close_cnum(conn, p->pipe_user.vuid);
2141 return status;
2144 /***********************************************************************************
2145 Win9x NT tools set security descriptor.
2146 ***********************************************************************************/
2148 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2150 DATA_BLOB null_pw;
2151 files_struct *fsp = NULL;
2152 SMB_STRUCT_STAT st;
2153 NTSTATUS nt_status;
2154 connection_struct *conn = NULL;
2155 BOOL became_user = False;
2156 WERROR status = WERR_OK;
2157 pstring tmp_file;
2159 ZERO_STRUCT(st);
2161 /* Null password is ok - we are already an authenticated user... */
2162 null_pw = data_blob_null;
2164 become_root();
2165 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2166 unbecome_root();
2168 if (conn == NULL) {
2169 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2170 status = ntstatus_to_werror(nt_status);
2171 goto error_exit;
2174 if (!become_user(conn, conn->vuid)) {
2175 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2176 status = WERR_ACCESS_DENIED;
2177 goto error_exit;
2179 became_user = True;
2181 pstrcpy(tmp_file, r->in.file);
2182 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2183 if (!NT_STATUS_IS_OK(nt_status)) {
2184 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2185 status = WERR_ACCESS_DENIED;
2186 goto error_exit;
2189 nt_status = check_name(conn, r->in.file);
2190 if (!NT_STATUS_IS_OK(nt_status)) {
2191 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", r->in.file));
2192 status = WERR_ACCESS_DENIED;
2193 goto error_exit;
2197 nt_status = open_file_stat(conn, NULL, r->in.file, &st, &fsp);
2199 if (!NT_STATUS_IS_OK(nt_status)) {
2200 /* Perhaps it is a directory */
2201 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2202 nt_status = open_directory(conn, NULL, r->in.file, &st,
2203 FILE_READ_ATTRIBUTES,
2204 FILE_SHARE_READ|FILE_SHARE_WRITE,
2205 FILE_OPEN,
2207 FILE_ATTRIBUTE_DIRECTORY,
2208 NULL, &fsp);
2210 if (!NT_STATUS_IS_OK(nt_status)) {
2211 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", r->in.file));
2212 status = WERR_ACCESS_DENIED;
2213 goto error_exit;
2217 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2219 if (!NT_STATUS_IS_OK(nt_status)) {
2220 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
2221 status = WERR_ACCESS_DENIED;
2222 goto error_exit;
2225 close_file(fsp, NORMAL_CLOSE);
2226 unbecome_user();
2227 close_cnum(conn, p->pipe_user.vuid);
2228 return status;
2230 error_exit:
2232 if(fsp) {
2233 close_file(fsp, NORMAL_CLOSE);
2236 if (became_user) {
2237 unbecome_user();
2240 if (conn) {
2241 close_cnum(conn, p->pipe_user.vuid);
2244 return status;
2247 /***********************************************************************************
2248 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2249 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2250 These disks would the disks listed by this function.
2251 Users could then create shares relative to these disks. Watch out for moving these disks around.
2252 "Nigel Williams" <nigel@veritas.com>.
2253 ***********************************************************************************/
2255 static const char *server_disks[] = {"C:"};
2257 static uint32 get_server_disk_count(void)
2259 return sizeof(server_disks)/sizeof(server_disks[0]);
2262 static uint32 init_server_disk_enum(uint32 *resume)
2264 uint32 server_disk_count = get_server_disk_count();
2266 /*resume can be an offset into the list for now*/
2268 if(*resume & 0x80000000)
2269 *resume = 0;
2271 if(*resume > server_disk_count)
2272 *resume = server_disk_count;
2274 return server_disk_count - *resume;
2277 static const char *next_server_disk_enum(uint32 *resume)
2279 const char *disk;
2281 if(init_server_disk_enum(resume) == 0)
2282 return NULL;
2284 disk = server_disks[*resume];
2286 (*resume)++;
2288 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2290 return disk;
2293 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2295 uint32 i;
2296 const char *disk_name;
2298 WERROR status = WERR_OK;
2300 *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2301 r->out.info->count = 0;
2303 if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2304 return WERR_NOMEM;
2307 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2309 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2311 r->out.info->count++;
2312 (*r->out.totalentries)++;
2314 /*copy disk name into a unicode string*/
2316 r->out.info->disks[i].disk = disk_name;
2319 /* add a terminating null string. Is this there if there is more data to come? */
2321 r->out.info->count++;
2322 (*r->out.totalentries)++;
2324 r->out.info->disks[i].disk = "";
2326 return status;
2329 /********************************************************************
2330 ********************************************************************/
2332 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2334 int len;
2336 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2337 return WERR_INVALID_PARAM;
2340 switch ( r->in.name_type ) {
2341 case 0x9:
2342 len = strlen_m(r->in.name);
2344 if ((r->in.flags == 0x0) && (len > 81)) {
2345 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2346 return WERR_INVALID_NAME;
2348 if ((r->in.flags == 0x80000000) && (len > 13)) {
2349 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2350 return WERR_INVALID_NAME;
2353 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2354 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2355 return WERR_INVALID_NAME;
2357 break;
2359 default:
2360 return WERR_UNKNOWN_LEVEL;
2363 return WERR_OK;
2367 /********************************************************************
2368 ********************************************************************/
2370 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2372 return WERR_ACCESS_DENIED;
2375 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2377 p->rng_fault_state = True;
2378 return WERR_NOT_SUPPORTED;
2381 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2383 p->rng_fault_state = True;
2384 return WERR_NOT_SUPPORTED;
2387 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2389 p->rng_fault_state = True;
2390 return WERR_NOT_SUPPORTED;
2393 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2395 p->rng_fault_state = True;
2396 return WERR_NOT_SUPPORTED;
2399 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2401 p->rng_fault_state = True;
2402 return WERR_NOT_SUPPORTED;
2405 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2407 p->rng_fault_state = True;
2408 return WERR_NOT_SUPPORTED;
2411 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2413 p->rng_fault_state = True;
2414 return WERR_NOT_SUPPORTED;
2417 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2419 p->rng_fault_state = True;
2420 return WERR_NOT_SUPPORTED;
2423 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2425 p->rng_fault_state = True;
2426 return WERR_NOT_SUPPORTED;
2429 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2431 p->rng_fault_state = True;
2432 return WERR_NOT_SUPPORTED;
2435 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2437 p->rng_fault_state = True;
2438 return WERR_NOT_SUPPORTED;
2441 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2443 p->rng_fault_state = True;
2444 return WERR_NOT_SUPPORTED;
2447 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2449 p->rng_fault_state = True;
2450 return WERR_NOT_SUPPORTED;
2453 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2455 p->rng_fault_state = True;
2456 return WERR_NOT_SUPPORTED;
2459 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2461 p->rng_fault_state = True;
2462 return WERR_NOT_SUPPORTED;
2465 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2467 p->rng_fault_state = True;
2468 return WERR_NOT_SUPPORTED;
2471 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2473 p->rng_fault_state = True;
2474 return WERR_NOT_SUPPORTED;
2477 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2479 p->rng_fault_state = True;
2480 return WERR_NOT_SUPPORTED;
2483 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2485 p->rng_fault_state = True;
2486 return WERR_NOT_SUPPORTED;
2489 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2491 p->rng_fault_state = True;
2492 return WERR_NOT_SUPPORTED;
2495 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2497 p->rng_fault_state = True;
2498 return WERR_NOT_SUPPORTED;
2501 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2503 p->rng_fault_state = True;
2504 return WERR_NOT_SUPPORTED;
2507 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2509 p->rng_fault_state = True;
2510 return WERR_NOT_SUPPORTED;
2513 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2515 p->rng_fault_state = True;
2516 return WERR_NOT_SUPPORTED;
2519 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2521 p->rng_fault_state = True;
2522 return WERR_NOT_SUPPORTED;
2525 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2527 p->rng_fault_state = True;
2528 return WERR_NOT_SUPPORTED;
2531 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2533 p->rng_fault_state = True;
2534 return WERR_NOT_SUPPORTED;
2537 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2539 p->rng_fault_state = True;
2540 return WERR_NOT_SUPPORTED;
2543 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2545 p->rng_fault_state = True;
2546 return WERR_NOT_SUPPORTED;
2549 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2551 p->rng_fault_state = True;
2552 return WERR_NOT_SUPPORTED;
2555 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2557 p->rng_fault_state = True;
2558 return WERR_NOT_SUPPORTED;
2561 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2563 p->rng_fault_state = True;
2564 return WERR_NOT_SUPPORTED;
2567 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2569 p->rng_fault_state = True;
2570 return WERR_NOT_SUPPORTED;
2573 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2575 p->rng_fault_state = True;
2576 return WERR_NOT_SUPPORTED;
2579 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2581 p->rng_fault_state = True;
2582 return WERR_NOT_SUPPORTED;