s4-netlogon: implement dcesrv_netr_DsRAddressToSitenamesExW
[Samba/aatanasov.git] / source3 / rpc_server / srv_srvsvc_nt.c
blobf7f51d1e9a9cd195669b4549663fa8fb482c6105
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Guenther Deschner 2008.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 /* This is the implementation of the srvsvc pipe. */
26 #include "includes.h"
28 extern const struct generic_mapping file_generic_mapping;
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_SRV
33 #define MAX_SERVER_DISK_ENTRIES 15
35 /* Use for enumerating connections, pipes, & files */
37 struct file_enum_count {
38 TALLOC_CTX *ctx;
39 const char *username;
40 struct srvsvc_NetFileCtr3 *ctr3;
43 struct sess_file_count {
44 struct server_id pid;
45 uid_t uid;
46 int count;
49 /****************************************************************************
50 Count the entries belonging to a service in the connection db.
51 ****************************************************************************/
53 static int pipe_enum_fn( struct db_record *rec, void *p)
55 struct pipe_open_rec prec;
56 struct file_enum_count *fenum = (struct file_enum_count *)p;
57 struct srvsvc_NetFileInfo3 *f;
58 int i = fenum->ctr3->count;
59 char *fullpath = NULL;
60 const char *username;
62 if (rec->value.dsize != sizeof(struct pipe_open_rec))
63 return 0;
65 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
67 if ( !process_exists(prec.pid) ) {
68 return 0;
71 username = uidtoname(prec.uid);
73 if ((fenum->username != NULL)
74 && !strequal(username, fenum->username)) {
75 return 0;
78 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
79 if (!fullpath) {
80 return 1;
83 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
84 struct srvsvc_NetFileInfo3, i+1);
85 if ( !f ) {
86 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
87 return 1;
89 fenum->ctr3->array = f;
91 fenum->ctr3->array[i].fid =
92 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum);
93 fenum->ctr3->array[i].permissions =
94 (FILE_READ_DATA|FILE_WRITE_DATA);
95 fenum->ctr3->array[i].num_locks = 0;
96 fenum->ctr3->array[i].path = fullpath;
97 fenum->ctr3->array[i].user = username;
99 fenum->ctr3->count++;
101 return 0;
104 /*******************************************************************
105 ********************************************************************/
107 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
108 const char *username,
109 struct srvsvc_NetFileCtr3 **ctr3,
110 uint32_t resume )
112 struct file_enum_count fenum;
114 fenum.ctx = ctx;
115 fenum.username = username;
116 fenum.ctr3 = *ctr3;
118 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
119 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
120 "failed\n"));
121 return WERR_NOMEM;
124 *ctr3 = fenum.ctr3;
126 return WERR_OK;
129 /*******************************************************************
130 ********************************************************************/
132 static void enum_file_fn( const struct share_mode_entry *e,
133 const char *sharepath, const char *fname,
134 void *private_data )
136 struct file_enum_count *fenum =
137 (struct file_enum_count *)private_data;
139 struct srvsvc_NetFileInfo3 *f;
140 int i = fenum->ctr3->count;
141 files_struct fsp;
142 struct byte_range_lock *brl;
143 int num_locks = 0;
144 char *fullpath = NULL;
145 uint32 permissions;
146 const char *username;
148 /* If the pid was not found delete the entry from connections.tdb */
150 if ( !process_exists(e->pid) ) {
151 return;
154 username = uidtoname(e->uid);
156 if ((fenum->username != NULL)
157 && !strequal(username, fenum->username)) {
158 return;
161 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
162 struct srvsvc_NetFileInfo3, i+1);
163 if ( !f ) {
164 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
165 return;
167 fenum->ctr3->array = f;
169 /* need to count the number of locks on a file */
171 ZERO_STRUCT( fsp );
172 fsp.file_id = e->id;
174 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
175 num_locks = brl->num_locks;
176 TALLOC_FREE(brl);
179 if ( strcmp( fname, "." ) == 0 ) {
180 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
181 } else {
182 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
183 sharepath, fname );
185 if (!fullpath) {
186 return;
188 string_replace( fullpath, '/', '\\' );
190 /* mask out create (what ever that is) */
191 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
193 /* now fill in the srvsvc_NetFileInfo3 struct */
195 fenum->ctr3->array[i].fid =
196 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
197 fenum->ctr3->array[i].permissions = permissions;
198 fenum->ctr3->array[i].num_locks = num_locks;
199 fenum->ctr3->array[i].path = fullpath;
200 fenum->ctr3->array[i].user = username;
202 fenum->ctr3->count++;
205 /*******************************************************************
206 ********************************************************************/
208 static WERROR net_enum_files(TALLOC_CTX *ctx,
209 const char *username,
210 struct srvsvc_NetFileCtr3 **ctr3,
211 uint32_t resume)
213 struct file_enum_count f_enum_cnt;
215 f_enum_cnt.ctx = ctx;
216 f_enum_cnt.username = username;
217 f_enum_cnt.ctr3 = *ctr3;
219 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
221 *ctr3 = f_enum_cnt.ctr3;
223 return WERR_OK;
226 /*******************************************************************
227 Utility function to get the 'type' of a share from an snum.
228 ********************************************************************/
229 static uint32 get_share_type(int snum)
231 /* work out the share type */
232 uint32 type = STYPE_DISKTREE;
234 if (lp_print_ok(snum))
235 type = STYPE_PRINTQ;
236 if (strequal(lp_fstype(snum), "IPC"))
237 type = STYPE_IPC;
238 if (lp_administrative_share(snum))
239 type |= STYPE_HIDDEN;
241 return type;
244 /*******************************************************************
245 Fill in a share info level 0 structure.
246 ********************************************************************/
248 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
250 r->name = lp_servicename(snum);
253 /*******************************************************************
254 Fill in a share info level 1 structure.
255 ********************************************************************/
257 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
259 char *net_name = lp_servicename(snum);
260 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
262 if (remark) {
263 remark = talloc_sub_advanced(
264 p->mem_ctx, lp_servicename(snum),
265 get_current_username(), lp_pathname(snum),
266 p->server_info->utok.uid, get_current_username(),
267 "", remark);
270 r->name = net_name;
271 r->type = get_share_type(snum);
272 r->comment = remark ? remark : "";
275 /*******************************************************************
276 Fill in a share info level 2 structure.
277 ********************************************************************/
279 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
281 char *remark = NULL;
282 char *path = NULL;
283 int max_connections = lp_max_connections(snum);
284 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
285 char *net_name = lp_servicename(snum);
287 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
288 if (remark) {
289 remark = talloc_sub_advanced(
290 p->mem_ctx, lp_servicename(snum),
291 get_current_username(), lp_pathname(snum),
292 p->server_info->utok.uid, get_current_username(),
293 "", remark);
295 path = talloc_asprintf(p->mem_ctx,
296 "C:%s", lp_pathname(snum));
298 if (path) {
300 * Change / to \\ so that win2k will see it as a valid path.
301 * This was added to enable use of browsing in win2k add
302 * share dialog.
305 string_replace(path, '/', '\\');
308 r->name = net_name;
309 r->type = get_share_type(snum);
310 r->comment = remark ? remark : "";
311 r->permissions = 0;
312 r->max_users = max_uses;
313 r->current_users = count_current_connections(net_name, false);
314 r->path = path ? path : "";
315 r->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 *r, int snum)
349 const char *net_name = lp_servicename(snum);
350 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
352 if (remark) {
353 remark = talloc_sub_advanced(
354 p->mem_ctx, lp_servicename(snum),
355 get_current_username(), lp_pathname(snum),
356 p->server_info->utok.uid, get_current_username(),
357 "", remark);
360 r->name = net_name;
361 r->type = get_share_type(snum);
362 r->comment = remark ? remark : "";
363 r->csc_policy = (lp_csc_policy(snum) << 4);
366 /*******************************************************************
367 Fill in a share info level 502 structure.
368 ********************************************************************/
370 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
372 const char *net_name = lp_servicename(snum);
373 char *path = NULL;
374 SEC_DESC *sd = NULL;
375 struct sec_desc_buf *sd_buf = NULL;
376 size_t sd_size = 0;
377 TALLOC_CTX *ctx = p->mem_ctx;
378 char *remark = talloc_strdup(ctx, lp_comment(snum));;
380 if (remark) {
381 remark = talloc_sub_advanced(
382 p->mem_ctx, lp_servicename(snum),
383 get_current_username(), lp_pathname(snum),
384 p->server_info->utok.uid, get_current_username(),
385 "", remark);
387 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
388 if (path) {
390 * Change / to \\ so that win2k will see it as a valid path. This was added to
391 * enable use of browsing in win2k add share dialog.
393 string_replace(path, '/', '\\');
396 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
398 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
400 r->name = net_name;
401 r->type = get_share_type(snum);
402 r->comment = remark ? remark : "";
403 r->permissions = 0;
404 r->max_users = (uint32_t)-1;
405 r->current_users = 1; /* ??? */
406 r->path = path ? path : "";
407 r->password = "";
408 r->sd_buf = *sd_buf;
411 /***************************************************************************
412 Fill in a share info level 1004 structure.
413 ***************************************************************************/
415 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
417 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
419 if (remark) {
420 remark = talloc_sub_advanced(
421 p->mem_ctx, lp_servicename(snum),
422 get_current_username(), lp_pathname(snum),
423 p->server_info->utok.uid, get_current_username(),
424 "", remark);
427 r->comment = remark ? remark : "";
430 /***************************************************************************
431 Fill in a share info level 1005 structure.
432 ***************************************************************************/
434 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
436 uint32_t dfs_flags = 0;
438 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
439 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
442 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
444 r->dfs_flags = dfs_flags;
447 /***************************************************************************
448 Fill in a share info level 1006 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
453 r->max_users = (uint32_t)-1;
456 /***************************************************************************
457 Fill in a share info level 1007 structure.
458 ***************************************************************************/
460 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
462 r->flags = 0;
463 r->alternate_directory_name = "";
466 /*******************************************************************
467 Fill in a share info level 1501 structure.
468 ********************************************************************/
470 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
472 SEC_DESC *sd;
473 size_t sd_size;
474 TALLOC_CTX *ctx = p->mem_ctx;
476 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
478 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
481 /*******************************************************************
482 True if it ends in '$'.
483 ********************************************************************/
485 static bool is_hidden_share(int snum)
487 const char *net_name = lp_servicename(snum);
489 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
492 /*******************************************************************
493 Verify user is allowed to view share, access based enumeration
494 ********************************************************************/
495 static bool is_enumeration_allowed(pipes_struct *p,
496 int snum)
498 if (!lp_access_based_share_enum(snum))
499 return true;
501 return share_access_check(p->server_info->ptok, lp_servicename(snum),
502 FILE_READ_DATA);
505 /*******************************************************************
506 Fill in a share info structure.
507 ********************************************************************/
509 static WERROR init_srv_share_info_ctr(pipes_struct *p,
510 struct srvsvc_NetShareInfoCtr *info_ctr,
511 uint32_t *resume_handle_p,
512 uint32_t *total_entries,
513 bool all_shares)
515 int num_entries = 0;
516 int alloc_entries = 0;
517 int num_services = 0;
518 int snum;
519 TALLOC_CTX *ctx = p->mem_ctx;
520 int i = 0;
521 int valid_share_count = 0;
522 bool *allowed = 0;
523 union srvsvc_NetShareCtr ctr;
524 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
526 DEBUG(5,("init_srv_share_info_ctr\n"));
528 /* Ensure all the usershares are loaded. */
529 become_root();
530 load_usershare_shares();
531 load_registry_shares();
532 num_services = lp_numservices();
533 unbecome_root();
535 allowed = TALLOC_ZERO_ARRAY(ctx, bool, num_services);
536 W_ERROR_HAVE_NO_MEMORY(allowed);
538 /* Count the number of entries. */
539 for (snum = 0; snum < num_services; snum++) {
540 if (lp_browseable(snum) && lp_snum_ok(snum) &&
541 is_enumeration_allowed(p, snum) &&
542 (all_shares || !is_hidden_share(snum)) ) {
543 DEBUG(10, ("counting service %s\n",
544 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
545 allowed[snum] = true;
546 num_entries++;
547 } else {
548 DEBUG(10, ("NOT counting service %s\n",
549 lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
553 if (!num_entries || (resume_handle >= num_entries)) {
554 return WERR_OK;
557 /* Calculate alloc entries. */
558 alloc_entries = num_entries - resume_handle;
559 switch (info_ctr->level) {
560 case 0:
561 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
562 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
564 ctr.ctr0->count = alloc_entries;
565 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
566 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
568 for (snum = 0; snum < num_services; snum++) {
569 if (allowed[snum] &&
570 (resume_handle <= (i + valid_share_count++)) ) {
571 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
575 break;
577 case 1:
578 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
579 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
581 ctr.ctr1->count = alloc_entries;
582 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
583 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
585 for (snum = 0; snum < num_services; snum++) {
586 if (allowed[snum] &&
587 (resume_handle <= (i + valid_share_count++)) ) {
588 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
592 break;
594 case 2:
595 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
596 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
598 ctr.ctr2->count = alloc_entries;
599 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
600 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
602 for (snum = 0; snum < num_services; snum++) {
603 if (allowed[snum] &&
604 (resume_handle <= (i + valid_share_count++)) ) {
605 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
609 break;
611 case 501:
612 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
613 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
615 ctr.ctr501->count = alloc_entries;
616 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
617 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
619 for (snum = 0; snum < num_services; snum++) {
620 if (allowed[snum] &&
621 (resume_handle <= (i + valid_share_count++)) ) {
622 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
626 break;
628 case 502:
629 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
630 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
632 ctr.ctr502->count = alloc_entries;
633 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
634 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
636 for (snum = 0; snum < num_services; snum++) {
637 if (allowed[snum] &&
638 (resume_handle <= (i + valid_share_count++)) ) {
639 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
643 break;
645 case 1004:
646 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
647 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
649 ctr.ctr1004->count = alloc_entries;
650 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
651 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
653 for (snum = 0; snum < num_services; snum++) {
654 if (allowed[snum] &&
655 (resume_handle <= (i + valid_share_count++)) ) {
656 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
660 break;
662 case 1005:
663 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
664 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
666 ctr.ctr1005->count = alloc_entries;
667 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
668 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
670 for (snum = 0; snum < num_services; snum++) {
671 if (allowed[snum] &&
672 (resume_handle <= (i + valid_share_count++)) ) {
673 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
677 break;
679 case 1006:
680 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
681 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
683 ctr.ctr1006->count = alloc_entries;
684 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
685 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
687 for (snum = 0; snum < num_services; snum++) {
688 if (allowed[snum] &&
689 (resume_handle <= (i + valid_share_count++)) ) {
690 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
694 break;
696 case 1007:
697 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
698 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
700 ctr.ctr1007->count = alloc_entries;
701 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
702 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
704 for (snum = 0; snum < num_services; snum++) {
705 if (allowed[snum] &&
706 (resume_handle <= (i + valid_share_count++)) ) {
707 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
711 break;
713 case 1501:
714 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
715 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
717 ctr.ctr1501->count = alloc_entries;
718 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
719 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
721 for (snum = 0; snum < num_services; snum++) {
722 if (allowed[snum] &&
723 (resume_handle <= (i + valid_share_count++)) ) {
724 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
728 break;
730 default:
731 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
732 info_ctr->level));
733 return WERR_UNKNOWN_LEVEL;
736 *total_entries = alloc_entries;
737 if (resume_handle_p) {
738 if (all_shares) {
739 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
740 } else {
741 *resume_handle_p = num_entries;
745 info_ctr->ctr = ctr;
747 return WERR_OK;
750 /*******************************************************************
751 fill in a sess info level 0 structure.
752 ********************************************************************/
754 static WERROR init_srv_sess_info_0(pipes_struct *p,
755 struct srvsvc_NetSessCtr0 *ctr0,
756 uint32_t *resume_handle_p,
757 uint32_t *total_entries)
759 struct sessionid *session_list;
760 uint32_t num_entries = 0;
761 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
762 *total_entries = list_sessions(p->mem_ctx, &session_list);
764 DEBUG(5,("init_srv_sess_info_0\n"));
766 if (ctr0 == NULL) {
767 if (resume_handle_p) {
768 *resume_handle_p = 0;
770 return WERR_OK;
773 for (; resume_handle < *total_entries; resume_handle++) {
775 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
776 ctr0->array,
777 struct srvsvc_NetSessInfo0,
778 num_entries+1);
779 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
781 ctr0->array[num_entries].client =
782 session_list[resume_handle].remote_machine;
784 num_entries++;
787 ctr0->count = num_entries;
789 if (resume_handle_p) {
790 if (*resume_handle_p >= *total_entries) {
791 *resume_handle_p = 0;
792 } else {
793 *resume_handle_p = resume_handle;
797 return WERR_OK;
800 /*******************************************************************
801 ********************************************************************/
803 static void sess_file_fn( const struct share_mode_entry *e,
804 const char *sharepath, const char *fname,
805 void *data )
807 struct sess_file_count *sess = (struct sess_file_count *)data;
809 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
810 sess->count++;
813 return;
816 /*******************************************************************
817 ********************************************************************/
819 static int net_count_files( uid_t uid, struct server_id pid )
821 struct sess_file_count s_file_cnt;
823 s_file_cnt.count = 0;
824 s_file_cnt.uid = uid;
825 s_file_cnt.pid = pid;
827 share_mode_forall( sess_file_fn, &s_file_cnt );
829 return s_file_cnt.count;
832 /*******************************************************************
833 fill in a sess info level 1 structure.
834 ********************************************************************/
836 static WERROR init_srv_sess_info_1(pipes_struct *p,
837 struct srvsvc_NetSessCtr1 *ctr1,
838 uint32_t *resume_handle_p,
839 uint32_t *total_entries)
841 struct sessionid *session_list;
842 uint32_t num_entries = 0;
843 time_t now = time(NULL);
844 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
846 ZERO_STRUCTP(ctr1);
848 if (ctr1 == NULL) {
849 if (resume_handle_p) {
850 *resume_handle_p = 0;
852 return WERR_OK;
855 *total_entries = list_sessions(p->mem_ctx, &session_list);
857 for (; resume_handle < *total_entries; resume_handle++) {
858 uint32 num_files;
859 uint32 connect_time;
860 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
861 bool guest;
863 if ( !pw ) {
864 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
865 session_list[resume_handle].username));
866 continue;
869 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
870 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
871 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
873 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
874 ctr1->array,
875 struct srvsvc_NetSessInfo1,
876 num_entries+1);
877 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
879 ctr1->array[num_entries].client = session_list[resume_handle].remote_machine;
880 ctr1->array[num_entries].user = session_list[resume_handle].username;
881 ctr1->array[num_entries].num_open = num_files;
882 ctr1->array[num_entries].time = connect_time;
883 ctr1->array[num_entries].idle_time = 0;
884 ctr1->array[num_entries].user_flags = guest;
886 num_entries++;
889 ctr1->count = num_entries;
891 if (resume_handle_p) {
892 if (*resume_handle_p >= *total_entries) {
893 *resume_handle_p = 0;
894 } else {
895 *resume_handle_p = resume_handle;
899 return WERR_OK;
902 /*******************************************************************
903 fill in a conn info level 0 structure.
904 ********************************************************************/
906 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
907 uint32_t *resume_handle_p,
908 uint32_t *total_entries)
910 uint32_t num_entries = 0;
911 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
913 DEBUG(5,("init_srv_conn_info_0\n"));
915 if (ctr0 == NULL) {
916 if (resume_handle_p) {
917 *resume_handle_p = 0;
919 return WERR_OK;
922 *total_entries = 1;
924 ZERO_STRUCTP(ctr0);
926 for (; resume_handle < *total_entries; resume_handle++) {
928 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
929 ctr0->array,
930 struct srvsvc_NetConnInfo0,
931 num_entries+1);
932 if (!ctr0->array) {
933 return WERR_NOMEM;
936 ctr0->array[num_entries].conn_id = *total_entries;
938 /* move on to creating next connection */
939 num_entries++;
942 ctr0->count = num_entries;
943 *total_entries = num_entries;
945 if (resume_handle_p) {
946 if (*resume_handle_p >= *total_entries) {
947 *resume_handle_p = 0;
948 } else {
949 *resume_handle_p = resume_handle;
953 return WERR_OK;
956 /*******************************************************************
957 fill in a conn info level 1 structure.
958 ********************************************************************/
960 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
961 uint32_t *resume_handle_p,
962 uint32_t *total_entries)
964 uint32_t num_entries = 0;
965 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
967 DEBUG(5,("init_srv_conn_info_1\n"));
969 if (ctr1 == NULL) {
970 if (resume_handle_p) {
971 *resume_handle_p = 0;
973 return WERR_OK;
976 *total_entries = 1;
978 ZERO_STRUCTP(ctr1);
980 for (; resume_handle < *total_entries; resume_handle++) {
982 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
983 ctr1->array,
984 struct srvsvc_NetConnInfo1,
985 num_entries+1);
986 if (!ctr1->array) {
987 return WERR_NOMEM;
990 ctr1->array[num_entries].conn_id = *total_entries;
991 ctr1->array[num_entries].conn_type = 0x3;
992 ctr1->array[num_entries].num_open = 1;
993 ctr1->array[num_entries].num_users = 1;
994 ctr1->array[num_entries].conn_time = 3;
995 ctr1->array[num_entries].user = "dummy_user";
996 ctr1->array[num_entries].share = "IPC$";
998 /* move on to creating next connection */
999 num_entries++;
1002 ctr1->count = num_entries;
1003 *total_entries = num_entries;
1005 if (resume_handle_p) {
1006 if (*resume_handle_p >= *total_entries) {
1007 *resume_handle_p = 0;
1008 } else {
1009 *resume_handle_p = resume_handle;
1013 return WERR_OK;
1016 /*******************************************************************
1017 _srvsvc_NetFileEnum
1018 *******************************************************************/
1020 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
1021 struct srvsvc_NetFileEnum *r)
1023 TALLOC_CTX *ctx = NULL;
1024 struct srvsvc_NetFileCtr3 *ctr3;
1025 uint32_t resume_hnd = 0;
1026 WERROR werr;
1028 switch (r->in.info_ctr->level) {
1029 case 3:
1030 break;
1031 default:
1032 return WERR_UNKNOWN_LEVEL;
1035 ctx = talloc_tos();
1036 ctr3 = r->in.info_ctr->ctr.ctr3;
1037 if (!ctr3) {
1038 werr = WERR_INVALID_PARAM;
1039 goto done;
1042 /* TODO -- Windows enumerates
1043 (b) active pipes
1044 (c) open directories and files */
1046 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1047 if (!W_ERROR_IS_OK(werr)) {
1048 goto done;
1051 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1052 if (!W_ERROR_IS_OK(werr)) {
1053 goto done;
1056 *r->out.totalentries = ctr3->count;
1057 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1058 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1060 werr = WERR_OK;
1062 done:
1063 return werr;
1066 /*******************************************************************
1067 _srvsvc_NetSrvGetInfo
1068 ********************************************************************/
1070 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1071 struct srvsvc_NetSrvGetInfo *r)
1073 WERROR status = WERR_OK;
1075 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1077 if (!pipe_access_check(p)) {
1078 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1079 return WERR_ACCESS_DENIED;
1082 switch (r->in.level) {
1084 /* Technically level 102 should only be available to
1085 Administrators but there isn't anything super-secret
1086 here, as most of it is made up. */
1088 case 102: {
1089 struct srvsvc_NetSrvInfo102 *info102;
1091 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1092 if (!info102) {
1093 return WERR_NOMEM;
1096 info102->platform_id = PLATFORM_ID_NT;
1097 info102->server_name = global_myname();
1098 info102->version_major = lp_major_announce_version();
1099 info102->version_minor = lp_minor_announce_version();
1100 info102->server_type = lp_default_server_announce();
1101 info102->comment = string_truncate(lp_serverstring(),
1102 MAX_SERVER_STRING_LENGTH);
1103 info102->users = 0xffffffff;
1104 info102->disc = 0xf;
1105 info102->hidden = 0;
1106 info102->announce = 240;
1107 info102->anndelta = 3000;
1108 info102->licenses = 100000;
1109 info102->userpath = "C:\\";
1111 r->out.info->info102 = info102;
1112 break;
1114 case 101: {
1115 struct srvsvc_NetSrvInfo101 *info101;
1117 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1118 if (!info101) {
1119 return WERR_NOMEM;
1122 info101->platform_id = PLATFORM_ID_NT;
1123 info101->server_name = global_myname();
1124 info101->version_major = lp_major_announce_version();
1125 info101->version_minor = lp_minor_announce_version();
1126 info101->server_type = lp_default_server_announce();
1127 info101->comment = string_truncate(lp_serverstring(),
1128 MAX_SERVER_STRING_LENGTH);
1130 r->out.info->info101 = info101;
1131 break;
1133 case 100: {
1134 struct srvsvc_NetSrvInfo100 *info100;
1136 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1137 if (!info100) {
1138 return WERR_NOMEM;
1141 info100->platform_id = PLATFORM_ID_NT;
1142 info100->server_name = global_myname();
1144 r->out.info->info100 = info100;
1146 break;
1148 default:
1149 status = WERR_UNKNOWN_LEVEL;
1150 break;
1153 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1155 return status;
1158 /*******************************************************************
1159 _srvsvc_NetSrvSetInfo
1160 ********************************************************************/
1162 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1163 struct srvsvc_NetSrvSetInfo *r)
1165 WERROR status = WERR_OK;
1167 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1169 /* Set up the net server set info structure. */
1171 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1173 return status;
1176 /*******************************************************************
1177 _srvsvc_NetConnEnum
1178 ********************************************************************/
1180 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1181 struct srvsvc_NetConnEnum *r)
1183 WERROR werr;
1185 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1187 switch (r->in.info_ctr->level) {
1188 case 0:
1189 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1190 r->in.resume_handle,
1191 r->out.totalentries);
1192 break;
1193 case 1:
1194 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1195 r->in.resume_handle,
1196 r->out.totalentries);
1197 break;
1198 default:
1199 return WERR_UNKNOWN_LEVEL;
1202 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1204 return werr;
1207 /*******************************************************************
1208 _srvsvc_NetSessEnum
1209 ********************************************************************/
1211 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1212 struct srvsvc_NetSessEnum *r)
1214 WERROR werr;
1216 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1218 switch (r->in.info_ctr->level) {
1219 case 0:
1220 werr = init_srv_sess_info_0(p,
1221 r->in.info_ctr->ctr.ctr0,
1222 r->in.resume_handle,
1223 r->out.totalentries);
1224 break;
1225 case 1:
1226 werr = init_srv_sess_info_1(p,
1227 r->in.info_ctr->ctr.ctr1,
1228 r->in.resume_handle,
1229 r->out.totalentries);
1230 break;
1231 default:
1232 return WERR_UNKNOWN_LEVEL;
1235 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1237 return werr;
1240 /*******************************************************************
1241 _srvsvc_NetSessDel
1242 ********************************************************************/
1244 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1245 struct srvsvc_NetSessDel *r)
1247 struct sessionid *session_list;
1248 int num_sessions, snum;
1249 const char *username;
1250 const char *machine;
1251 bool not_root = False;
1252 WERROR werr;
1254 username = r->in.user;
1255 machine = r->in.client;
1257 /* strip leading backslashes if any */
1258 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1259 machine += 2;
1262 num_sessions = list_sessions(p->mem_ctx, &session_list);
1264 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1266 werr = WERR_ACCESS_DENIED;
1268 /* fail out now if you are not root or not a domain admin */
1270 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1271 ( ! nt_token_check_domain_rid(p->server_info->ptok,
1272 DOMAIN_GROUP_RID_ADMINS))) {
1274 goto done;
1277 for (snum = 0; snum < num_sessions; snum++) {
1279 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1280 strequal(session_list[snum].remote_machine, machine)) {
1282 NTSTATUS ntstat;
1284 if (p->server_info->utok.uid != sec_initial_uid()) {
1285 not_root = True;
1286 become_root();
1289 ntstat = messaging_send(smbd_messaging_context(),
1290 session_list[snum].pid,
1291 MSG_SHUTDOWN, &data_blob_null);
1293 if (NT_STATUS_IS_OK(ntstat))
1294 werr = WERR_OK;
1296 if (not_root)
1297 unbecome_root();
1301 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1303 done:
1305 return werr;
1308 /*******************************************************************
1309 _srvsvc_NetShareEnumAll
1310 ********************************************************************/
1312 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1313 struct srvsvc_NetShareEnumAll *r)
1315 WERROR werr;
1317 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1319 if (!pipe_access_check(p)) {
1320 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1321 return WERR_ACCESS_DENIED;
1324 /* Create the list of shares for the response. */
1325 werr = init_srv_share_info_ctr(p,
1326 r->in.info_ctr,
1327 r->in.resume_handle,
1328 r->out.totalentries,
1329 true);
1331 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1333 return werr;
1336 /*******************************************************************
1337 _srvsvc_NetShareEnum
1338 ********************************************************************/
1340 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1341 struct srvsvc_NetShareEnum *r)
1343 WERROR werr;
1345 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1347 if (!pipe_access_check(p)) {
1348 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1349 return WERR_ACCESS_DENIED;
1352 /* Create the list of shares for the response. */
1353 werr = init_srv_share_info_ctr(p,
1354 r->in.info_ctr,
1355 r->in.resume_handle,
1356 r->out.totalentries,
1357 false);
1359 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1361 return werr;
1364 /*******************************************************************
1365 _srvsvc_NetShareGetInfo
1366 ********************************************************************/
1368 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1369 struct srvsvc_NetShareGetInfo *r)
1371 WERROR status = WERR_OK;
1372 fstring share_name;
1373 int snum;
1374 union srvsvc_NetShareInfo *info = r->out.info;
1376 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1378 fstrcpy(share_name, r->in.share_name);
1380 snum = find_service(share_name);
1381 if (snum < 0) {
1382 return WERR_INVALID_NAME;
1385 switch (r->in.level) {
1386 case 0:
1387 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1388 W_ERROR_HAVE_NO_MEMORY(info->info0);
1389 init_srv_share_info_0(p, info->info0, snum);
1390 break;
1391 case 1:
1392 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1393 W_ERROR_HAVE_NO_MEMORY(info->info1);
1394 init_srv_share_info_1(p, info->info1, snum);
1395 break;
1396 case 2:
1397 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1398 W_ERROR_HAVE_NO_MEMORY(info->info2);
1399 init_srv_share_info_2(p, info->info2, snum);
1400 break;
1401 case 501:
1402 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1403 W_ERROR_HAVE_NO_MEMORY(info->info501);
1404 init_srv_share_info_501(p, info->info501, snum);
1405 break;
1406 case 502:
1407 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1408 W_ERROR_HAVE_NO_MEMORY(info->info502);
1409 init_srv_share_info_502(p, info->info502, snum);
1410 break;
1411 case 1004:
1412 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1413 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1414 init_srv_share_info_1004(p, info->info1004, snum);
1415 break;
1416 case 1005:
1417 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1418 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1419 init_srv_share_info_1005(p, info->info1005, snum);
1420 break;
1421 case 1006:
1422 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1423 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1424 init_srv_share_info_1006(p, info->info1006, snum);
1425 break;
1426 case 1007:
1427 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1428 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1429 init_srv_share_info_1007(p, info->info1007, snum);
1430 break;
1431 case 1501:
1432 init_srv_share_info_1501(p, info->info1501, snum);
1433 break;
1434 default:
1435 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1436 r->in.level));
1437 status = WERR_UNKNOWN_LEVEL;
1438 break;
1441 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1443 return status;
1446 /*******************************************************************
1447 Check a given DOS pathname is valid for a share.
1448 ********************************************************************/
1450 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1452 char *ptr = NULL;
1454 if (!dos_pathname) {
1455 return NULL;
1458 ptr = talloc_strdup(ctx, dos_pathname);
1459 if (!ptr) {
1460 return NULL;
1462 /* Convert any '\' paths to '/' */
1463 unix_format(ptr);
1464 ptr = unix_clean_name(ctx, ptr);
1465 if (!ptr) {
1466 return NULL;
1469 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1470 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1471 ptr += 2;
1473 /* Only absolute paths allowed. */
1474 if (*ptr != '/')
1475 return NULL;
1477 return ptr;
1480 /*******************************************************************
1481 _srvsvc_NetShareSetInfo. Modify share details.
1482 ********************************************************************/
1484 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1485 struct srvsvc_NetShareSetInfo *r)
1487 char *command = NULL;
1488 char *share_name = NULL;
1489 char *comment = NULL;
1490 const char *pathname = NULL;
1491 int type;
1492 int snum;
1493 int ret;
1494 char *path = NULL;
1495 SEC_DESC *psd = NULL;
1496 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1497 bool is_disk_op = False;
1498 int max_connections = 0;
1499 TALLOC_CTX *ctx = p->mem_ctx;
1500 union srvsvc_NetShareInfo *info = r->in.info;
1502 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1504 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1505 if (!share_name) {
1506 return WERR_NOMEM;
1509 if (r->out.parm_error) {
1510 *r->out.parm_error = 0;
1513 if ( strequal(share_name,"IPC$")
1514 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1515 || strequal(share_name,"global") )
1517 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
1518 "modified by a remote user.\n",
1519 share_name ));
1520 return WERR_ACCESS_DENIED;
1523 snum = find_service(share_name);
1525 /* Does this share exist ? */
1526 if (snum < 0)
1527 return WERR_NET_NAME_NOT_FOUND;
1529 /* No change to printer shares. */
1530 if (lp_print_ok(snum))
1531 return WERR_ACCESS_DENIED;
1533 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1535 /* fail out now if you are not root and not a disk op */
1537 if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op ) {
1538 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
1539 "SeDiskOperatorPrivilege privilege needed to modify "
1540 "share %s\n",
1541 (unsigned int)p->server_info->utok.uid,
1542 share_name ));
1543 return WERR_ACCESS_DENIED;
1546 switch (r->in.level) {
1547 case 1:
1548 pathname = talloc_strdup(ctx, lp_pathname(snum));
1549 comment = talloc_strdup(ctx, info->info1->comment);
1550 type = info->info1->type;
1551 psd = NULL;
1552 break;
1553 case 2:
1554 comment = talloc_strdup(ctx, info->info2->comment);
1555 pathname = info->info2->path;
1556 type = info->info2->type;
1557 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1558 0 : info->info2->max_users;
1559 psd = NULL;
1560 break;
1561 #if 0
1562 /* not supported on set but here for completeness */
1563 case 501:
1564 comment = talloc_strdup(ctx, info->info501->comment);
1565 type = info->info501->type;
1566 psd = NULL;
1567 break;
1568 #endif
1569 case 502:
1570 comment = talloc_strdup(ctx, info->info502->comment);
1571 pathname = info->info502->path;
1572 type = info->info502->type;
1573 psd = info->info502->sd_buf.sd;
1574 map_generic_share_sd_bits(psd);
1575 break;
1576 case 1004:
1577 pathname = talloc_strdup(ctx, lp_pathname(snum));
1578 comment = talloc_strdup(ctx, info->info1004->comment);
1579 type = STYPE_DISKTREE;
1580 break;
1581 case 1005:
1582 /* XP re-sets the csc policy even if it wasn't changed by the
1583 user, so we must compare it to see if it's what is set in
1584 smb.conf, so that we can contine other ops like setting
1585 ACLs on a share */
1586 if (((info->info1005->dfs_flags &
1587 SHARE_1005_CSC_POLICY_MASK) >>
1588 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1589 return WERR_OK;
1590 else {
1591 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1592 return WERR_ACCESS_DENIED;
1594 case 1006:
1595 case 1007:
1596 return WERR_ACCESS_DENIED;
1597 case 1501:
1598 pathname = talloc_strdup(ctx, lp_pathname(snum));
1599 comment = talloc_strdup(ctx, lp_comment(snum));
1600 psd = info->info1501->sd;
1601 map_generic_share_sd_bits(psd);
1602 type = STYPE_DISKTREE;
1603 break;
1604 default:
1605 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1606 r->in.level));
1607 return WERR_UNKNOWN_LEVEL;
1610 /* We can only modify disk shares. */
1611 if (type != STYPE_DISKTREE) {
1612 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
1613 "disk share\n",
1614 share_name ));
1615 return WERR_ACCESS_DENIED;
1618 if (comment == NULL) {
1619 return WERR_NOMEM;
1622 /* Check if the pathname is valid. */
1623 if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
1624 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
1625 pathname ));
1626 return WERR_OBJECT_PATH_INVALID;
1629 /* Ensure share name, pathname and comment don't contain '"' characters. */
1630 string_replace(share_name, '"', ' ');
1631 string_replace(path, '"', ' ');
1632 string_replace(comment, '"', ' ');
1634 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1635 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1637 /* Only call modify function if something changed. */
1639 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1640 || (lp_max_connections(snum) != max_connections)) {
1641 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1642 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1643 return WERR_ACCESS_DENIED;
1646 command = talloc_asprintf(p->mem_ctx,
1647 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1648 lp_change_share_cmd(),
1649 get_dyn_CONFIGFILE(),
1650 share_name,
1651 path,
1652 comment ? comment : "",
1653 max_connections);
1654 if (!command) {
1655 return WERR_NOMEM;
1658 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1660 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1662 if (is_disk_op)
1663 become_root();
1665 if ( (ret = smbrun(command, NULL)) == 0 ) {
1666 /* Tell everyone we updated smb.conf. */
1667 message_send_all(smbd_messaging_context(),
1668 MSG_SMB_CONF_UPDATED, NULL, 0,
1669 NULL);
1672 if ( is_disk_op )
1673 unbecome_root();
1675 /********* END SeDiskOperatorPrivilege BLOCK *********/
1677 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1678 command, ret ));
1680 TALLOC_FREE(command);
1682 if ( ret != 0 )
1683 return WERR_ACCESS_DENIED;
1684 } else {
1685 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1686 share_name ));
1689 /* Replace SD if changed. */
1690 if (psd) {
1691 SEC_DESC *old_sd;
1692 size_t sd_size;
1694 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1696 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
1697 if (!set_share_security(share_name, psd))
1698 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1699 share_name ));
1703 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1705 return WERR_OK;
1708 /*******************************************************************
1709 _srvsvc_NetShareAdd.
1710 Call 'add_share_command "sharename" "pathname"
1711 "comment" "max connections = "
1712 ********************************************************************/
1714 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1715 struct srvsvc_NetShareAdd *r)
1717 char *command = NULL;
1718 char *share_name = NULL;
1719 char *comment = NULL;
1720 char *pathname = NULL;
1721 int type;
1722 int snum;
1723 int ret;
1724 char *path;
1725 SEC_DESC *psd = NULL;
1726 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1727 bool is_disk_op;
1728 int max_connections = 0;
1729 TALLOC_CTX *ctx = p->mem_ctx;
1731 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1733 if (r->out.parm_error) {
1734 *r->out.parm_error = 0;
1737 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1739 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1740 return WERR_ACCESS_DENIED;
1742 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1743 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1744 return WERR_ACCESS_DENIED;
1747 switch (r->in.level) {
1748 case 0:
1749 /* No path. Not enough info in a level 0 to do anything. */
1750 return WERR_ACCESS_DENIED;
1751 case 1:
1752 /* Not enough info in a level 1 to do anything. */
1753 return WERR_ACCESS_DENIED;
1754 case 2:
1755 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1756 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1757 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1758 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1759 0 : r->in.info->info2->max_users;
1760 type = r->in.info->info2->type;
1761 break;
1762 case 501:
1763 /* No path. Not enough info in a level 501 to do anything. */
1764 return WERR_ACCESS_DENIED;
1765 case 502:
1766 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1767 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1768 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1769 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1770 0 : r->in.info->info502->max_users;
1771 type = r->in.info->info502->type;
1772 psd = r->in.info->info502->sd_buf.sd;
1773 map_generic_share_sd_bits(psd);
1774 break;
1776 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1778 case 1004:
1779 case 1005:
1780 case 1006:
1781 case 1007:
1782 return WERR_ACCESS_DENIED;
1783 case 1501:
1784 /* DFS only level. */
1785 return WERR_ACCESS_DENIED;
1786 default:
1787 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1788 r->in.level));
1789 return WERR_UNKNOWN_LEVEL;
1792 /* check for invalid share names */
1794 if (!share_name || !validate_net_name(share_name,
1795 INVALID_SHARENAME_CHARS,
1796 strlen(share_name))) {
1797 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1798 share_name ? share_name : ""));
1799 return WERR_INVALID_NAME;
1802 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1803 || (lp_enable_asu_support() &&
1804 strequal(share_name,"ADMIN$"))) {
1805 return WERR_ACCESS_DENIED;
1808 snum = find_service(share_name);
1810 /* Share already exists. */
1811 if (snum >= 0) {
1812 return WERR_FILE_EXISTS;
1815 /* We can only add disk shares. */
1816 if (type != STYPE_DISKTREE) {
1817 return WERR_ACCESS_DENIED;
1820 /* Check if the pathname is valid. */
1821 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1822 return WERR_OBJECT_PATH_INVALID;
1825 /* Ensure share name, pathname and comment don't contain '"' characters. */
1826 string_replace(share_name, '"', ' ');
1827 string_replace(path, '"', ' ');
1828 if (comment) {
1829 string_replace(comment, '"', ' ');
1832 command = talloc_asprintf(ctx,
1833 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1834 lp_add_share_cmd(),
1835 get_dyn_CONFIGFILE(),
1836 share_name,
1837 path,
1838 comment ? comment : "",
1839 max_connections);
1840 if (!command) {
1841 return WERR_NOMEM;
1844 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1846 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1848 if ( is_disk_op )
1849 become_root();
1851 /* FIXME: use libnetconf here - gd */
1853 if ( (ret = smbrun(command, NULL)) == 0 ) {
1854 /* Tell everyone we updated smb.conf. */
1855 message_send_all(smbd_messaging_context(),
1856 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1859 if ( is_disk_op )
1860 unbecome_root();
1862 /********* END SeDiskOperatorPrivilege BLOCK *********/
1864 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1865 command, ret ));
1867 TALLOC_FREE(command);
1869 if ( ret != 0 )
1870 return WERR_ACCESS_DENIED;
1872 if (psd) {
1873 if (!set_share_security(share_name, psd)) {
1874 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1875 share_name ));
1880 * We don't call reload_services() here, the message will
1881 * cause this to be done before the next packet is read
1882 * from the client. JRA.
1885 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1887 return WERR_OK;
1890 /*******************************************************************
1891 _srvsvc_NetShareDel
1892 Call "delete share command" with the share name as
1893 a parameter.
1894 ********************************************************************/
1896 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1897 struct srvsvc_NetShareDel *r)
1899 char *command = NULL;
1900 char *share_name = NULL;
1901 int ret;
1902 int snum;
1903 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1904 bool is_disk_op;
1905 struct share_params *params;
1906 TALLOC_CTX *ctx = p->mem_ctx;
1908 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1910 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1911 if (!share_name) {
1912 return WERR_NET_NAME_NOT_FOUND;
1914 if ( strequal(share_name,"IPC$")
1915 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1916 || strequal(share_name,"global") )
1918 return WERR_ACCESS_DENIED;
1921 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1922 return WERR_NO_SUCH_SHARE;
1925 snum = find_service(share_name);
1927 /* No change to printer shares. */
1928 if (lp_print_ok(snum))
1929 return WERR_ACCESS_DENIED;
1931 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
1933 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
1934 return WERR_ACCESS_DENIED;
1936 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1937 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1938 return WERR_ACCESS_DENIED;
1941 command = talloc_asprintf(ctx,
1942 "%s \"%s\" \"%s\"",
1943 lp_delete_share_cmd(),
1944 get_dyn_CONFIGFILE(),
1945 lp_servicename(snum));
1946 if (!command) {
1947 return WERR_NOMEM;
1950 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1952 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1954 if ( is_disk_op )
1955 become_root();
1957 if ( (ret = smbrun(command, NULL)) == 0 ) {
1958 /* Tell everyone we updated smb.conf. */
1959 message_send_all(smbd_messaging_context(),
1960 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1963 if ( is_disk_op )
1964 unbecome_root();
1966 /********* END SeDiskOperatorPrivilege BLOCK *********/
1968 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1970 if ( ret != 0 )
1971 return WERR_ACCESS_DENIED;
1973 /* Delete the SD in the database. */
1974 delete_share_security(lp_servicename(params->service));
1976 lp_killservice(params->service);
1978 return WERR_OK;
1981 /*******************************************************************
1982 _srvsvc_NetShareDelSticky
1983 ********************************************************************/
1985 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1986 struct srvsvc_NetShareDelSticky *r)
1988 struct srvsvc_NetShareDel q;
1990 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1992 q.in.server_unc = r->in.server_unc;
1993 q.in.share_name = r->in.share_name;
1994 q.in.reserved = r->in.reserved;
1996 return _srvsvc_NetShareDel(p, &q);
1999 /*******************************************************************
2000 _srvsvc_NetRemoteTOD
2001 ********************************************************************/
2003 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
2004 struct srvsvc_NetRemoteTOD *r)
2006 struct srvsvc_NetRemoteTODInfo *tod;
2007 struct tm *t;
2008 time_t unixdate = time(NULL);
2010 /* We do this call first as if we do it *after* the gmtime call
2011 it overwrites the pointed-to values. JRA */
2013 uint32 zone = get_time_zone(unixdate)/60;
2015 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2017 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
2018 return WERR_NOMEM;
2020 *r->out.info = tod;
2022 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2024 t = gmtime(&unixdate);
2026 /* set up the */
2027 tod->elapsed = unixdate;
2028 tod->msecs = 0;
2029 tod->hours = t->tm_hour;
2030 tod->mins = t->tm_min;
2031 tod->secs = t->tm_sec;
2032 tod->hunds = 0;
2033 tod->timezone = zone;
2034 tod->tinterval = 10000;
2035 tod->day = t->tm_mday;
2036 tod->month = t->tm_mon + 1;
2037 tod->year = 1900+t->tm_year;
2038 tod->weekday = t->tm_wday;
2040 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2042 return WERR_OK;
2045 /***********************************************************************************
2046 _srvsvc_NetGetFileSecurity
2047 Win9x NT tools get security descriptor.
2048 ***********************************************************************************/
2050 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2051 struct srvsvc_NetGetFileSecurity *r)
2053 struct smb_filename *smb_fname = NULL;
2054 SEC_DESC *psd = NULL;
2055 size_t sd_size;
2056 fstring servicename;
2057 SMB_STRUCT_STAT st;
2058 NTSTATUS nt_status;
2059 WERROR werr;
2060 connection_struct *conn = NULL;
2061 struct sec_desc_buf *sd_buf = NULL;
2062 files_struct *fsp = NULL;
2063 int snum;
2064 char *oldcwd = NULL;
2066 ZERO_STRUCT(st);
2068 fstrcpy(servicename, r->in.share);
2070 snum = find_service(servicename);
2071 if (snum == -1) {
2072 DEBUG(10, ("Could not find service %s\n", servicename));
2073 werr = WERR_NET_NAME_NOT_FOUND;
2074 goto error_exit;
2077 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2078 lp_pathname(snum), p->server_info,
2079 &oldcwd);
2080 if (!NT_STATUS_IS_OK(nt_status)) {
2081 DEBUG(10, ("create_conn_struct failed: %s\n",
2082 nt_errstr(nt_status)));
2083 werr = ntstatus_to_werror(nt_status);
2084 goto error_exit;
2087 nt_status = filename_convert(talloc_tos(),
2088 conn,
2089 false,
2090 r->in.file,
2092 NULL,
2093 &smb_fname);
2094 if (!NT_STATUS_IS_OK(nt_status)) {
2095 werr = ntstatus_to_werror(nt_status);
2096 goto error_exit;
2099 nt_status = SMB_VFS_CREATE_FILE(
2100 conn, /* conn */
2101 NULL, /* req */
2102 0, /* root_dir_fid */
2103 smb_fname, /* fname */
2104 FILE_READ_ATTRIBUTES, /* access_mask */
2105 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2106 FILE_OPEN, /* create_disposition*/
2107 0, /* create_options */
2108 0, /* file_attributes */
2109 INTERNAL_OPEN_ONLY, /* oplock_request */
2110 0, /* allocation_size */
2111 NULL, /* sd */
2112 NULL, /* ea_list */
2113 &fsp, /* result */
2114 NULL); /* pinfo */
2116 if (!NT_STATUS_IS_OK(nt_status)) {
2117 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
2118 smb_fname_str_dbg(smb_fname)));
2119 werr = ntstatus_to_werror(nt_status);
2120 goto error_exit;
2123 nt_status = SMB_VFS_FGET_NT_ACL(fsp,
2124 (OWNER_SECURITY_INFORMATION
2125 |GROUP_SECURITY_INFORMATION
2126 |DACL_SECURITY_INFORMATION), &psd);
2128 if (!NT_STATUS_IS_OK(nt_status)) {
2129 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
2130 "for file %s\n", smb_fname_str_dbg(smb_fname)));
2131 werr = ntstatus_to_werror(nt_status);
2132 goto error_exit;
2135 sd_size = ndr_size_security_descriptor(psd, NULL, 0);
2137 sd_buf = TALLOC_ZERO_P(p->mem_ctx, struct sec_desc_buf);
2138 if (!sd_buf) {
2139 werr = WERR_NOMEM;
2140 goto error_exit;
2143 sd_buf->sd_size = sd_size;
2144 sd_buf->sd = psd;
2146 *r->out.sd_buf = sd_buf;
2148 psd->dacl->revision = NT4_ACL_REVISION;
2150 close_file(NULL, fsp, NORMAL_CLOSE);
2151 vfs_ChDir(conn, oldcwd);
2152 conn_free(conn);
2153 werr = WERR_OK;
2154 goto done;
2156 error_exit:
2158 if (fsp) {
2159 close_file(NULL, fsp, NORMAL_CLOSE);
2162 if (oldcwd) {
2163 vfs_ChDir(conn, oldcwd);
2166 if (conn) {
2167 conn_free(conn);
2170 done:
2171 TALLOC_FREE(smb_fname);
2173 return werr;
2176 /***********************************************************************************
2177 _srvsvc_NetSetFileSecurity
2178 Win9x NT tools set security descriptor.
2179 ***********************************************************************************/
2181 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2182 struct srvsvc_NetSetFileSecurity *r)
2184 struct smb_filename *smb_fname = NULL;
2185 fstring servicename;
2186 files_struct *fsp = NULL;
2187 SMB_STRUCT_STAT st;
2188 NTSTATUS nt_status;
2189 WERROR werr;
2190 connection_struct *conn = NULL;
2191 int snum;
2192 char *oldcwd = NULL;
2193 struct security_descriptor *psd = NULL;
2194 uint32_t security_info_sent = 0;
2196 ZERO_STRUCT(st);
2198 fstrcpy(servicename, r->in.share);
2200 snum = find_service(servicename);
2201 if (snum == -1) {
2202 DEBUG(10, ("Could not find service %s\n", servicename));
2203 werr = WERR_NET_NAME_NOT_FOUND;
2204 goto error_exit;
2207 nt_status = create_conn_struct(talloc_tos(), &conn, snum,
2208 lp_pathname(snum), p->server_info,
2209 &oldcwd);
2210 if (!NT_STATUS_IS_OK(nt_status)) {
2211 DEBUG(10, ("create_conn_struct failed: %s\n",
2212 nt_errstr(nt_status)));
2213 werr = ntstatus_to_werror(nt_status);
2214 goto error_exit;
2217 nt_status = filename_convert(talloc_tos(),
2218 conn,
2219 false,
2220 r->in.file,
2222 NULL,
2223 &smb_fname);
2224 if (!NT_STATUS_IS_OK(nt_status)) {
2225 werr = ntstatus_to_werror(nt_status);
2226 goto error_exit;
2229 nt_status = SMB_VFS_CREATE_FILE(
2230 conn, /* conn */
2231 NULL, /* req */
2232 0, /* root_dir_fid */
2233 smb_fname, /* fname */
2234 FILE_WRITE_ATTRIBUTES, /* access_mask */
2235 FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
2236 FILE_OPEN, /* create_disposition*/
2237 0, /* create_options */
2238 0, /* file_attributes */
2239 INTERNAL_OPEN_ONLY, /* oplock_request */
2240 0, /* allocation_size */
2241 NULL, /* sd */
2242 NULL, /* ea_list */
2243 &fsp, /* result */
2244 NULL); /* pinfo */
2246 if (!NT_STATUS_IS_OK(nt_status)) {
2247 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
2248 smb_fname_str_dbg(smb_fname)));
2249 werr = ntstatus_to_werror(nt_status);
2250 goto error_exit;
2253 psd = r->in.sd_buf->sd;
2254 security_info_sent = r->in.securityinformation;
2256 if (psd->owner_sid==0) {
2257 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
2259 if (psd->group_sid==0) {
2260 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
2262 if (psd->sacl==0) {
2263 security_info_sent &= ~SACL_SECURITY_INFORMATION;
2265 if (psd->dacl==0) {
2266 security_info_sent &= ~DACL_SECURITY_INFORMATION;
2269 /* Convert all the generic bits. */
2270 security_acl_map_generic(psd->dacl, &file_generic_mapping);
2271 security_acl_map_generic(psd->sacl, &file_generic_mapping);
2273 nt_status = SMB_VFS_FSET_NT_ACL(fsp,
2274 security_info_sent,
2275 psd);
2277 if (!NT_STATUS_IS_OK(nt_status) ) {
2278 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
2279 "on file %s\n", r->in.share));
2280 werr = WERR_ACCESS_DENIED;
2281 goto error_exit;
2284 close_file(NULL, fsp, NORMAL_CLOSE);
2285 vfs_ChDir(conn, oldcwd);
2286 conn_free(conn);
2287 werr = WERR_OK;
2288 goto done;
2290 error_exit:
2292 if (fsp) {
2293 close_file(NULL, fsp, NORMAL_CLOSE);
2296 if (oldcwd) {
2297 vfs_ChDir(conn, oldcwd);
2300 if (conn) {
2301 conn_free(conn);
2304 done:
2305 TALLOC_FREE(smb_fname);
2307 return werr;
2310 /***********************************************************************************
2311 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2312 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2313 These disks would the disks listed by this function.
2314 Users could then create shares relative to these disks. Watch out for moving these disks around.
2315 "Nigel Williams" <nigel@veritas.com>.
2316 ***********************************************************************************/
2318 static const char *server_disks[] = {"C:"};
2320 static uint32 get_server_disk_count(void)
2322 return sizeof(server_disks)/sizeof(server_disks[0]);
2325 static uint32 init_server_disk_enum(uint32 *resume)
2327 uint32 server_disk_count = get_server_disk_count();
2329 /*resume can be an offset into the list for now*/
2331 if(*resume & 0x80000000)
2332 *resume = 0;
2334 if(*resume > server_disk_count)
2335 *resume = server_disk_count;
2337 return server_disk_count - *resume;
2340 static const char *next_server_disk_enum(uint32 *resume)
2342 const char *disk;
2344 if(init_server_disk_enum(resume) == 0)
2345 return NULL;
2347 disk = server_disks[*resume];
2349 (*resume)++;
2351 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2353 return disk;
2356 /********************************************************************
2357 _srvsvc_NetDiskEnum
2358 ********************************************************************/
2360 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2361 struct srvsvc_NetDiskEnum *r)
2363 uint32 i;
2364 const char *disk_name;
2365 TALLOC_CTX *ctx = p->mem_ctx;
2366 WERROR werr;
2367 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2369 werr = WERR_OK;
2371 *r->out.totalentries = init_server_disk_enum(&resume);
2373 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2374 MAX_SERVER_DISK_ENTRIES);
2375 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2377 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2379 r->out.info->count = 0;
2381 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2383 r->out.info->count++;
2385 /*copy disk name into a unicode string*/
2387 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2388 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2391 /* add a terminating null string. Is this there if there is more data to come? */
2393 r->out.info->count++;
2395 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2396 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2398 if (r->out.resume_handle) {
2399 *r->out.resume_handle = resume;
2402 return werr;
2405 /********************************************************************
2406 _srvsvc_NetNameValidate
2407 ********************************************************************/
2409 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2410 struct srvsvc_NetNameValidate *r)
2412 switch (r->in.name_type) {
2413 case 0x9:
2414 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2415 strlen_m(r->in.name)))
2417 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2418 r->in.name));
2419 return WERR_INVALID_NAME;
2421 break;
2423 default:
2424 return WERR_UNKNOWN_LEVEL;
2427 return WERR_OK;
2430 /*******************************************************************
2431 ********************************************************************/
2433 static void enum_file_close_fn( const struct share_mode_entry *e,
2434 const char *sharepath, const char *fname,
2435 void *private_data )
2437 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2438 struct srvsvc_NetFileClose *r =
2439 (struct srvsvc_NetFileClose *)private_data;
2440 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2442 if (fid != r->in.fid) {
2443 return; /* Not this file. */
2446 if (!process_exists(e->pid) ) {
2447 return;
2450 /* Ok - send the close message. */
2451 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2452 sharepath,
2453 share_mode_str(talloc_tos(), 0, e) ));
2455 share_mode_entry_to_message(msg, e);
2457 r->out.result = ntstatus_to_werror(
2458 messaging_send_buf(smbd_messaging_context(),
2459 e->pid, MSG_SMB_CLOSE_FILE,
2460 (uint8 *)msg,
2461 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2464 /********************************************************************
2465 Close a file given a 32-bit file id.
2466 ********************************************************************/
2468 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2470 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2471 bool is_disk_op;
2473 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2475 is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
2477 if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
2478 return WERR_ACCESS_DENIED;
2481 /* enum_file_close_fn sends the close message to
2482 * the relevent smbd process. */
2484 r->out.result = WERR_BADFILE;
2485 share_mode_forall( enum_file_close_fn, (void *)r);
2486 return r->out.result;
2489 /********************************************************************
2490 ********************************************************************/
2492 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2494 p->rng_fault_state = True;
2495 return WERR_NOT_SUPPORTED;
2498 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2500 p->rng_fault_state = True;
2501 return WERR_NOT_SUPPORTED;
2504 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2506 p->rng_fault_state = True;
2507 return WERR_NOT_SUPPORTED;
2510 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2512 p->rng_fault_state = True;
2513 return WERR_NOT_SUPPORTED;
2516 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2518 p->rng_fault_state = True;
2519 return WERR_NOT_SUPPORTED;
2522 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2524 p->rng_fault_state = True;
2525 return WERR_NOT_SUPPORTED;
2528 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2530 p->rng_fault_state = True;
2531 return WERR_NOT_SUPPORTED;
2534 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2536 p->rng_fault_state = True;
2537 return WERR_NOT_SUPPORTED;
2540 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2542 p->rng_fault_state = True;
2543 return WERR_NOT_SUPPORTED;
2546 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2548 p->rng_fault_state = True;
2549 return WERR_NOT_SUPPORTED;
2552 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2554 p->rng_fault_state = True;
2555 return WERR_NOT_SUPPORTED;
2558 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2560 p->rng_fault_state = True;
2561 return WERR_NOT_SUPPORTED;
2564 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2566 p->rng_fault_state = True;
2567 return WERR_NOT_SUPPORTED;
2570 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2572 p->rng_fault_state = True;
2573 return WERR_NOT_SUPPORTED;
2576 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2578 p->rng_fault_state = True;
2579 return WERR_NOT_SUPPORTED;
2582 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2584 p->rng_fault_state = True;
2585 return WERR_NOT_SUPPORTED;
2588 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2590 p->rng_fault_state = True;
2591 return WERR_NOT_SUPPORTED;
2594 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2596 p->rng_fault_state = True;
2597 return WERR_NOT_SUPPORTED;
2600 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2602 p->rng_fault_state = True;
2603 return WERR_NOT_SUPPORTED;
2606 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2608 p->rng_fault_state = True;
2609 return WERR_NOT_SUPPORTED;
2612 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2614 p->rng_fault_state = True;
2615 return WERR_NOT_SUPPORTED;
2618 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2620 p->rng_fault_state = True;
2621 return WERR_NOT_SUPPORTED;
2624 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2626 p->rng_fault_state = True;
2627 return WERR_NOT_SUPPORTED;
2630 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2632 p->rng_fault_state = True;
2633 return WERR_NOT_SUPPORTED;
2636 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2638 p->rng_fault_state = True;
2639 return WERR_NOT_SUPPORTED;
2642 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2644 p->rng_fault_state = True;
2645 return WERR_NOT_SUPPORTED;
2648 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2650 p->rng_fault_state = True;
2651 return WERR_NOT_SUPPORTED;
2654 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2656 p->rng_fault_state = True;
2657 return WERR_NOT_SUPPORTED;
2660 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2662 p->rng_fault_state = True;
2663 return WERR_NOT_SUPPORTED;
2666 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2668 p->rng_fault_state = True;
2669 return WERR_NOT_SUPPORTED;
2672 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2674 p->rng_fault_state = True;
2675 return WERR_NOT_SUPPORTED;
2678 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2680 p->rng_fault_state = True;
2681 return WERR_NOT_SUPPORTED;
2684 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2686 p->rng_fault_state = True;
2687 return WERR_NOT_SUPPORTED;
2690 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2692 p->rng_fault_state = True;
2693 return WERR_NOT_SUPPORTED;
2696 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2698 p->rng_fault_state = True;
2699 return WERR_NOT_SUPPORTED;