Move MAX.*ENTRY definitions out of old rpc srvsvc parsing code.
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob2034b9792cfc727cfacc16ae1dbe46954379f822
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 /* This is the implementation of the srvsvc pipe. */
25 #include "includes.h"
27 extern const struct generic_mapping file_generic_mapping;
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_RPC_SRV
32 #define MAX_SERVER_DISK_ENTRIES 15
34 /***************************/
36 /* oops - this is going to take up a *massive* amount of stack. */
37 /* the UNISTR2s already have 1024 uint16 chars in them... */
39 #define MAX_SESS_ENTRIES 32
41 /***************************/
43 /* oops - this is going to take up a *massive* amount of stack. */
44 /* the UNISTR2s already have 1024 uint16 chars in them... */
45 #define MAX_CONN_ENTRIES 32
47 /* Use for enumerating connections, pipes, & files */
49 struct file_enum_count {
50 TALLOC_CTX *ctx;
51 const char *username;
52 struct srvsvc_NetFileCtr3 *ctr3;
55 struct sess_file_count {
56 struct server_id pid;
57 uid_t uid;
58 int count;
61 /****************************************************************************
62 Count the entries belonging to a service in the connection db.
63 ****************************************************************************/
65 static int pipe_enum_fn( struct db_record *rec, void *p)
67 struct pipe_open_rec prec;
68 struct file_enum_count *fenum = (struct file_enum_count *)p;
69 struct srvsvc_NetFileInfo3 *f;
70 int i = fenum->ctr3->count;
71 char *fullpath = NULL;
72 const char *username;
74 if (rec->value.dsize != sizeof(struct pipe_open_rec))
75 return 0;
77 memcpy(&prec, rec->value.dptr, sizeof(struct pipe_open_rec));
79 if ( !process_exists(prec.pid) ) {
80 return 0;
83 username = uidtoname(prec.uid);
85 if ((fenum->username != NULL)
86 && !strequal(username, fenum->username)) {
87 return 0;
90 fullpath = talloc_asprintf(fenum->ctx, "\\PIPE\\%s", prec.name );
91 if (!fullpath) {
92 return 1;
95 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
96 struct srvsvc_NetFileInfo3, i+1);
97 if ( !f ) {
98 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
99 return 1;
101 fenum->ctr3->array = f;
103 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
104 (uint32_t)((procid_to_pid(&prec.pid)<<16) & prec.pnum),
105 (FILE_READ_DATA|FILE_WRITE_DATA),
107 fullpath,
108 username);
110 fenum->ctr3->count++;
112 return 0;
115 /*******************************************************************
116 ********************************************************************/
118 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
119 const char *username,
120 struct srvsvc_NetFileCtr3 **ctr3,
121 uint32_t resume )
123 struct file_enum_count fenum;
125 fenum.ctx = ctx;
126 fenum.username = username;
127 fenum.ctr3 = *ctr3;
129 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
130 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
131 "failed\n"));
132 return WERR_NOMEM;
135 *ctr3 = fenum.ctr3;
137 return WERR_OK;
140 /*******************************************************************
141 ********************************************************************/
143 static void enum_file_fn( const struct share_mode_entry *e,
144 const char *sharepath, const char *fname,
145 void *private_data )
147 struct file_enum_count *fenum =
148 (struct file_enum_count *)private_data;
150 struct srvsvc_NetFileInfo3 *f;
151 int i = fenum->ctr3->count;
152 files_struct fsp;
153 struct byte_range_lock *brl;
154 int num_locks = 0;
155 char *fullpath = NULL;
156 uint32 permissions;
157 const char *username;
159 /* If the pid was not found delete the entry from connections.tdb */
161 if ( !process_exists(e->pid) ) {
162 return;
165 username = uidtoname(e->uid);
167 if ((fenum->username != NULL)
168 && !strequal(username, fenum->username)) {
169 return;
172 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
173 struct srvsvc_NetFileInfo3, i+1);
174 if ( !f ) {
175 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
176 return;
178 fenum->ctr3->array = f;
180 /* need to count the number of locks on a file */
182 ZERO_STRUCT( fsp );
183 fsp.file_id = e->id;
185 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
186 num_locks = brl->num_locks;
187 TALLOC_FREE(brl);
190 if ( strcmp( fname, "." ) == 0 ) {
191 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
192 } else {
193 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
194 sharepath, fname );
196 if (!fullpath) {
197 return;
199 string_replace( fullpath, '/', '\\' );
201 /* mask out create (what ever that is) */
202 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
204 /* now fill in the srvsvc_NetFileInfo3 struct */
205 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
206 e->share_file_id,
207 permissions,
208 num_locks,
209 username,
210 fullpath);
211 fenum->ctr3->count++;
214 /*******************************************************************
215 ********************************************************************/
217 static WERROR net_enum_files(TALLOC_CTX *ctx,
218 const char *username,
219 struct srvsvc_NetFileCtr3 **ctr3,
220 uint32_t resume)
222 struct file_enum_count f_enum_cnt;
224 f_enum_cnt.ctx = ctx;
225 f_enum_cnt.username = username;
226 f_enum_cnt.ctr3 = *ctr3;
228 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
230 *ctr3 = f_enum_cnt.ctr3;
232 return WERR_OK;
235 /*******************************************************************
236 Utility function to get the 'type' of a share from an snum.
237 ********************************************************************/
238 static uint32 get_share_type(int snum)
240 /* work out the share type */
241 uint32 type = STYPE_DISKTREE;
243 if (lp_print_ok(snum))
244 type = STYPE_PRINTQ;
245 if (strequal(lp_fstype(snum), "IPC"))
246 type = STYPE_IPC;
247 if (lp_administrative_share(snum))
248 type |= STYPE_HIDDEN;
250 return type;
253 /*******************************************************************
254 Fill in a share info level 0 structure.
255 ********************************************************************/
257 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
259 const char *net_name = lp_servicename(snum);
261 init_srvsvc_NetShareInfo0(r, net_name);
264 /*******************************************************************
265 Fill in a share info level 1 structure.
266 ********************************************************************/
268 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
270 char *net_name = lp_servicename(snum);
271 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
273 if (remark) {
274 remark = standard_sub_conn(p->mem_ctx,
275 p->conn,
276 remark);
279 init_srvsvc_NetShareInfo1(r, net_name,
280 get_share_type(snum),
281 remark ? remark : "");
284 /*******************************************************************
285 Fill in a share info level 2 structure.
286 ********************************************************************/
288 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
290 char *remark = NULL;
291 char *path = NULL;
292 int max_connections = lp_max_connections(snum);
293 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
294 int count = 0;
295 char *net_name = lp_servicename(snum);
297 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
298 if (remark) {
299 remark = standard_sub_conn(p->mem_ctx,
300 p->conn,
301 remark);
303 path = talloc_asprintf(p->mem_ctx,
304 "C:%s", lp_pathname(snum));
306 if (path) {
308 * Change / to \\ so that win2k will see it as a valid path.
309 * This was added to enable use of browsing in win2k add
310 * share dialog.
313 string_replace(path, '/', '\\');
316 count = count_current_connections(net_name, false);
318 init_srvsvc_NetShareInfo2(r, net_name,
319 get_share_type(snum),
320 remark ? remark : "",
322 max_uses,
323 count,
324 path ? path : "",
325 "");
328 /*******************************************************************
329 Map any generic bits to file specific bits.
330 ********************************************************************/
332 static void map_generic_share_sd_bits(SEC_DESC *psd)
334 int i;
335 SEC_ACL *ps_dacl = NULL;
337 if (!psd)
338 return;
340 ps_dacl = psd->dacl;
341 if (!ps_dacl)
342 return;
344 for (i = 0; i < ps_dacl->num_aces; i++) {
345 SEC_ACE *psa = &ps_dacl->aces[i];
346 uint32 orig_mask = psa->access_mask;
348 se_map_generic(&psa->access_mask, &file_generic_mapping);
349 psa->access_mask |= orig_mask;
353 /*******************************************************************
354 Fill in a share info level 501 structure.
355 ********************************************************************/
357 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
359 const char *net_name = lp_servicename(snum);
360 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
362 if (remark) {
363 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
366 init_srvsvc_NetShareInfo501(r, net_name,
367 get_share_type(snum),
368 remark ? remark : "",
369 (lp_csc_policy(snum) << 4));
372 /*******************************************************************
373 Fill in a share info level 502 structure.
374 ********************************************************************/
376 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
378 const char *net_name = lp_servicename(snum);
379 char *path = NULL;
380 SEC_DESC *sd = NULL;
381 size_t sd_size = 0;
382 TALLOC_CTX *ctx = p->mem_ctx;
383 char *remark = talloc_strdup(ctx, lp_comment(snum));;
385 if (remark) {
386 remark = standard_sub_conn(ctx, p->conn, remark);
388 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
389 if (path) {
391 * Change / to \\ so that win2k will see it as a valid path. This was added to
392 * enable use of browsing in win2k add share dialog.
394 string_replace(path, '/', '\\');
397 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
399 init_srvsvc_NetShareInfo502(r, net_name,
400 get_share_type(snum),
401 remark ? remark : "",
403 0xffffffff,
405 path ? path : "",
408 sd);
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 = standard_sub_conn(p->mem_ctx, p->conn, remark);
423 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
426 /***************************************************************************
427 Fill in a share info level 1005 structure.
428 ***************************************************************************/
430 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
432 uint32_t dfs_flags = 0;
434 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
435 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
438 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
440 init_srvsvc_NetShareInfo1005(r, dfs_flags);
443 /***************************************************************************
444 Fill in a share info level 1006 structure.
445 ***************************************************************************/
447 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
449 init_srvsvc_NetShareInfo1006(r, 0xffffffff);
452 /***************************************************************************
453 Fill in a share info level 1007 structure.
454 ***************************************************************************/
456 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
458 uint32 flags = 0;
460 init_srvsvc_NetShareInfo1007(r, flags, "");
463 /*******************************************************************
464 Fill in a share info level 1501 structure.
465 ********************************************************************/
467 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
469 SEC_DESC *sd;
470 size_t sd_size;
471 TALLOC_CTX *ctx = p->mem_ctx;
473 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
475 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
478 /*******************************************************************
479 True if it ends in '$'.
480 ********************************************************************/
482 static bool is_hidden_share(int snum)
484 const char *net_name = lp_servicename(snum);
486 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
489 /*******************************************************************
490 Fill in a share info structure.
491 ********************************************************************/
493 static WERROR init_srv_share_info_ctr(pipes_struct *p,
494 struct srvsvc_NetShareInfoCtr *info_ctr,
495 uint32_t *resume_handle_p,
496 uint32_t *total_entries,
497 bool all_shares)
499 int num_entries = 0;
500 int alloc_entries = 0;
501 int num_services = 0;
502 int snum;
503 TALLOC_CTX *ctx = p->mem_ctx;
504 int i = 0;
505 int valid_share_count = 0;
506 union srvsvc_NetShareCtr ctr;
507 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
509 DEBUG(5,("init_srv_share_info_ctr\n"));
511 /* Ensure all the usershares are loaded. */
512 become_root();
513 load_usershare_shares();
514 load_registry_shares();
515 num_services = lp_numservices();
516 unbecome_root();
518 /* Count the number of entries. */
519 for (snum = 0; snum < num_services; snum++) {
520 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
521 num_entries++;
525 if (!num_entries || (resume_handle >= num_entries)) {
526 return WERR_OK;
529 /* Calculate alloc entries. */
530 alloc_entries = num_entries - resume_handle;
531 switch (info_ctr->level) {
532 case 0:
533 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
534 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
536 ctr.ctr0->count = alloc_entries;
537 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
538 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
540 for (snum = 0; snum < num_services; snum++) {
541 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
542 (resume_handle <= (i + valid_share_count++)) ) {
543 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
547 break;
549 case 1:
550 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
551 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
553 ctr.ctr1->count = alloc_entries;
554 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
555 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
557 for (snum = 0; snum < num_services; snum++) {
558 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
559 (resume_handle <= (i + valid_share_count++)) ) {
560 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
564 break;
566 case 2:
567 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
568 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
570 ctr.ctr2->count = alloc_entries;
571 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
572 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
574 for (snum = 0; snum < num_services; snum++) {
575 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
576 (resume_handle <= (i + valid_share_count++)) ) {
577 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
581 break;
583 case 501:
584 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
585 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
587 ctr.ctr501->count = alloc_entries;
588 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
589 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
591 for (snum = 0; snum < num_services; snum++) {
592 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
593 (resume_handle <= (i + valid_share_count++)) ) {
594 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
598 break;
600 case 502:
601 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
602 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
604 ctr.ctr502->count = alloc_entries;
605 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
606 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
608 for (snum = 0; snum < num_services; snum++) {
609 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
610 (resume_handle <= (i + valid_share_count++)) ) {
611 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
615 break;
617 case 1004:
618 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
619 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
621 ctr.ctr1004->count = alloc_entries;
622 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
623 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
625 for (snum = 0; snum < num_services; snum++) {
626 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
627 (resume_handle <= (i + valid_share_count++)) ) {
628 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
632 break;
634 case 1005:
635 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
636 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
638 ctr.ctr1005->count = alloc_entries;
639 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
640 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
642 for (snum = 0; snum < num_services; snum++) {
643 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
644 (resume_handle <= (i + valid_share_count++)) ) {
645 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
649 break;
651 case 1006:
652 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
653 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
655 ctr.ctr1006->count = alloc_entries;
656 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
657 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
659 for (snum = 0; snum < num_services; snum++) {
660 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
661 (resume_handle <= (i + valid_share_count++)) ) {
662 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
666 break;
668 case 1007:
669 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
670 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
672 ctr.ctr1007->count = alloc_entries;
673 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
674 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
676 for (snum = 0; snum < num_services; snum++) {
677 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
678 (resume_handle <= (i + valid_share_count++)) ) {
679 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
683 break;
685 case 1501:
686 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
687 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
689 ctr.ctr1501->count = alloc_entries;
690 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
691 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
693 for (snum = 0; snum < num_services; snum++) {
694 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
695 (resume_handle <= (i + valid_share_count++)) ) {
696 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
700 break;
702 default:
703 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
704 info_ctr->level));
705 return WERR_UNKNOWN_LEVEL;
708 *total_entries = alloc_entries;
709 if (resume_handle_p) {
710 if (all_shares) {
711 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
712 } else {
713 *resume_handle_p = num_entries;
717 info_ctr->ctr = ctr;
719 return WERR_OK;
722 /*******************************************************************
723 fill in a sess info level 0 structure.
724 ********************************************************************/
726 static WERROR init_srv_sess_info_0(pipes_struct *p,
727 struct srvsvc_NetSessCtr0 *ctr0,
728 uint32_t *resume_handle_p,
729 uint32_t *total_entries)
731 struct sessionid *session_list;
732 uint32_t num_entries = 0;
733 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
734 *total_entries = list_sessions(p->mem_ctx, &session_list);
736 DEBUG(5,("init_srv_sess_info_0\n"));
738 if (ctr0 == NULL) {
739 if (resume_handle_p) {
740 *resume_handle_p = 0;
742 return WERR_OK;
745 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
747 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
748 ctr0->array,
749 struct srvsvc_NetSessInfo0,
750 num_entries+1);
751 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
753 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
754 session_list[resume_handle].remote_machine);
755 num_entries++;
758 ctr0->count = num_entries;
760 if (resume_handle_p) {
761 if (*resume_handle_p >= *total_entries) {
762 *resume_handle_p = 0;
763 } else {
764 *resume_handle_p = resume_handle;
768 return WERR_OK;
771 /*******************************************************************
772 ********************************************************************/
774 static void sess_file_fn( const struct share_mode_entry *e,
775 const char *sharepath, const char *fname,
776 void *data )
778 struct sess_file_count *sess = (struct sess_file_count *)data;
780 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
781 sess->count++;
784 return;
787 /*******************************************************************
788 ********************************************************************/
790 static int net_count_files( uid_t uid, struct server_id pid )
792 struct sess_file_count s_file_cnt;
794 s_file_cnt.count = 0;
795 s_file_cnt.uid = uid;
796 s_file_cnt.pid = pid;
798 share_mode_forall( sess_file_fn, &s_file_cnt );
800 return s_file_cnt.count;
803 /*******************************************************************
804 fill in a sess info level 1 structure.
805 ********************************************************************/
807 static WERROR init_srv_sess_info_1(pipes_struct *p,
808 struct srvsvc_NetSessCtr1 *ctr1,
809 uint32_t *resume_handle_p,
810 uint32_t *total_entries)
812 struct sessionid *session_list;
813 uint32_t num_entries = 0;
814 time_t now = time(NULL);
815 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
817 ZERO_STRUCTP(ctr1);
819 if (ctr1 == NULL) {
820 if (resume_handle_p) {
821 *resume_handle_p = 0;
823 return WERR_OK;
826 *total_entries = list_sessions(p->mem_ctx, &session_list);
828 for (; resume_handle < *total_entries && num_entries < MAX_SESS_ENTRIES; resume_handle++) {
829 uint32 num_files;
830 uint32 connect_time;
831 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
832 bool guest;
834 if ( !pw ) {
835 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
836 session_list[resume_handle].username));
837 continue;
840 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
841 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
842 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
844 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
845 ctr1->array,
846 struct srvsvc_NetSessInfo1,
847 num_entries+1);
848 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
850 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
851 session_list[resume_handle].remote_machine,
852 session_list[resume_handle].username,
853 num_files,
854 connect_time,
856 guest);
857 num_entries++;
860 ctr1->count = num_entries;
862 if (resume_handle_p) {
863 if (*resume_handle_p >= *total_entries) {
864 *resume_handle_p = 0;
865 } else {
866 *resume_handle_p = resume_handle;
870 return WERR_OK;
873 /*******************************************************************
874 fill in a conn info level 0 structure.
875 ********************************************************************/
877 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
878 uint32_t *resume_handle_p,
879 uint32_t *total_entries)
881 uint32_t num_entries = 0;
882 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
884 DEBUG(5,("init_srv_conn_info_0\n"));
886 if (ctr0 == NULL) {
887 if (resume_handle_p) {
888 *resume_handle_p = 0;
890 return WERR_OK;
893 *total_entries = 1;
895 ZERO_STRUCTP(ctr0);
897 for (; resume_handle < *total_entries && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
899 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
900 ctr0->array,
901 struct srvsvc_NetConnInfo0,
902 num_entries+1);
903 if (!ctr0->array) {
904 return WERR_NOMEM;
907 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
908 (*total_entries));
910 /* move on to creating next connection */
911 num_entries++;
914 ctr0->count = num_entries;
915 *total_entries = num_entries;
917 if (resume_handle_p) {
918 if (*resume_handle_p >= *total_entries) {
919 *resume_handle_p = 0;
920 } else {
921 *resume_handle_p = resume_handle;
925 return WERR_OK;
928 /*******************************************************************
929 fill in a conn info level 1 structure.
930 ********************************************************************/
932 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
933 uint32_t *resume_handle_p,
934 uint32_t *total_entries)
936 uint32_t num_entries = 0;
937 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
939 DEBUG(5,("init_srv_conn_info_1\n"));
941 if (ctr1 == NULL) {
942 if (resume_handle_p) {
943 *resume_handle_p = 0;
945 return WERR_OK;
948 *total_entries = 1;
950 ZERO_STRUCTP(ctr1);
952 for (; (resume_handle < *total_entries) && num_entries < MAX_CONN_ENTRIES; resume_handle++) {
954 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
955 ctr1->array,
956 struct srvsvc_NetConnInfo1,
957 num_entries+1);
958 if (!ctr1->array) {
959 return WERR_NOMEM;
962 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
963 (*total_entries),
964 0x3,
968 "dummy_user",
969 "IPC$");
971 /* move on to creating next connection */
972 num_entries++;
975 ctr1->count = num_entries;
976 *total_entries = num_entries;
978 if (resume_handle_p) {
979 if (*resume_handle_p >= *total_entries) {
980 *resume_handle_p = 0;
981 } else {
982 *resume_handle_p = resume_handle;
986 return WERR_OK;
989 /*******************************************************************
990 _srvsvc_NetFileEnum
991 *******************************************************************/
993 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
994 struct srvsvc_NetFileEnum *r)
996 TALLOC_CTX *ctx = NULL;
997 struct srvsvc_NetFileCtr3 *ctr3;
998 uint32_t resume_hnd = 0;
999 WERROR werr;
1001 switch (r->in.info_ctr->level) {
1002 case 3:
1003 break;
1004 default:
1005 return WERR_UNKNOWN_LEVEL;
1008 ctx = talloc_tos();
1009 ctr3 = r->in.info_ctr->ctr.ctr3;
1010 if (!ctr3) {
1011 goto done;
1014 /* TODO -- Windows enumerates
1015 (b) active pipes
1016 (c) open directories and files */
1018 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1019 if (!W_ERROR_IS_OK(werr)) {
1020 goto done;
1023 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1024 if (!W_ERROR_IS_OK(werr)) {
1025 goto done;
1028 *r->out.totalentries = ctr3->count;
1029 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1030 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1032 werr = WERR_OK;
1034 done:
1035 return werr;
1038 /*******************************************************************
1039 _srvsvc_NetSrvGetInfo
1040 ********************************************************************/
1042 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1043 struct srvsvc_NetSrvGetInfo *r)
1045 WERROR status = WERR_OK;
1047 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1049 if (!pipe_access_check(p)) {
1050 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1051 return WERR_ACCESS_DENIED;
1054 switch (r->in.level) {
1056 /* Technically level 102 should only be available to
1057 Administrators but there isn't anything super-secret
1058 here, as most of it is made up. */
1060 case 102: {
1061 struct srvsvc_NetSrvInfo102 *info102;
1063 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1064 if (!info102) {
1065 return WERR_NOMEM;
1068 init_srvsvc_NetSrvInfo102(info102,
1069 PLATFORM_ID_NT,
1070 global_myname(),
1071 lp_major_announce_version(),
1072 lp_minor_announce_version(),
1073 lp_default_server_announce(),
1074 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1075 0xffffffff, /* users */
1076 0xf, /* disc */
1077 0, /* hidden */
1078 240, /* announce */
1079 3000, /* announce delta */
1080 100000, /* licenses */
1081 "c:\\"); /* user path */
1082 r->out.info->info102 = info102;
1083 break;
1085 case 101: {
1086 struct srvsvc_NetSrvInfo101 *info101;
1088 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1089 if (!info101) {
1090 return WERR_NOMEM;
1093 init_srvsvc_NetSrvInfo101(info101,
1094 PLATFORM_ID_NT,
1095 global_myname(),
1096 lp_major_announce_version(),
1097 lp_minor_announce_version(),
1098 lp_default_server_announce(),
1099 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1100 r->out.info->info101 = info101;
1101 break;
1103 case 100: {
1104 struct srvsvc_NetSrvInfo100 *info100;
1106 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1107 if (!info100) {
1108 return WERR_NOMEM;
1111 init_srvsvc_NetSrvInfo100(info100,
1112 PLATFORM_ID_NT,
1113 global_myname());
1114 r->out.info->info100 = info100;
1116 break;
1118 default:
1119 status = WERR_UNKNOWN_LEVEL;
1120 break;
1123 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1125 return status;
1128 /*******************************************************************
1129 _srvsvc_NetSrvSetInfo
1130 ********************************************************************/
1132 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1133 struct srvsvc_NetSrvSetInfo *r)
1135 WERROR status = WERR_OK;
1137 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1139 /* Set up the net server set info structure. */
1141 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1143 return status;
1146 /*******************************************************************
1147 _srvsvc_NetConnEnum
1148 ********************************************************************/
1150 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1151 struct srvsvc_NetConnEnum *r)
1153 WERROR werr;
1155 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1157 switch (r->in.info_ctr->level) {
1158 case 0:
1159 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1160 r->in.resume_handle,
1161 r->out.totalentries);
1162 break;
1163 case 1:
1164 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1165 r->in.resume_handle,
1166 r->out.totalentries);
1167 break;
1168 default:
1169 return WERR_UNKNOWN_LEVEL;
1172 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1174 return werr;
1177 /*******************************************************************
1178 _srvsvc_NetSessEnum
1179 ********************************************************************/
1181 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1182 struct srvsvc_NetSessEnum *r)
1184 WERROR werr;
1186 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1188 switch (r->in.info_ctr->level) {
1189 case 0:
1190 werr = init_srv_sess_info_0(p,
1191 r->in.info_ctr->ctr.ctr0,
1192 r->in.resume_handle,
1193 r->out.totalentries);
1194 break;
1195 case 1:
1196 werr = init_srv_sess_info_1(p,
1197 r->in.info_ctr->ctr.ctr1,
1198 r->in.resume_handle,
1199 r->out.totalentries);
1200 break;
1201 default:
1202 return WERR_UNKNOWN_LEVEL;
1205 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1207 return werr;
1210 /*******************************************************************
1211 _srvsvc_NetSessDel
1212 ********************************************************************/
1214 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1215 struct srvsvc_NetSessDel *r)
1217 struct sessionid *session_list;
1218 struct current_user user;
1219 int num_sessions, snum;
1220 const char *username;
1221 const char *machine;
1222 bool not_root = False;
1223 WERROR werr;
1225 username = r->in.user;
1226 machine = r->in.client;
1228 /* strip leading backslashes if any */
1229 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1230 machine += 2;
1233 num_sessions = list_sessions(p->mem_ctx, &session_list);
1235 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1237 werr = WERR_ACCESS_DENIED;
1239 get_current_user(&user, p);
1241 /* fail out now if you are not root or not a domain admin */
1243 if ((user.ut.uid != sec_initial_uid()) &&
1244 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1246 goto done;
1249 for (snum = 0; snum < num_sessions; snum++) {
1251 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1252 strequal(session_list[snum].remote_machine, machine)) {
1254 NTSTATUS ntstat;
1256 if (user.ut.uid != sec_initial_uid()) {
1257 not_root = True;
1258 become_root();
1261 ntstat = messaging_send(smbd_messaging_context(),
1262 session_list[snum].pid,
1263 MSG_SHUTDOWN, &data_blob_null);
1265 if (NT_STATUS_IS_OK(ntstat))
1266 werr = WERR_OK;
1268 if (not_root)
1269 unbecome_root();
1273 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1275 done:
1277 return werr;
1280 /*******************************************************************
1281 _srvsvc_NetShareEnumAll
1282 ********************************************************************/
1284 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1285 struct srvsvc_NetShareEnumAll *r)
1287 WERROR werr;
1289 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1291 if (!pipe_access_check(p)) {
1292 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1293 return WERR_ACCESS_DENIED;
1296 /* Create the list of shares for the response. */
1297 werr = init_srv_share_info_ctr(p,
1298 r->in.info_ctr,
1299 r->in.resume_handle,
1300 r->out.totalentries,
1301 true);
1303 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1305 return werr;
1308 /*******************************************************************
1309 _srvsvc_NetShareEnum
1310 ********************************************************************/
1312 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1313 struct srvsvc_NetShareEnum *r)
1315 WERROR werr;
1317 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1319 if (!pipe_access_check(p)) {
1320 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\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 false);
1331 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1333 return werr;
1336 /*******************************************************************
1337 _srvsvc_NetShareGetInfo
1338 ********************************************************************/
1340 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1341 struct srvsvc_NetShareGetInfo *r)
1343 WERROR status = WERR_OK;
1344 fstring share_name;
1345 int snum;
1346 union srvsvc_NetShareInfo *info = r->out.info;
1348 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1350 fstrcpy(share_name, r->in.share_name);
1352 snum = find_service(share_name);
1353 if (snum < 0) {
1354 return WERR_INVALID_NAME;
1357 switch (r->in.level) {
1358 case 0:
1359 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1360 W_ERROR_HAVE_NO_MEMORY(info->info0);
1361 init_srv_share_info_0(p, info->info0, snum);
1362 break;
1363 case 1:
1364 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1365 W_ERROR_HAVE_NO_MEMORY(info->info1);
1366 init_srv_share_info_1(p, info->info1, snum);
1367 break;
1368 case 2:
1369 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1370 W_ERROR_HAVE_NO_MEMORY(info->info2);
1371 init_srv_share_info_2(p, info->info2, snum);
1372 break;
1373 case 501:
1374 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1375 W_ERROR_HAVE_NO_MEMORY(info->info501);
1376 init_srv_share_info_501(p, info->info501, snum);
1377 break;
1378 case 502:
1379 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1380 W_ERROR_HAVE_NO_MEMORY(info->info502);
1381 init_srv_share_info_502(p, info->info502, snum);
1382 break;
1383 case 1004:
1384 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1385 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1386 init_srv_share_info_1004(p, info->info1004, snum);
1387 break;
1388 case 1005:
1389 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1390 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1391 init_srv_share_info_1005(p, info->info1005, snum);
1392 break;
1393 case 1006:
1394 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1395 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1396 init_srv_share_info_1006(p, info->info1006, snum);
1397 break;
1398 case 1007:
1399 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1400 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1401 init_srv_share_info_1007(p, info->info1007, snum);
1402 break;
1403 case 1501:
1404 init_srv_share_info_1501(p, info->info1501, snum);
1405 break;
1406 default:
1407 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1408 r->in.level));
1409 status = WERR_UNKNOWN_LEVEL;
1410 break;
1413 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1415 return status;
1418 /*******************************************************************
1419 Check a given DOS pathname is valid for a share.
1420 ********************************************************************/
1422 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1424 char *ptr = NULL;
1426 if (!dos_pathname) {
1427 return NULL;
1430 ptr = talloc_strdup(ctx, dos_pathname);
1431 if (!ptr) {
1432 return NULL;
1434 /* Convert any '\' paths to '/' */
1435 unix_format(ptr);
1436 ptr = unix_clean_name(ctx, ptr);
1437 if (!ptr) {
1438 return NULL;
1441 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1442 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1443 ptr += 2;
1445 /* Only absolute paths allowed. */
1446 if (*ptr != '/')
1447 return NULL;
1449 return ptr;
1452 /*******************************************************************
1453 _srvsvc_NetShareSetInfo. Modify share details.
1454 ********************************************************************/
1456 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1457 struct srvsvc_NetShareSetInfo *r)
1459 struct current_user user;
1460 char *command = NULL;
1461 char *share_name = NULL;
1462 char *comment = NULL;
1463 const char *pathname = NULL;
1464 int type;
1465 int snum;
1466 int ret;
1467 char *path = NULL;
1468 SEC_DESC *psd = NULL;
1469 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1470 bool is_disk_op = False;
1471 int max_connections = 0;
1472 TALLOC_CTX *ctx = p->mem_ctx;
1473 union srvsvc_NetShareInfo *info = r->in.info;
1475 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1477 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1478 if (!share_name) {
1479 return WERR_NOMEM;
1482 *r->out.parm_error = 0;
1484 if ( strequal(share_name,"IPC$")
1485 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1486 || strequal(share_name,"global") )
1488 return WERR_ACCESS_DENIED;
1491 snum = find_service(share_name);
1493 /* Does this share exist ? */
1494 if (snum < 0)
1495 return WERR_NET_NAME_NOT_FOUND;
1497 /* No change to printer shares. */
1498 if (lp_print_ok(snum))
1499 return WERR_ACCESS_DENIED;
1501 get_current_user(&user,p);
1503 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1505 /* fail out now if you are not root and not a disk op */
1507 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1508 return WERR_ACCESS_DENIED;
1510 switch (r->in.level) {
1511 case 1:
1512 pathname = talloc_strdup(ctx, lp_pathname(snum));
1513 comment = talloc_strdup(ctx, info->info2->comment);
1514 type = info->info2->type;
1515 psd = NULL;
1516 break;
1517 case 2:
1518 comment = talloc_strdup(ctx, info->info2->comment);
1519 pathname = info->info2->path;
1520 type = info->info2->type;
1521 max_connections = (info->info2->max_users == 0xffffffff) ?
1522 0 : info->info2->max_users;
1523 psd = NULL;
1524 break;
1525 #if 0
1526 /* not supported on set but here for completeness */
1527 case 501:
1528 comment = talloc_strdup(ctx, info->info501->comment);
1529 type = info->info501->type;
1530 psd = NULL;
1531 break;
1532 #endif
1533 case 502:
1534 comment = talloc_strdup(ctx, info->info502->comment);
1535 pathname = info->info502->path;
1536 type = info->info502->type;
1537 psd = info->info502->sd;
1538 map_generic_share_sd_bits(psd);
1539 break;
1540 case 1004:
1541 pathname = talloc_strdup(ctx, lp_pathname(snum));
1542 comment = talloc_strdup(ctx, info->info1004->comment);
1543 type = STYPE_DISKTREE;
1544 break;
1545 case 1005:
1546 /* XP re-sets the csc policy even if it wasn't changed by the
1547 user, so we must compare it to see if it's what is set in
1548 smb.conf, so that we can contine other ops like setting
1549 ACLs on a share */
1550 if (((info->info1005->dfs_flags &
1551 SHARE_1005_CSC_POLICY_MASK) >>
1552 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1553 return WERR_OK;
1554 else {
1555 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1556 return WERR_ACCESS_DENIED;
1558 case 1006:
1559 case 1007:
1560 return WERR_ACCESS_DENIED;
1561 case 1501:
1562 pathname = talloc_strdup(ctx, lp_pathname(snum));
1563 comment = talloc_strdup(ctx, lp_comment(snum));
1564 psd = info->info1501->sd;
1565 map_generic_share_sd_bits(psd);
1566 type = STYPE_DISKTREE;
1567 break;
1568 default:
1569 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1570 r->in.level));
1571 return WERR_UNKNOWN_LEVEL;
1574 /* We can only modify disk shares. */
1575 if (type != STYPE_DISKTREE)
1576 return WERR_ACCESS_DENIED;
1578 if (comment == NULL) {
1579 return WERR_NOMEM;
1582 /* Check if the pathname is valid. */
1583 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1584 return WERR_OBJECT_PATH_INVALID;
1586 /* Ensure share name, pathname and comment don't contain '"' characters. */
1587 string_replace(share_name, '"', ' ');
1588 string_replace(path, '"', ' ');
1589 string_replace(comment, '"', ' ');
1591 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1592 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1594 /* Only call modify function if something changed. */
1596 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1597 || (lp_max_connections(snum) != max_connections)) {
1598 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1599 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1600 return WERR_ACCESS_DENIED;
1603 command = talloc_asprintf(p->mem_ctx,
1604 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1605 lp_change_share_cmd(),
1606 get_dyn_CONFIGFILE(),
1607 share_name,
1608 path,
1609 comment ? comment : "",
1610 max_connections);
1611 if (!command) {
1612 return WERR_NOMEM;
1615 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1617 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1619 if (is_disk_op)
1620 become_root();
1622 if ( (ret = smbrun(command, NULL)) == 0 ) {
1623 /* Tell everyone we updated smb.conf. */
1624 message_send_all(smbd_messaging_context(),
1625 MSG_SMB_CONF_UPDATED, NULL, 0,
1626 NULL);
1629 if ( is_disk_op )
1630 unbecome_root();
1632 /********* END SeDiskOperatorPrivilege BLOCK *********/
1634 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1635 command, ret ));
1637 TALLOC_FREE(command);
1639 if ( ret != 0 )
1640 return WERR_ACCESS_DENIED;
1641 } else {
1642 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1643 share_name ));
1646 /* Replace SD if changed. */
1647 if (psd) {
1648 SEC_DESC *old_sd;
1649 size_t sd_size;
1651 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1653 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1654 if (!set_share_security(share_name, psd))
1655 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1656 share_name ));
1660 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1662 return WERR_OK;
1665 /*******************************************************************
1666 _srvsvc_NetShareAdd.
1667 Call 'add_share_command "sharename" "pathname"
1668 "comment" "max connections = "
1669 ********************************************************************/
1671 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1672 struct srvsvc_NetShareAdd *r)
1674 struct current_user user;
1675 char *command = NULL;
1676 char *share_name = NULL;
1677 char *comment = NULL;
1678 char *pathname = NULL;
1679 int type;
1680 int snum;
1681 int ret;
1682 char *path;
1683 SEC_DESC *psd = NULL;
1684 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1685 bool is_disk_op;
1686 int max_connections = 0;
1687 TALLOC_CTX *ctx = p->mem_ctx;
1689 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1691 *r->out.parm_error = 0;
1693 get_current_user(&user,p);
1695 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1697 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1698 return WERR_ACCESS_DENIED;
1700 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1701 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1702 return WERR_ACCESS_DENIED;
1705 switch (r->in.level) {
1706 case 0:
1707 /* No path. Not enough info in a level 0 to do anything. */
1708 return WERR_ACCESS_DENIED;
1709 case 1:
1710 /* Not enough info in a level 1 to do anything. */
1711 return WERR_ACCESS_DENIED;
1712 case 2:
1713 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1714 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1715 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1716 max_connections = (r->in.info->info2->max_users == 0xffffffff) ?
1717 0 : r->in.info->info2->max_users;
1718 type = r->in.info->info2->type;
1719 break;
1720 case 501:
1721 /* No path. Not enough info in a level 501 to do anything. */
1722 return WERR_ACCESS_DENIED;
1723 case 502:
1724 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1725 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1726 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1727 max_connections = (r->in.info->info502->max_users == 0xffffffff) ?
1728 0 : r->in.info->info502->max_users;
1729 type = r->in.info->info502->type;
1730 psd = r->in.info->info502->sd;
1731 map_generic_share_sd_bits(psd);
1732 break;
1734 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1736 case 1004:
1737 case 1005:
1738 case 1006:
1739 case 1007:
1740 return WERR_ACCESS_DENIED;
1741 case 1501:
1742 /* DFS only level. */
1743 return WERR_ACCESS_DENIED;
1744 default:
1745 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1746 r->in.level));
1747 return WERR_UNKNOWN_LEVEL;
1750 /* check for invalid share names */
1752 if (!share_name || !validate_net_name(share_name,
1753 INVALID_SHARENAME_CHARS,
1754 strlen(share_name))) {
1755 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1756 share_name ? share_name : ""));
1757 return WERR_INVALID_NAME;
1760 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1761 || (lp_enable_asu_support() &&
1762 strequal(share_name,"ADMIN$"))) {
1763 return WERR_ACCESS_DENIED;
1766 snum = find_service(share_name);
1768 /* Share already exists. */
1769 if (snum >= 0) {
1770 return WERR_ALREADY_EXISTS;
1773 /* We can only add disk shares. */
1774 if (type != STYPE_DISKTREE) {
1775 return WERR_ACCESS_DENIED;
1778 /* Check if the pathname is valid. */
1779 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1780 return WERR_OBJECT_PATH_INVALID;
1783 /* Ensure share name, pathname and comment don't contain '"' characters. */
1784 string_replace(share_name, '"', ' ');
1785 string_replace(path, '"', ' ');
1786 if (comment) {
1787 string_replace(comment, '"', ' ');
1790 command = talloc_asprintf(ctx,
1791 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1792 lp_add_share_cmd(),
1793 get_dyn_CONFIGFILE(),
1794 share_name,
1795 path,
1796 comment ? comment : "",
1797 max_connections);
1798 if (!command) {
1799 return WERR_NOMEM;
1802 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1804 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1806 if ( is_disk_op )
1807 become_root();
1809 /* FIXME: use libnetconf here - gd */
1811 if ( (ret = smbrun(command, NULL)) == 0 ) {
1812 /* Tell everyone we updated smb.conf. */
1813 message_send_all(smbd_messaging_context(),
1814 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1817 if ( is_disk_op )
1818 unbecome_root();
1820 /********* END SeDiskOperatorPrivilege BLOCK *********/
1822 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1823 command, ret ));
1825 TALLOC_FREE(command);
1827 if ( ret != 0 )
1828 return WERR_ACCESS_DENIED;
1830 if (psd) {
1831 if (!set_share_security(share_name, psd)) {
1832 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1833 share_name ));
1838 * We don't call reload_services() here, the message will
1839 * cause this to be done before the next packet is read
1840 * from the client. JRA.
1843 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1845 return WERR_OK;
1848 /*******************************************************************
1849 _srvsvc_NetShareDel
1850 Call "delete share command" with the share name as
1851 a parameter.
1852 ********************************************************************/
1854 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1855 struct srvsvc_NetShareDel *r)
1857 struct current_user user;
1858 char *command = NULL;
1859 char *share_name = NULL;
1860 int ret;
1861 int snum;
1862 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1863 bool is_disk_op;
1864 struct share_params *params;
1865 TALLOC_CTX *ctx = p->mem_ctx;
1867 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1869 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1870 if (!share_name) {
1871 return WERR_NET_NAME_NOT_FOUND;
1873 if ( strequal(share_name,"IPC$")
1874 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1875 || strequal(share_name,"global") )
1877 return WERR_ACCESS_DENIED;
1880 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1881 return WERR_NO_SUCH_SHARE;
1884 snum = find_service(share_name);
1886 /* No change to printer shares. */
1887 if (lp_print_ok(snum))
1888 return WERR_ACCESS_DENIED;
1890 get_current_user(&user,p);
1892 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1894 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1895 return WERR_ACCESS_DENIED;
1897 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1898 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1899 return WERR_ACCESS_DENIED;
1902 command = talloc_asprintf(ctx,
1903 "%s \"%s\" \"%s\"",
1904 lp_delete_share_cmd(),
1905 get_dyn_CONFIGFILE(),
1906 lp_servicename(snum));
1907 if (!command) {
1908 return WERR_NOMEM;
1911 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1913 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1915 if ( is_disk_op )
1916 become_root();
1918 if ( (ret = smbrun(command, NULL)) == 0 ) {
1919 /* Tell everyone we updated smb.conf. */
1920 message_send_all(smbd_messaging_context(),
1921 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1924 if ( is_disk_op )
1925 unbecome_root();
1927 /********* END SeDiskOperatorPrivilege BLOCK *********/
1929 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1931 if ( ret != 0 )
1932 return WERR_ACCESS_DENIED;
1934 /* Delete the SD in the database. */
1935 delete_share_security(lp_servicename(params->service));
1937 lp_killservice(params->service);
1939 return WERR_OK;
1942 /*******************************************************************
1943 _srvsvc_NetShareDelSticky
1944 ********************************************************************/
1946 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1947 struct srvsvc_NetShareDelSticky *r)
1949 struct srvsvc_NetShareDel q;
1951 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1953 q.in.server_unc = r->in.server_unc;
1954 q.in.share_name = r->in.share_name;
1955 q.in.reserved = r->in.reserved;
1957 return _srvsvc_NetShareDel(p, &q);
1960 /*******************************************************************
1961 _srvsvc_NetRemoteTOD
1962 ********************************************************************/
1964 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1965 struct srvsvc_NetRemoteTOD *r)
1967 struct srvsvc_NetRemoteTODInfo *tod;
1968 struct tm *t;
1969 time_t unixdate = time(NULL);
1971 /* We do this call first as if we do it *after* the gmtime call
1972 it overwrites the pointed-to values. JRA */
1974 uint32 zone = get_time_zone(unixdate)/60;
1976 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1978 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1979 return WERR_NOMEM;
1981 *r->out.info = tod;
1983 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1985 t = gmtime(&unixdate);
1987 /* set up the */
1988 init_srvsvc_NetRemoteTODInfo(tod,
1989 unixdate,
1991 t->tm_hour,
1992 t->tm_min,
1993 t->tm_sec,
1995 zone,
1996 10000,
1997 t->tm_mday,
1998 t->tm_mon + 1,
1999 1900+t->tm_year,
2000 t->tm_wday);
2002 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2004 return WERR_OK;
2007 /***********************************************************************************
2008 _srvsvc_NetGetFileSecurity
2009 Win9x NT tools get security descriptor.
2010 ***********************************************************************************/
2012 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2013 struct srvsvc_NetGetFileSecurity *r)
2015 SEC_DESC *psd = NULL;
2016 size_t sd_size;
2017 DATA_BLOB null_pw;
2018 char *filename_in = NULL;
2019 char *filename = NULL;
2020 char *qualname = NULL;
2021 SMB_STRUCT_STAT st;
2022 NTSTATUS nt_status;
2023 WERROR werr;
2024 struct current_user user;
2025 connection_struct *conn = NULL;
2026 bool became_user = False;
2027 TALLOC_CTX *ctx = p->mem_ctx;
2028 struct sec_desc_buf *sd_buf;
2030 ZERO_STRUCT(st);
2032 werr = WERR_OK;
2034 qualname = talloc_strdup(ctx, r->in.share);
2035 if (!qualname) {
2036 werr = WERR_ACCESS_DENIED;
2037 goto error_exit;
2040 /* Null password is ok - we are already an authenticated user... */
2041 null_pw = data_blob_null;
2043 get_current_user(&user, p);
2045 become_root();
2046 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2047 unbecome_root();
2049 if (conn == NULL) {
2050 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2051 qualname));
2052 werr = ntstatus_to_werror(nt_status);
2053 goto error_exit;
2056 if (!become_user(conn, conn->vuid)) {
2057 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2058 werr = WERR_ACCESS_DENIED;
2059 goto error_exit;
2061 became_user = True;
2063 filename_in = talloc_strdup(ctx, r->in.file);
2064 if (!filename_in) {
2065 werr = WERR_ACCESS_DENIED;
2066 goto error_exit;
2069 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2070 if (!NT_STATUS_IS_OK(nt_status)) {
2071 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2072 filename));
2073 werr = WERR_ACCESS_DENIED;
2074 goto error_exit;
2077 nt_status = check_name(conn, filename);
2078 if (!NT_STATUS_IS_OK(nt_status)) {
2079 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2080 filename));
2081 werr = WERR_ACCESS_DENIED;
2082 goto error_exit;
2085 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2086 (OWNER_SECURITY_INFORMATION
2087 |GROUP_SECURITY_INFORMATION
2088 |DACL_SECURITY_INFORMATION), &psd);
2090 if (!NT_STATUS_IS_OK(nt_status)) {
2091 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2092 filename));
2093 werr = ntstatus_to_werror(nt_status);
2094 goto error_exit;
2097 sd_size = ndr_size_security_descriptor(psd, 0);
2099 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2100 if (!sd_buf) {
2101 werr = WERR_NOMEM;
2102 goto error_exit;
2105 sd_buf->sd_size = sd_size;
2106 sd_buf->sd = psd;
2108 *r->out.sd_buf = sd_buf;
2110 psd->dacl->revision = NT4_ACL_REVISION;
2112 unbecome_user();
2113 close_cnum(conn, user.vuid);
2114 return werr;
2116 error_exit:
2118 if (became_user)
2119 unbecome_user();
2121 if (conn)
2122 close_cnum(conn, user.vuid);
2124 return werr;
2127 /***********************************************************************************
2128 _srvsvc_NetSetFileSecurity
2129 Win9x NT tools set security descriptor.
2130 ***********************************************************************************/
2132 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2133 struct srvsvc_NetSetFileSecurity *r)
2135 char *filename_in = NULL;
2136 char *filename = NULL;
2137 char *qualname = NULL;
2138 DATA_BLOB null_pw;
2139 files_struct *fsp = NULL;
2140 SMB_STRUCT_STAT st;
2141 NTSTATUS nt_status;
2142 WERROR werr;
2143 struct current_user user;
2144 connection_struct *conn = NULL;
2145 bool became_user = False;
2146 TALLOC_CTX *ctx = p->mem_ctx;
2148 ZERO_STRUCT(st);
2150 werr = WERR_OK;
2152 qualname = talloc_strdup(ctx, r->in.share);
2153 if (!qualname) {
2154 werr = WERR_ACCESS_DENIED;
2155 goto error_exit;
2158 /* Null password is ok - we are already an authenticated user... */
2159 null_pw = data_blob_null;
2161 get_current_user(&user, p);
2163 become_root();
2164 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2165 unbecome_root();
2167 if (conn == NULL) {
2168 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2169 werr = ntstatus_to_werror(nt_status);
2170 goto error_exit;
2173 if (!become_user(conn, conn->vuid)) {
2174 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2175 werr = WERR_ACCESS_DENIED;
2176 goto error_exit;
2178 became_user = True;
2180 filename_in = talloc_strdup(ctx, r->in.file);
2181 if (!filename_in) {
2182 werr = WERR_ACCESS_DENIED;
2183 goto error_exit;
2186 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2187 if (!NT_STATUS_IS_OK(nt_status)) {
2188 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2189 werr = WERR_ACCESS_DENIED;
2190 goto error_exit;
2193 nt_status = check_name(conn, filename);
2194 if (!NT_STATUS_IS_OK(nt_status)) {
2195 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2196 werr = WERR_ACCESS_DENIED;
2197 goto error_exit;
2200 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2202 if ( !NT_STATUS_IS_OK(nt_status) ) {
2203 /* Perhaps it is a directory */
2204 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2205 nt_status = open_directory(conn, NULL, filename, &st,
2206 FILE_READ_ATTRIBUTES,
2207 FILE_SHARE_READ|FILE_SHARE_WRITE,
2208 FILE_OPEN,
2210 FILE_ATTRIBUTE_DIRECTORY,
2211 NULL, &fsp);
2213 if ( !NT_STATUS_IS_OK(nt_status) ) {
2214 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2215 werr = ntstatus_to_werror(nt_status);
2216 goto error_exit;
2220 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2221 r->in.securityinformation,
2222 r->in.sd_buf->sd);
2224 if (!NT_STATUS_IS_OK(nt_status) ) {
2225 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2226 werr = WERR_ACCESS_DENIED;
2227 goto error_exit;
2230 close_file(fsp, NORMAL_CLOSE);
2231 unbecome_user();
2232 close_cnum(conn, user.vuid);
2233 return werr;
2235 error_exit:
2237 if(fsp) {
2238 close_file(fsp, NORMAL_CLOSE);
2241 if (became_user) {
2242 unbecome_user();
2245 if (conn) {
2246 close_cnum(conn, user.vuid);
2249 return werr;
2252 /***********************************************************************************
2253 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2254 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2255 These disks would the disks listed by this function.
2256 Users could then create shares relative to these disks. Watch out for moving these disks around.
2257 "Nigel Williams" <nigel@veritas.com>.
2258 ***********************************************************************************/
2260 static const char *server_disks[] = {"C:"};
2262 static uint32 get_server_disk_count(void)
2264 return sizeof(server_disks)/sizeof(server_disks[0]);
2267 static uint32 init_server_disk_enum(uint32 *resume)
2269 uint32 server_disk_count = get_server_disk_count();
2271 /*resume can be an offset into the list for now*/
2273 if(*resume & 0x80000000)
2274 *resume = 0;
2276 if(*resume > server_disk_count)
2277 *resume = server_disk_count;
2279 return server_disk_count - *resume;
2282 static const char *next_server_disk_enum(uint32 *resume)
2284 const char *disk;
2286 if(init_server_disk_enum(resume) == 0)
2287 return NULL;
2289 disk = server_disks[*resume];
2291 (*resume)++;
2293 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2295 return disk;
2298 /********************************************************************
2299 _srvsvc_NetDiskEnum
2300 ********************************************************************/
2302 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2303 struct srvsvc_NetDiskEnum *r)
2305 uint32 i;
2306 const char *disk_name;
2307 TALLOC_CTX *ctx = p->mem_ctx;
2308 WERROR werr;
2309 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2311 werr = WERR_OK;
2313 *r->out.totalentries = init_server_disk_enum(&resume);
2315 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2316 MAX_SERVER_DISK_ENTRIES);
2317 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2319 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2321 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2323 r->out.info->count++;
2325 /*copy disk name into a unicode string*/
2327 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2328 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2331 /* add a terminating null string. Is this there if there is more data to come? */
2333 r->out.info->count++;
2335 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2336 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2338 if (r->out.resume_handle) {
2339 *r->out.resume_handle = resume;
2342 return werr;
2345 /********************************************************************
2346 _srvsvc_NetNameValidate
2347 ********************************************************************/
2349 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2350 struct srvsvc_NetNameValidate *r)
2352 switch (r->in.name_type) {
2353 case 0x9:
2354 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2355 strlen_m(r->in.name)))
2357 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2358 r->in.name));
2359 return WERR_INVALID_NAME;
2361 break;
2363 default:
2364 return WERR_UNKNOWN_LEVEL;
2367 return WERR_OK;
2370 /********************************************************************
2371 ********************************************************************/
2373 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2375 return WERR_ACCESS_DENIED;
2379 /********************************************************************
2380 ********************************************************************/
2382 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2384 p->rng_fault_state = True;
2385 return WERR_NOT_SUPPORTED;
2388 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2390 p->rng_fault_state = True;
2391 return WERR_NOT_SUPPORTED;
2394 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2396 p->rng_fault_state = True;
2397 return WERR_NOT_SUPPORTED;
2400 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2402 p->rng_fault_state = True;
2403 return WERR_NOT_SUPPORTED;
2406 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2408 p->rng_fault_state = True;
2409 return WERR_NOT_SUPPORTED;
2412 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2414 p->rng_fault_state = True;
2415 return WERR_NOT_SUPPORTED;
2418 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2420 p->rng_fault_state = True;
2421 return WERR_NOT_SUPPORTED;
2424 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2426 p->rng_fault_state = True;
2427 return WERR_NOT_SUPPORTED;
2430 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2432 p->rng_fault_state = True;
2433 return WERR_NOT_SUPPORTED;
2436 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2438 p->rng_fault_state = True;
2439 return WERR_NOT_SUPPORTED;
2442 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2444 p->rng_fault_state = True;
2445 return WERR_NOT_SUPPORTED;
2448 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2450 p->rng_fault_state = True;
2451 return WERR_NOT_SUPPORTED;
2454 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2456 p->rng_fault_state = True;
2457 return WERR_NOT_SUPPORTED;
2460 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2462 p->rng_fault_state = True;
2463 return WERR_NOT_SUPPORTED;
2466 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2468 p->rng_fault_state = True;
2469 return WERR_NOT_SUPPORTED;
2472 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2474 p->rng_fault_state = True;
2475 return WERR_NOT_SUPPORTED;
2478 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2480 p->rng_fault_state = True;
2481 return WERR_NOT_SUPPORTED;
2484 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2486 p->rng_fault_state = True;
2487 return WERR_NOT_SUPPORTED;
2490 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2492 p->rng_fault_state = True;
2493 return WERR_NOT_SUPPORTED;
2496 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2498 p->rng_fault_state = True;
2499 return WERR_NOT_SUPPORTED;
2502 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2504 p->rng_fault_state = True;
2505 return WERR_NOT_SUPPORTED;
2508 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2510 p->rng_fault_state = True;
2511 return WERR_NOT_SUPPORTED;
2514 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2516 p->rng_fault_state = True;
2517 return WERR_NOT_SUPPORTED;
2520 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2522 p->rng_fault_state = True;
2523 return WERR_NOT_SUPPORTED;
2526 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2528 p->rng_fault_state = True;
2529 return WERR_NOT_SUPPORTED;
2532 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2534 p->rng_fault_state = True;
2535 return WERR_NOT_SUPPORTED;
2538 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2540 p->rng_fault_state = True;
2541 return WERR_NOT_SUPPORTED;
2544 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2546 p->rng_fault_state = True;
2547 return WERR_NOT_SUPPORTED;
2550 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2552 p->rng_fault_state = True;
2553 return WERR_NOT_SUPPORTED;
2556 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2558 p->rng_fault_state = True;
2559 return WERR_NOT_SUPPORTED;
2562 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2564 p->rng_fault_state = True;
2565 return WERR_NOT_SUPPORTED;
2568 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2570 p->rng_fault_state = True;
2571 return WERR_NOT_SUPPORTED;
2574 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2576 p->rng_fault_state = True;
2577 return WERR_NOT_SUPPORTED;
2580 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2582 p->rng_fault_state = True;
2583 return WERR_NOT_SUPPORTED;
2586 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2588 p->rng_fault_state = True;
2589 return WERR_NOT_SUPPORTED;