packaging(RHEL): remove duplicate installation of pam_smbpass.so
[Samba.git] / source / rpc_server / srv_srvsvc_nt.c
blob3672219dec4f0c8c8f955e82bb62807122566592
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 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
92 (((uint32_t)(procid_to_pid(&prec.pid))<<16) | prec.pnum),
93 (FILE_READ_DATA|FILE_WRITE_DATA),
95 fullpath,
96 username);
98 fenum->ctr3->count++;
100 return 0;
103 /*******************************************************************
104 ********************************************************************/
106 static WERROR net_enum_pipes(TALLOC_CTX *ctx,
107 const char *username,
108 struct srvsvc_NetFileCtr3 **ctr3,
109 uint32_t resume )
111 struct file_enum_count fenum;
113 fenum.ctx = ctx;
114 fenum.username = username;
115 fenum.ctr3 = *ctr3;
117 if (connections_traverse(pipe_enum_fn, &fenum) == -1) {
118 DEBUG(0,("net_enum_pipes: traverse of connections.tdb "
119 "failed\n"));
120 return WERR_NOMEM;
123 *ctr3 = fenum.ctr3;
125 return WERR_OK;
128 /*******************************************************************
129 ********************************************************************/
131 static void enum_file_fn( const struct share_mode_entry *e,
132 const char *sharepath, const char *fname,
133 void *private_data )
135 struct file_enum_count *fenum =
136 (struct file_enum_count *)private_data;
138 struct srvsvc_NetFileInfo3 *f;
139 int i = fenum->ctr3->count;
140 files_struct fsp;
141 struct byte_range_lock *brl;
142 int num_locks = 0;
143 char *fullpath = NULL;
144 uint32 permissions;
145 const char *username;
147 /* If the pid was not found delete the entry from connections.tdb */
149 if ( !process_exists(e->pid) ) {
150 return;
153 username = uidtoname(e->uid);
155 if ((fenum->username != NULL)
156 && !strequal(username, fenum->username)) {
157 return;
160 f = TALLOC_REALLOC_ARRAY(fenum->ctx, fenum->ctr3->array,
161 struct srvsvc_NetFileInfo3, i+1);
162 if ( !f ) {
163 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
164 return;
166 fenum->ctr3->array = f;
168 /* need to count the number of locks on a file */
170 ZERO_STRUCT( fsp );
171 fsp.file_id = e->id;
173 if ( (brl = brl_get_locks(talloc_tos(), &fsp)) != NULL ) {
174 num_locks = brl->num_locks;
175 TALLOC_FREE(brl);
178 if ( strcmp( fname, "." ) == 0 ) {
179 fullpath = talloc_asprintf(fenum->ctx, "C:%s", sharepath );
180 } else {
181 fullpath = talloc_asprintf(fenum->ctx, "C:%s/%s",
182 sharepath, fname );
184 if (!fullpath) {
185 return;
187 string_replace( fullpath, '/', '\\' );
189 /* mask out create (what ever that is) */
190 permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
192 /* now fill in the srvsvc_NetFileInfo3 struct */
193 init_srvsvc_NetFileInfo3(&fenum->ctr3->array[i],
194 (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id),
195 permissions,
196 num_locks,
197 fullpath,
198 username);
199 fenum->ctr3->count++;
202 /*******************************************************************
203 ********************************************************************/
205 static WERROR net_enum_files(TALLOC_CTX *ctx,
206 const char *username,
207 struct srvsvc_NetFileCtr3 **ctr3,
208 uint32_t resume)
210 struct file_enum_count f_enum_cnt;
212 f_enum_cnt.ctx = ctx;
213 f_enum_cnt.username = username;
214 f_enum_cnt.ctr3 = *ctr3;
216 share_mode_forall( enum_file_fn, (void *)&f_enum_cnt );
218 *ctr3 = f_enum_cnt.ctr3;
220 return WERR_OK;
223 /*******************************************************************
224 Utility function to get the 'type' of a share from an snum.
225 ********************************************************************/
226 static uint32 get_share_type(int snum)
228 /* work out the share type */
229 uint32 type = STYPE_DISKTREE;
231 if (lp_print_ok(snum))
232 type = STYPE_PRINTQ;
233 if (strequal(lp_fstype(snum), "IPC"))
234 type = STYPE_IPC;
235 if (lp_administrative_share(snum))
236 type |= STYPE_HIDDEN;
238 return type;
241 /*******************************************************************
242 Fill in a share info level 0 structure.
243 ********************************************************************/
245 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *r, int snum)
247 const char *net_name = lp_servicename(snum);
249 init_srvsvc_NetShareInfo0(r, net_name);
252 /*******************************************************************
253 Fill in a share info level 1 structure.
254 ********************************************************************/
256 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *r, int snum)
258 char *net_name = lp_servicename(snum);
259 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
261 if (remark) {
262 remark = standard_sub_conn(p->mem_ctx,
263 p->conn,
264 remark);
267 init_srvsvc_NetShareInfo1(r, net_name,
268 get_share_type(snum),
269 remark ? remark : "");
272 /*******************************************************************
273 Fill in a share info level 2 structure.
274 ********************************************************************/
276 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *r, int snum)
278 char *remark = NULL;
279 char *path = NULL;
280 int max_connections = lp_max_connections(snum);
281 uint32_t max_uses = max_connections!=0 ? max_connections : (uint32_t)-1;
282 int count = 0;
283 char *net_name = lp_servicename(snum);
285 remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
286 if (remark) {
287 remark = standard_sub_conn(p->mem_ctx,
288 p->conn,
289 remark);
291 path = talloc_asprintf(p->mem_ctx,
292 "C:%s", lp_pathname(snum));
294 if (path) {
296 * Change / to \\ so that win2k will see it as a valid path.
297 * This was added to enable use of browsing in win2k add
298 * share dialog.
301 string_replace(path, '/', '\\');
304 count = count_current_connections(net_name, false);
306 init_srvsvc_NetShareInfo2(r, net_name,
307 get_share_type(snum),
308 remark ? remark : "",
310 max_uses,
311 count,
312 path ? path : "",
313 "");
316 /*******************************************************************
317 Map any generic bits to file specific bits.
318 ********************************************************************/
320 static void map_generic_share_sd_bits(SEC_DESC *psd)
322 int i;
323 SEC_ACL *ps_dacl = NULL;
325 if (!psd)
326 return;
328 ps_dacl = psd->dacl;
329 if (!ps_dacl)
330 return;
332 for (i = 0; i < ps_dacl->num_aces; i++) {
333 SEC_ACE *psa = &ps_dacl->aces[i];
334 uint32 orig_mask = psa->access_mask;
336 se_map_generic(&psa->access_mask, &file_generic_mapping);
337 psa->access_mask |= orig_mask;
341 /*******************************************************************
342 Fill in a share info level 501 structure.
343 ********************************************************************/
345 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *r, int snum)
347 const char *net_name = lp_servicename(snum);
348 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
350 if (remark) {
351 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
354 init_srvsvc_NetShareInfo501(r, net_name,
355 get_share_type(snum),
356 remark ? remark : "",
357 (lp_csc_policy(snum) << 4));
360 /*******************************************************************
361 Fill in a share info level 502 structure.
362 ********************************************************************/
364 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *r, int snum)
366 const char *net_name = lp_servicename(snum);
367 char *path = NULL;
368 SEC_DESC *sd = NULL;
369 struct sec_desc_buf *sd_buf = NULL;
370 size_t sd_size = 0;
371 TALLOC_CTX *ctx = p->mem_ctx;
372 char *remark = talloc_strdup(ctx, lp_comment(snum));;
374 if (remark) {
375 remark = standard_sub_conn(ctx, p->conn, remark);
377 path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
378 if (path) {
380 * Change / to \\ so that win2k will see it as a valid path. This was added to
381 * enable use of browsing in win2k add share dialog.
383 string_replace(path, '/', '\\');
386 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
388 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
390 init_srvsvc_NetShareInfo502(r, net_name,
391 get_share_type(snum),
392 remark ? remark : "",
394 (uint32_t)-1,
396 path ? path : "",
398 sd_buf);
401 /***************************************************************************
402 Fill in a share info level 1004 structure.
403 ***************************************************************************/
405 static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo1004 *r, int snum)
407 char *remark = talloc_strdup(p->mem_ctx, lp_comment(snum));
409 if (remark) {
410 remark = standard_sub_conn(p->mem_ctx, p->conn, remark);
413 init_srvsvc_NetShareInfo1004(r, remark ? remark : "");
416 /***************************************************************************
417 Fill in a share info level 1005 structure.
418 ***************************************************************************/
420 static void init_srv_share_info_1005(pipes_struct *p, struct srvsvc_NetShareInfo1005 *r, int snum)
422 uint32_t dfs_flags = 0;
424 if (lp_host_msdfs() && lp_msdfs_root(snum)) {
425 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
428 dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
430 init_srvsvc_NetShareInfo1005(r, dfs_flags);
433 /***************************************************************************
434 Fill in a share info level 1006 structure.
435 ***************************************************************************/
437 static void init_srv_share_info_1006(pipes_struct *p, struct srvsvc_NetShareInfo1006 *r, int snum)
439 init_srvsvc_NetShareInfo1006(r, (uint32_t)-1);
442 /***************************************************************************
443 Fill in a share info level 1007 structure.
444 ***************************************************************************/
446 static void init_srv_share_info_1007(pipes_struct *p, struct srvsvc_NetShareInfo1007 *r, int snum)
448 uint32 flags = 0;
450 init_srvsvc_NetShareInfo1007(r, flags, "");
453 /*******************************************************************
454 Fill in a share info level 1501 structure.
455 ********************************************************************/
457 static void init_srv_share_info_1501(pipes_struct *p, struct sec_desc_buf *r, int snum)
459 SEC_DESC *sd;
460 size_t sd_size;
461 TALLOC_CTX *ctx = p->mem_ctx;
463 sd = get_share_security(ctx, lp_servicename(snum), &sd_size);
465 r = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
468 /*******************************************************************
469 True if it ends in '$'.
470 ********************************************************************/
472 static bool is_hidden_share(int snum)
474 const char *net_name = lp_servicename(snum);
476 return (net_name[strlen(net_name) - 1] == '$') ? True : False;
479 /*******************************************************************
480 Fill in a share info structure.
481 ********************************************************************/
483 static WERROR init_srv_share_info_ctr(pipes_struct *p,
484 struct srvsvc_NetShareInfoCtr *info_ctr,
485 uint32_t *resume_handle_p,
486 uint32_t *total_entries,
487 bool all_shares)
489 int num_entries = 0;
490 int alloc_entries = 0;
491 int num_services = 0;
492 int snum;
493 TALLOC_CTX *ctx = p->mem_ctx;
494 int i = 0;
495 int valid_share_count = 0;
496 union srvsvc_NetShareCtr ctr;
497 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
499 DEBUG(5,("init_srv_share_info_ctr\n"));
501 /* Ensure all the usershares are loaded. */
502 become_root();
503 load_usershare_shares();
504 load_registry_shares();
505 num_services = lp_numservices();
506 unbecome_root();
508 /* Count the number of entries. */
509 for (snum = 0; snum < num_services; snum++) {
510 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) {
511 DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
512 num_entries++;
513 } else {
514 DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
518 if (!num_entries || (resume_handle >= num_entries)) {
519 return WERR_OK;
522 /* Calculate alloc entries. */
523 alloc_entries = num_entries - resume_handle;
524 switch (info_ctr->level) {
525 case 0:
526 ctr.ctr0 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr0);
527 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0);
529 ctr.ctr0->count = alloc_entries;
530 ctr.ctr0->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
531 W_ERROR_HAVE_NO_MEMORY(ctr.ctr0->array);
533 for (snum = 0; snum < num_services; snum++) {
534 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
535 (resume_handle <= (i + valid_share_count++)) ) {
536 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
540 break;
542 case 1:
543 ctr.ctr1 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1);
544 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1);
546 ctr.ctr1->count = alloc_entries;
547 ctr.ctr1->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
548 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1->array);
550 for (snum = 0; snum < num_services; snum++) {
551 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
552 (resume_handle <= (i + valid_share_count++)) ) {
553 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
557 break;
559 case 2:
560 ctr.ctr2 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr2);
561 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2);
563 ctr.ctr2->count = alloc_entries;
564 ctr.ctr2->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
565 W_ERROR_HAVE_NO_MEMORY(ctr.ctr2->array);
567 for (snum = 0; snum < num_services; snum++) {
568 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
569 (resume_handle <= (i + valid_share_count++)) ) {
570 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
574 break;
576 case 501:
577 ctr.ctr501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr501);
578 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501);
580 ctr.ctr501->count = alloc_entries;
581 ctr.ctr501->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
582 W_ERROR_HAVE_NO_MEMORY(ctr.ctr501->array);
584 for (snum = 0; snum < num_services; snum++) {
585 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
586 (resume_handle <= (i + valid_share_count++)) ) {
587 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
591 break;
593 case 502:
594 ctr.ctr502 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr502);
595 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502);
597 ctr.ctr502->count = alloc_entries;
598 ctr.ctr502->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
599 W_ERROR_HAVE_NO_MEMORY(ctr.ctr502->array);
601 for (snum = 0; snum < num_services; snum++) {
602 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
603 (resume_handle <= (i + valid_share_count++)) ) {
604 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
608 break;
610 case 1004:
611 ctr.ctr1004 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1004);
612 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004);
614 ctr.ctr1004->count = alloc_entries;
615 ctr.ctr1004->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
616 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1004->array);
618 for (snum = 0; snum < num_services; snum++) {
619 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
620 (resume_handle <= (i + valid_share_count++)) ) {
621 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
625 break;
627 case 1005:
628 ctr.ctr1005 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1005);
629 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005);
631 ctr.ctr1005->count = alloc_entries;
632 ctr.ctr1005->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
633 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1005->array);
635 for (snum = 0; snum < num_services; snum++) {
636 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
637 (resume_handle <= (i + valid_share_count++)) ) {
638 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
642 break;
644 case 1006:
645 ctr.ctr1006 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1006);
646 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006);
648 ctr.ctr1006->count = alloc_entries;
649 ctr.ctr1006->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
650 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1006->array);
652 for (snum = 0; snum < num_services; snum++) {
653 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
654 (resume_handle <= (i + valid_share_count++)) ) {
655 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
659 break;
661 case 1007:
662 ctr.ctr1007 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1007);
663 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007);
665 ctr.ctr1007->count = alloc_entries;
666 ctr.ctr1007->array = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
667 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1007->array);
669 for (snum = 0; snum < num_services; snum++) {
670 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
671 (resume_handle <= (i + valid_share_count++)) ) {
672 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
676 break;
678 case 1501:
679 ctr.ctr1501 = TALLOC_ZERO_P(ctx, struct srvsvc_NetShareCtr1501);
680 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501);
682 ctr.ctr1501->count = alloc_entries;
683 ctr.ctr1501->array = TALLOC_ZERO_ARRAY(ctx, struct sec_desc_buf, alloc_entries);
684 W_ERROR_HAVE_NO_MEMORY(ctr.ctr1501->array);
686 for (snum = 0; snum < num_services; snum++) {
687 if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) &&
688 (resume_handle <= (i + valid_share_count++)) ) {
689 init_srv_share_info_1501(p, &ctr.ctr1501->array[i++], snum);
693 break;
695 default:
696 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
697 info_ctr->level));
698 return WERR_UNKNOWN_LEVEL;
701 *total_entries = alloc_entries;
702 if (resume_handle_p) {
703 if (all_shares) {
704 *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
705 } else {
706 *resume_handle_p = num_entries;
710 info_ctr->ctr = ctr;
712 return WERR_OK;
715 /*******************************************************************
716 fill in a sess info level 0 structure.
717 ********************************************************************/
719 static WERROR init_srv_sess_info_0(pipes_struct *p,
720 struct srvsvc_NetSessCtr0 *ctr0,
721 uint32_t *resume_handle_p,
722 uint32_t *total_entries)
724 struct sessionid *session_list;
725 uint32_t num_entries = 0;
726 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
727 *total_entries = list_sessions(p->mem_ctx, &session_list);
729 DEBUG(5,("init_srv_sess_info_0\n"));
731 if (ctr0 == NULL) {
732 if (resume_handle_p) {
733 *resume_handle_p = 0;
735 return WERR_OK;
738 for (; resume_handle < *total_entries; resume_handle++) {
740 ctr0->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
741 ctr0->array,
742 struct srvsvc_NetSessInfo0,
743 num_entries+1);
744 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
746 init_srvsvc_NetSessInfo0(&ctr0->array[num_entries],
747 session_list[resume_handle].remote_machine);
748 num_entries++;
751 ctr0->count = num_entries;
753 if (resume_handle_p) {
754 if (*resume_handle_p >= *total_entries) {
755 *resume_handle_p = 0;
756 } else {
757 *resume_handle_p = resume_handle;
761 return WERR_OK;
764 /*******************************************************************
765 ********************************************************************/
767 static void sess_file_fn( const struct share_mode_entry *e,
768 const char *sharepath, const char *fname,
769 void *data )
771 struct sess_file_count *sess = (struct sess_file_count *)data;
773 if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
774 sess->count++;
777 return;
780 /*******************************************************************
781 ********************************************************************/
783 static int net_count_files( uid_t uid, struct server_id pid )
785 struct sess_file_count s_file_cnt;
787 s_file_cnt.count = 0;
788 s_file_cnt.uid = uid;
789 s_file_cnt.pid = pid;
791 share_mode_forall( sess_file_fn, &s_file_cnt );
793 return s_file_cnt.count;
796 /*******************************************************************
797 fill in a sess info level 1 structure.
798 ********************************************************************/
800 static WERROR init_srv_sess_info_1(pipes_struct *p,
801 struct srvsvc_NetSessCtr1 *ctr1,
802 uint32_t *resume_handle_p,
803 uint32_t *total_entries)
805 struct sessionid *session_list;
806 uint32_t num_entries = 0;
807 time_t now = time(NULL);
808 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
810 ZERO_STRUCTP(ctr1);
812 if (ctr1 == NULL) {
813 if (resume_handle_p) {
814 *resume_handle_p = 0;
816 return WERR_OK;
819 *total_entries = list_sessions(p->mem_ctx, &session_list);
821 for (; resume_handle < *total_entries; resume_handle++) {
822 uint32 num_files;
823 uint32 connect_time;
824 struct passwd *pw = sys_getpwnam(session_list[resume_handle].username);
825 bool guest;
827 if ( !pw ) {
828 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
829 session_list[resume_handle].username));
830 continue;
833 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
834 num_files = net_count_files(pw->pw_uid, session_list[resume_handle].pid);
835 guest = strequal( session_list[resume_handle].username, lp_guestaccount() );
837 ctr1->array = TALLOC_REALLOC_ARRAY(p->mem_ctx,
838 ctr1->array,
839 struct srvsvc_NetSessInfo1,
840 num_entries+1);
841 W_ERROR_HAVE_NO_MEMORY(ctr1->array);
843 init_srvsvc_NetSessInfo1(&ctr1->array[num_entries],
844 session_list[resume_handle].remote_machine,
845 session_list[resume_handle].username,
846 num_files,
847 connect_time,
849 guest);
850 num_entries++;
853 ctr1->count = num_entries;
855 if (resume_handle_p) {
856 if (*resume_handle_p >= *total_entries) {
857 *resume_handle_p = 0;
858 } else {
859 *resume_handle_p = resume_handle;
863 return WERR_OK;
866 /*******************************************************************
867 fill in a conn info level 0 structure.
868 ********************************************************************/
870 static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
871 uint32_t *resume_handle_p,
872 uint32_t *total_entries)
874 uint32_t num_entries = 0;
875 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
877 DEBUG(5,("init_srv_conn_info_0\n"));
879 if (ctr0 == NULL) {
880 if (resume_handle_p) {
881 *resume_handle_p = 0;
883 return WERR_OK;
886 *total_entries = 1;
888 ZERO_STRUCTP(ctr0);
890 for (; resume_handle < *total_entries; resume_handle++) {
892 ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
893 ctr0->array,
894 struct srvsvc_NetConnInfo0,
895 num_entries+1);
896 if (!ctr0->array) {
897 return WERR_NOMEM;
900 init_srvsvc_NetConnInfo0(&ctr0->array[num_entries],
901 (*total_entries));
903 /* move on to creating next connection */
904 num_entries++;
907 ctr0->count = num_entries;
908 *total_entries = num_entries;
910 if (resume_handle_p) {
911 if (*resume_handle_p >= *total_entries) {
912 *resume_handle_p = 0;
913 } else {
914 *resume_handle_p = resume_handle;
918 return WERR_OK;
921 /*******************************************************************
922 fill in a conn info level 1 structure.
923 ********************************************************************/
925 static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
926 uint32_t *resume_handle_p,
927 uint32_t *total_entries)
929 uint32_t num_entries = 0;
930 uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
932 DEBUG(5,("init_srv_conn_info_1\n"));
934 if (ctr1 == NULL) {
935 if (resume_handle_p) {
936 *resume_handle_p = 0;
938 return WERR_OK;
941 *total_entries = 1;
943 ZERO_STRUCTP(ctr1);
945 for (; resume_handle < *total_entries; resume_handle++) {
947 ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
948 ctr1->array,
949 struct srvsvc_NetConnInfo1,
950 num_entries+1);
951 if (!ctr1->array) {
952 return WERR_NOMEM;
955 init_srvsvc_NetConnInfo1(&ctr1->array[num_entries],
956 (*total_entries),
957 0x3,
961 "dummy_user",
962 "IPC$");
964 /* move on to creating next connection */
965 num_entries++;
968 ctr1->count = num_entries;
969 *total_entries = num_entries;
971 if (resume_handle_p) {
972 if (*resume_handle_p >= *total_entries) {
973 *resume_handle_p = 0;
974 } else {
975 *resume_handle_p = resume_handle;
979 return WERR_OK;
982 /*******************************************************************
983 _srvsvc_NetFileEnum
984 *******************************************************************/
986 WERROR _srvsvc_NetFileEnum(pipes_struct *p,
987 struct srvsvc_NetFileEnum *r)
989 TALLOC_CTX *ctx = NULL;
990 struct srvsvc_NetFileCtr3 *ctr3;
991 uint32_t resume_hnd = 0;
992 WERROR werr;
994 switch (r->in.info_ctr->level) {
995 case 3:
996 break;
997 default:
998 return WERR_UNKNOWN_LEVEL;
1001 ctx = talloc_tos();
1002 ctr3 = r->in.info_ctr->ctr.ctr3;
1003 if (!ctr3) {
1004 werr = WERR_INVALID_PARAM;
1005 goto done;
1008 /* TODO -- Windows enumerates
1009 (b) active pipes
1010 (c) open directories and files */
1012 werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
1013 if (!W_ERROR_IS_OK(werr)) {
1014 goto done;
1017 werr = net_enum_pipes(ctx, r->in.user, &ctr3, resume_hnd);
1018 if (!W_ERROR_IS_OK(werr)) {
1019 goto done;
1022 *r->out.totalentries = ctr3->count;
1023 r->out.info_ctr->ctr.ctr3->array = ctr3->array;
1024 r->out.info_ctr->ctr.ctr3->count = ctr3->count;
1026 werr = WERR_OK;
1028 done:
1029 return werr;
1032 /*******************************************************************
1033 _srvsvc_NetSrvGetInfo
1034 ********************************************************************/
1036 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p,
1037 struct srvsvc_NetSrvGetInfo *r)
1039 WERROR status = WERR_OK;
1041 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1043 if (!pipe_access_check(p)) {
1044 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
1045 return WERR_ACCESS_DENIED;
1048 switch (r->in.level) {
1050 /* Technically level 102 should only be available to
1051 Administrators but there isn't anything super-secret
1052 here, as most of it is made up. */
1054 case 102: {
1055 struct srvsvc_NetSrvInfo102 *info102;
1057 info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1058 if (!info102) {
1059 return WERR_NOMEM;
1062 init_srvsvc_NetSrvInfo102(info102,
1063 PLATFORM_ID_NT,
1064 global_myname(),
1065 lp_major_announce_version(),
1066 lp_minor_announce_version(),
1067 lp_default_server_announce(),
1068 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
1069 0xffffffff, /* users */
1070 0xf, /* disc */
1071 0, /* hidden */
1072 240, /* announce */
1073 3000, /* announce delta */
1074 100000, /* licenses */
1075 "c:\\"); /* user path */
1076 r->out.info->info102 = info102;
1077 break;
1079 case 101: {
1080 struct srvsvc_NetSrvInfo101 *info101;
1082 info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1083 if (!info101) {
1084 return WERR_NOMEM;
1087 init_srvsvc_NetSrvInfo101(info101,
1088 PLATFORM_ID_NT,
1089 global_myname(),
1090 lp_major_announce_version(),
1091 lp_minor_announce_version(),
1092 lp_default_server_announce(),
1093 string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
1094 r->out.info->info101 = info101;
1095 break;
1097 case 100: {
1098 struct srvsvc_NetSrvInfo100 *info100;
1100 info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1101 if (!info100) {
1102 return WERR_NOMEM;
1105 init_srvsvc_NetSrvInfo100(info100,
1106 PLATFORM_ID_NT,
1107 global_myname());
1108 r->out.info->info100 = info100;
1110 break;
1112 default:
1113 status = WERR_UNKNOWN_LEVEL;
1114 break;
1117 DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
1119 return status;
1122 /*******************************************************************
1123 _srvsvc_NetSrvSetInfo
1124 ********************************************************************/
1126 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p,
1127 struct srvsvc_NetSrvSetInfo *r)
1129 WERROR status = WERR_OK;
1131 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1133 /* Set up the net server set info structure. */
1135 DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
1137 return status;
1140 /*******************************************************************
1141 _srvsvc_NetConnEnum
1142 ********************************************************************/
1144 WERROR _srvsvc_NetConnEnum(pipes_struct *p,
1145 struct srvsvc_NetConnEnum *r)
1147 WERROR werr;
1149 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1151 switch (r->in.info_ctr->level) {
1152 case 0:
1153 werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
1154 r->in.resume_handle,
1155 r->out.totalentries);
1156 break;
1157 case 1:
1158 werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
1159 r->in.resume_handle,
1160 r->out.totalentries);
1161 break;
1162 default:
1163 return WERR_UNKNOWN_LEVEL;
1166 DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
1168 return werr;
1171 /*******************************************************************
1172 _srvsvc_NetSessEnum
1173 ********************************************************************/
1175 WERROR _srvsvc_NetSessEnum(pipes_struct *p,
1176 struct srvsvc_NetSessEnum *r)
1178 WERROR werr;
1180 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1182 switch (r->in.info_ctr->level) {
1183 case 0:
1184 werr = init_srv_sess_info_0(p,
1185 r->in.info_ctr->ctr.ctr0,
1186 r->in.resume_handle,
1187 r->out.totalentries);
1188 break;
1189 case 1:
1190 werr = init_srv_sess_info_1(p,
1191 r->in.info_ctr->ctr.ctr1,
1192 r->in.resume_handle,
1193 r->out.totalentries);
1194 break;
1195 default:
1196 return WERR_UNKNOWN_LEVEL;
1199 DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
1201 return werr;
1204 /*******************************************************************
1205 _srvsvc_NetSessDel
1206 ********************************************************************/
1208 WERROR _srvsvc_NetSessDel(pipes_struct *p,
1209 struct srvsvc_NetSessDel *r)
1211 struct sessionid *session_list;
1212 struct current_user user;
1213 int num_sessions, snum;
1214 const char *username;
1215 const char *machine;
1216 bool not_root = False;
1217 WERROR werr;
1219 username = r->in.user;
1220 machine = r->in.client;
1222 /* strip leading backslashes if any */
1223 if (machine && machine[0] == '\\' && machine[1] == '\\') {
1224 machine += 2;
1227 num_sessions = list_sessions(p->mem_ctx, &session_list);
1229 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1231 werr = WERR_ACCESS_DENIED;
1233 get_current_user(&user, p);
1235 /* fail out now if you are not root or not a domain admin */
1237 if ((user.ut.uid != sec_initial_uid()) &&
1238 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1240 goto done;
1243 for (snum = 0; snum < num_sessions; snum++) {
1245 if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
1246 strequal(session_list[snum].remote_machine, machine)) {
1248 NTSTATUS ntstat;
1250 if (user.ut.uid != sec_initial_uid()) {
1251 not_root = True;
1252 become_root();
1255 ntstat = messaging_send(smbd_messaging_context(),
1256 session_list[snum].pid,
1257 MSG_SHUTDOWN, &data_blob_null);
1259 if (NT_STATUS_IS_OK(ntstat))
1260 werr = WERR_OK;
1262 if (not_root)
1263 unbecome_root();
1267 DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
1269 done:
1271 return werr;
1274 /*******************************************************************
1275 _srvsvc_NetShareEnumAll
1276 ********************************************************************/
1278 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p,
1279 struct srvsvc_NetShareEnumAll *r)
1281 WERROR werr;
1283 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1285 if (!pipe_access_check(p)) {
1286 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
1287 return WERR_ACCESS_DENIED;
1290 /* Create the list of shares for the response. */
1291 werr = init_srv_share_info_ctr(p,
1292 r->in.info_ctr,
1293 r->in.resume_handle,
1294 r->out.totalentries,
1295 true);
1297 DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
1299 return werr;
1302 /*******************************************************************
1303 _srvsvc_NetShareEnum
1304 ********************************************************************/
1306 WERROR _srvsvc_NetShareEnum(pipes_struct *p,
1307 struct srvsvc_NetShareEnum *r)
1309 WERROR werr;
1311 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1313 if (!pipe_access_check(p)) {
1314 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
1315 return WERR_ACCESS_DENIED;
1318 /* Create the list of shares for the response. */
1319 werr = init_srv_share_info_ctr(p,
1320 r->in.info_ctr,
1321 r->in.resume_handle,
1322 r->out.totalentries,
1323 false);
1325 DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
1327 return werr;
1330 /*******************************************************************
1331 _srvsvc_NetShareGetInfo
1332 ********************************************************************/
1334 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p,
1335 struct srvsvc_NetShareGetInfo *r)
1337 WERROR status = WERR_OK;
1338 fstring share_name;
1339 int snum;
1340 union srvsvc_NetShareInfo *info = r->out.info;
1342 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1344 fstrcpy(share_name, r->in.share_name);
1346 snum = find_service(share_name);
1347 if (snum < 0) {
1348 return WERR_INVALID_NAME;
1351 switch (r->in.level) {
1352 case 0:
1353 info->info0 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo0);
1354 W_ERROR_HAVE_NO_MEMORY(info->info0);
1355 init_srv_share_info_0(p, info->info0, snum);
1356 break;
1357 case 1:
1358 info->info1 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1);
1359 W_ERROR_HAVE_NO_MEMORY(info->info1);
1360 init_srv_share_info_1(p, info->info1, snum);
1361 break;
1362 case 2:
1363 info->info2 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo2);
1364 W_ERROR_HAVE_NO_MEMORY(info->info2);
1365 init_srv_share_info_2(p, info->info2, snum);
1366 break;
1367 case 501:
1368 info->info501 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo501);
1369 W_ERROR_HAVE_NO_MEMORY(info->info501);
1370 init_srv_share_info_501(p, info->info501, snum);
1371 break;
1372 case 502:
1373 info->info502 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo502);
1374 W_ERROR_HAVE_NO_MEMORY(info->info502);
1375 init_srv_share_info_502(p, info->info502, snum);
1376 break;
1377 case 1004:
1378 info->info1004 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1379 W_ERROR_HAVE_NO_MEMORY(info->info1004);
1380 init_srv_share_info_1004(p, info->info1004, snum);
1381 break;
1382 case 1005:
1383 info->info1005 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1384 W_ERROR_HAVE_NO_MEMORY(info->info1005);
1385 init_srv_share_info_1005(p, info->info1005, snum);
1386 break;
1387 case 1006:
1388 info->info1006 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1389 W_ERROR_HAVE_NO_MEMORY(info->info1006);
1390 init_srv_share_info_1006(p, info->info1006, snum);
1391 break;
1392 case 1007:
1393 info->info1007 = TALLOC_P(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1394 W_ERROR_HAVE_NO_MEMORY(info->info1007);
1395 init_srv_share_info_1007(p, info->info1007, snum);
1396 break;
1397 case 1501:
1398 init_srv_share_info_1501(p, info->info1501, snum);
1399 break;
1400 default:
1401 DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
1402 r->in.level));
1403 status = WERR_UNKNOWN_LEVEL;
1404 break;
1407 DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
1409 return status;
1412 /*******************************************************************
1413 Check a given DOS pathname is valid for a share.
1414 ********************************************************************/
1416 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
1418 char *ptr = NULL;
1420 if (!dos_pathname) {
1421 return NULL;
1424 ptr = talloc_strdup(ctx, dos_pathname);
1425 if (!ptr) {
1426 return NULL;
1428 /* Convert any '\' paths to '/' */
1429 unix_format(ptr);
1430 ptr = unix_clean_name(ctx, ptr);
1431 if (!ptr) {
1432 return NULL;
1435 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1436 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
1437 ptr += 2;
1439 /* Only absolute paths allowed. */
1440 if (*ptr != '/')
1441 return NULL;
1443 return ptr;
1446 /*******************************************************************
1447 _srvsvc_NetShareSetInfo. Modify share details.
1448 ********************************************************************/
1450 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
1451 struct srvsvc_NetShareSetInfo *r)
1453 struct current_user user;
1454 char *command = NULL;
1455 char *share_name = NULL;
1456 char *comment = NULL;
1457 const char *pathname = NULL;
1458 int type;
1459 int snum;
1460 int ret;
1461 char *path = NULL;
1462 SEC_DESC *psd = NULL;
1463 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1464 bool is_disk_op = False;
1465 int max_connections = 0;
1466 TALLOC_CTX *ctx = p->mem_ctx;
1467 union srvsvc_NetShareInfo *info = r->in.info;
1469 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1471 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1472 if (!share_name) {
1473 return WERR_NOMEM;
1476 if (r->out.parm_error) {
1477 *r->out.parm_error = 0;
1480 if ( strequal(share_name,"IPC$")
1481 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1482 || strequal(share_name,"global") )
1484 return WERR_ACCESS_DENIED;
1487 snum = find_service(share_name);
1489 /* Does this share exist ? */
1490 if (snum < 0)
1491 return WERR_NET_NAME_NOT_FOUND;
1493 /* No change to printer shares. */
1494 if (lp_print_ok(snum))
1495 return WERR_ACCESS_DENIED;
1497 get_current_user(&user,p);
1499 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1501 /* fail out now if you are not root and not a disk op */
1503 if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
1504 return WERR_ACCESS_DENIED;
1506 switch (r->in.level) {
1507 case 1:
1508 pathname = talloc_strdup(ctx, lp_pathname(snum));
1509 comment = talloc_strdup(ctx, info->info1->comment);
1510 type = info->info1->type;
1511 psd = NULL;
1512 break;
1513 case 2:
1514 comment = talloc_strdup(ctx, info->info2->comment);
1515 pathname = info->info2->path;
1516 type = info->info2->type;
1517 max_connections = (info->info2->max_users == (uint32_t)-1) ?
1518 0 : info->info2->max_users;
1519 psd = NULL;
1520 break;
1521 #if 0
1522 /* not supported on set but here for completeness */
1523 case 501:
1524 comment = talloc_strdup(ctx, info->info501->comment);
1525 type = info->info501->type;
1526 psd = NULL;
1527 break;
1528 #endif
1529 case 502:
1530 comment = talloc_strdup(ctx, info->info502->comment);
1531 pathname = info->info502->path;
1532 type = info->info502->type;
1533 psd = info->info502->sd_buf.sd;
1534 map_generic_share_sd_bits(psd);
1535 break;
1536 case 1004:
1537 pathname = talloc_strdup(ctx, lp_pathname(snum));
1538 comment = talloc_strdup(ctx, info->info1004->comment);
1539 type = STYPE_DISKTREE;
1540 break;
1541 case 1005:
1542 /* XP re-sets the csc policy even if it wasn't changed by the
1543 user, so we must compare it to see if it's what is set in
1544 smb.conf, so that we can contine other ops like setting
1545 ACLs on a share */
1546 if (((info->info1005->dfs_flags &
1547 SHARE_1005_CSC_POLICY_MASK) >>
1548 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1549 return WERR_OK;
1550 else {
1551 DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1552 return WERR_ACCESS_DENIED;
1554 case 1006:
1555 case 1007:
1556 return WERR_ACCESS_DENIED;
1557 case 1501:
1558 pathname = talloc_strdup(ctx, lp_pathname(snum));
1559 comment = talloc_strdup(ctx, lp_comment(snum));
1560 psd = info->info1501->sd;
1561 map_generic_share_sd_bits(psd);
1562 type = STYPE_DISKTREE;
1563 break;
1564 default:
1565 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
1566 r->in.level));
1567 return WERR_UNKNOWN_LEVEL;
1570 /* We can only modify disk shares. */
1571 if (type != STYPE_DISKTREE)
1572 return WERR_ACCESS_DENIED;
1574 if (comment == NULL) {
1575 return WERR_NOMEM;
1578 /* Check if the pathname is valid. */
1579 if (!(path = valid_share_pathname(p->mem_ctx, pathname )))
1580 return WERR_OBJECT_PATH_INVALID;
1582 /* Ensure share name, pathname and comment don't contain '"' characters. */
1583 string_replace(share_name, '"', ' ');
1584 string_replace(path, '"', ' ');
1585 string_replace(comment, '"', ' ');
1587 DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
1588 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1590 /* Only call modify function if something changed. */
1592 if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum))
1593 || (lp_max_connections(snum) != max_connections)) {
1594 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1595 DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
1596 return WERR_ACCESS_DENIED;
1599 command = talloc_asprintf(p->mem_ctx,
1600 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1601 lp_change_share_cmd(),
1602 get_dyn_CONFIGFILE(),
1603 share_name,
1604 path,
1605 comment ? comment : "",
1606 max_connections);
1607 if (!command) {
1608 return WERR_NOMEM;
1611 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
1613 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1615 if (is_disk_op)
1616 become_root();
1618 if ( (ret = smbrun(command, NULL)) == 0 ) {
1619 /* Tell everyone we updated smb.conf. */
1620 message_send_all(smbd_messaging_context(),
1621 MSG_SMB_CONF_UPDATED, NULL, 0,
1622 NULL);
1625 if ( is_disk_op )
1626 unbecome_root();
1628 /********* END SeDiskOperatorPrivilege BLOCK *********/
1630 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
1631 command, ret ));
1633 TALLOC_FREE(command);
1635 if ( ret != 0 )
1636 return WERR_ACCESS_DENIED;
1637 } else {
1638 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
1639 share_name ));
1642 /* Replace SD if changed. */
1643 if (psd) {
1644 SEC_DESC *old_sd;
1645 size_t sd_size;
1647 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size);
1649 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1650 if (!set_share_security(share_name, psd))
1651 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
1652 share_name ));
1656 DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
1658 return WERR_OK;
1661 /*******************************************************************
1662 _srvsvc_NetShareAdd.
1663 Call 'add_share_command "sharename" "pathname"
1664 "comment" "max connections = "
1665 ********************************************************************/
1667 WERROR _srvsvc_NetShareAdd(pipes_struct *p,
1668 struct srvsvc_NetShareAdd *r)
1670 struct current_user user;
1671 char *command = NULL;
1672 char *share_name = NULL;
1673 char *comment = NULL;
1674 char *pathname = NULL;
1675 int type;
1676 int snum;
1677 int ret;
1678 char *path;
1679 SEC_DESC *psd = NULL;
1680 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1681 bool is_disk_op;
1682 int max_connections = 0;
1683 TALLOC_CTX *ctx = p->mem_ctx;
1685 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1687 *r->out.parm_error = 0;
1689 get_current_user(&user,p);
1691 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1693 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1694 return WERR_ACCESS_DENIED;
1696 if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1697 DEBUG(10,("_srvsvc_NetShareAdd: No add share command\n"));
1698 return WERR_ACCESS_DENIED;
1701 switch (r->in.level) {
1702 case 0:
1703 /* No path. Not enough info in a level 0 to do anything. */
1704 return WERR_ACCESS_DENIED;
1705 case 1:
1706 /* Not enough info in a level 1 to do anything. */
1707 return WERR_ACCESS_DENIED;
1708 case 2:
1709 share_name = talloc_strdup(ctx, r->in.info->info2->name);
1710 comment = talloc_strdup(ctx, r->in.info->info2->comment);
1711 pathname = talloc_strdup(ctx, r->in.info->info2->path);
1712 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
1713 0 : r->in.info->info2->max_users;
1714 type = r->in.info->info2->type;
1715 break;
1716 case 501:
1717 /* No path. Not enough info in a level 501 to do anything. */
1718 return WERR_ACCESS_DENIED;
1719 case 502:
1720 share_name = talloc_strdup(ctx, r->in.info->info502->name);
1721 comment = talloc_strdup(ctx, r->in.info->info502->comment);
1722 pathname = talloc_strdup(ctx, r->in.info->info502->path);
1723 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
1724 0 : r->in.info->info502->max_users;
1725 type = r->in.info->info502->type;
1726 psd = r->in.info->info502->sd_buf.sd;
1727 map_generic_share_sd_bits(psd);
1728 break;
1730 /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */
1732 case 1004:
1733 case 1005:
1734 case 1006:
1735 case 1007:
1736 return WERR_ACCESS_DENIED;
1737 case 1501:
1738 /* DFS only level. */
1739 return WERR_ACCESS_DENIED;
1740 default:
1741 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
1742 r->in.level));
1743 return WERR_UNKNOWN_LEVEL;
1746 /* check for invalid share names */
1748 if (!share_name || !validate_net_name(share_name,
1749 INVALID_SHARENAME_CHARS,
1750 strlen(share_name))) {
1751 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
1752 share_name ? share_name : ""));
1753 return WERR_INVALID_NAME;
1756 if (strequal(share_name,"IPC$") || strequal(share_name,"global")
1757 || (lp_enable_asu_support() &&
1758 strequal(share_name,"ADMIN$"))) {
1759 return WERR_ACCESS_DENIED;
1762 snum = find_service(share_name);
1764 /* Share already exists. */
1765 if (snum >= 0) {
1766 return WERR_ALREADY_EXISTS;
1769 /* We can only add disk shares. */
1770 if (type != STYPE_DISKTREE) {
1771 return WERR_ACCESS_DENIED;
1774 /* Check if the pathname is valid. */
1775 if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
1776 return WERR_OBJECT_PATH_INVALID;
1779 /* Ensure share name, pathname and comment don't contain '"' characters. */
1780 string_replace(share_name, '"', ' ');
1781 string_replace(path, '"', ' ');
1782 if (comment) {
1783 string_replace(comment, '"', ' ');
1786 command = talloc_asprintf(ctx,
1787 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1788 lp_add_share_cmd(),
1789 get_dyn_CONFIGFILE(),
1790 share_name,
1791 path,
1792 comment ? comment : "",
1793 max_connections);
1794 if (!command) {
1795 return WERR_NOMEM;
1798 DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
1800 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1802 if ( is_disk_op )
1803 become_root();
1805 /* FIXME: use libnetconf here - gd */
1807 if ( (ret = smbrun(command, NULL)) == 0 ) {
1808 /* Tell everyone we updated smb.conf. */
1809 message_send_all(smbd_messaging_context(),
1810 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1813 if ( is_disk_op )
1814 unbecome_root();
1816 /********* END SeDiskOperatorPrivilege BLOCK *********/
1818 DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
1819 command, ret ));
1821 TALLOC_FREE(command);
1823 if ( ret != 0 )
1824 return WERR_ACCESS_DENIED;
1826 if (psd) {
1827 if (!set_share_security(share_name, psd)) {
1828 DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
1829 share_name ));
1834 * We don't call reload_services() here, the message will
1835 * cause this to be done before the next packet is read
1836 * from the client. JRA.
1839 DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
1841 return WERR_OK;
1844 /*******************************************************************
1845 _srvsvc_NetShareDel
1846 Call "delete share command" with the share name as
1847 a parameter.
1848 ********************************************************************/
1850 WERROR _srvsvc_NetShareDel(pipes_struct *p,
1851 struct srvsvc_NetShareDel *r)
1853 struct current_user user;
1854 char *command = NULL;
1855 char *share_name = NULL;
1856 int ret;
1857 int snum;
1858 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1859 bool is_disk_op;
1860 struct share_params *params;
1861 TALLOC_CTX *ctx = p->mem_ctx;
1863 DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
1865 share_name = talloc_strdup(p->mem_ctx, r->in.share_name);
1866 if (!share_name) {
1867 return WERR_NET_NAME_NOT_FOUND;
1869 if ( strequal(share_name,"IPC$")
1870 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1871 || strequal(share_name,"global") )
1873 return WERR_ACCESS_DENIED;
1876 if (!(params = get_share_params(p->mem_ctx, share_name))) {
1877 return WERR_NO_SUCH_SHARE;
1880 snum = find_service(share_name);
1882 /* No change to printer shares. */
1883 if (lp_print_ok(snum))
1884 return WERR_ACCESS_DENIED;
1886 get_current_user(&user,p);
1888 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1890 if (user.ut.uid != sec_initial_uid() && !is_disk_op )
1891 return WERR_ACCESS_DENIED;
1893 if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1894 DEBUG(10,("_srvsvc_NetShareDel: No delete share command\n"));
1895 return WERR_ACCESS_DENIED;
1898 command = talloc_asprintf(ctx,
1899 "%s \"%s\" \"%s\"",
1900 lp_delete_share_cmd(),
1901 get_dyn_CONFIGFILE(),
1902 lp_servicename(snum));
1903 if (!command) {
1904 return WERR_NOMEM;
1907 DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
1909 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1911 if ( is_disk_op )
1912 become_root();
1914 if ( (ret = smbrun(command, NULL)) == 0 ) {
1915 /* Tell everyone we updated smb.conf. */
1916 message_send_all(smbd_messaging_context(),
1917 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
1920 if ( is_disk_op )
1921 unbecome_root();
1923 /********* END SeDiskOperatorPrivilege BLOCK *********/
1925 DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
1927 if ( ret != 0 )
1928 return WERR_ACCESS_DENIED;
1930 /* Delete the SD in the database. */
1931 delete_share_security(lp_servicename(params->service));
1933 lp_killservice(params->service);
1935 return WERR_OK;
1938 /*******************************************************************
1939 _srvsvc_NetShareDelSticky
1940 ********************************************************************/
1942 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p,
1943 struct srvsvc_NetShareDelSticky *r)
1945 struct srvsvc_NetShareDel q;
1947 DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
1949 q.in.server_unc = r->in.server_unc;
1950 q.in.share_name = r->in.share_name;
1951 q.in.reserved = r->in.reserved;
1953 return _srvsvc_NetShareDel(p, &q);
1956 /*******************************************************************
1957 _srvsvc_NetRemoteTOD
1958 ********************************************************************/
1960 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p,
1961 struct srvsvc_NetRemoteTOD *r)
1963 struct srvsvc_NetRemoteTODInfo *tod;
1964 struct tm *t;
1965 time_t unixdate = time(NULL);
1967 /* We do this call first as if we do it *after* the gmtime call
1968 it overwrites the pointed-to values. JRA */
1970 uint32 zone = get_time_zone(unixdate)/60;
1972 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1974 if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
1975 return WERR_NOMEM;
1977 *r->out.info = tod;
1979 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
1981 t = gmtime(&unixdate);
1983 /* set up the */
1984 init_srvsvc_NetRemoteTODInfo(tod,
1985 unixdate,
1987 t->tm_hour,
1988 t->tm_min,
1989 t->tm_sec,
1991 zone,
1992 10000,
1993 t->tm_mday,
1994 t->tm_mon + 1,
1995 1900+t->tm_year,
1996 t->tm_wday);
1998 DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
2000 return WERR_OK;
2003 /***********************************************************************************
2004 _srvsvc_NetGetFileSecurity
2005 Win9x NT tools get security descriptor.
2006 ***********************************************************************************/
2008 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
2009 struct srvsvc_NetGetFileSecurity *r)
2011 SEC_DESC *psd = NULL;
2012 size_t sd_size;
2013 DATA_BLOB null_pw;
2014 char *filename_in = NULL;
2015 char *filename = NULL;
2016 char *qualname = NULL;
2017 SMB_STRUCT_STAT st;
2018 NTSTATUS nt_status;
2019 WERROR werr;
2020 struct current_user user;
2021 connection_struct *conn = NULL;
2022 bool became_user = False;
2023 TALLOC_CTX *ctx = p->mem_ctx;
2024 struct sec_desc_buf *sd_buf;
2026 ZERO_STRUCT(st);
2028 werr = WERR_OK;
2030 qualname = talloc_strdup(ctx, r->in.share);
2031 if (!qualname) {
2032 werr = WERR_ACCESS_DENIED;
2033 goto error_exit;
2036 /* Null password is ok - we are already an authenticated user... */
2037 null_pw = data_blob_null;
2039 get_current_user(&user, p);
2041 become_root();
2042 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2043 unbecome_root();
2045 if (conn == NULL) {
2046 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to connect to %s\n",
2047 qualname));
2048 werr = ntstatus_to_werror(nt_status);
2049 goto error_exit;
2052 if (!become_user(conn, conn->vuid)) {
2053 DEBUG(0,("_srvsvc_NetGetFileSecurity: Can't become connected user!\n"));
2054 werr = WERR_ACCESS_DENIED;
2055 goto error_exit;
2057 became_user = True;
2059 filename_in = talloc_strdup(ctx, r->in.file);
2060 if (!filename_in) {
2061 werr = WERR_ACCESS_DENIED;
2062 goto error_exit;
2065 nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st);
2066 if (!NT_STATUS_IS_OK(nt_status)) {
2067 DEBUG(3,("_srvsvc_NetGetFileSecurity: bad pathname %s\n",
2068 filename));
2069 werr = WERR_ACCESS_DENIED;
2070 goto error_exit;
2073 nt_status = check_name(conn, filename);
2074 if (!NT_STATUS_IS_OK(nt_status)) {
2075 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't access %s\n",
2076 filename));
2077 werr = WERR_ACCESS_DENIED;
2078 goto error_exit;
2081 nt_status = SMB_VFS_GET_NT_ACL(conn, filename,
2082 (OWNER_SECURITY_INFORMATION
2083 |GROUP_SECURITY_INFORMATION
2084 |DACL_SECURITY_INFORMATION), &psd);
2086 if (!NT_STATUS_IS_OK(nt_status)) {
2087 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL for file %s\n",
2088 filename));
2089 werr = ntstatus_to_werror(nt_status);
2090 goto error_exit;
2093 sd_size = ndr_size_security_descriptor(psd, 0);
2095 sd_buf = TALLOC_ZERO_P(ctx, struct sec_desc_buf);
2096 if (!sd_buf) {
2097 werr = WERR_NOMEM;
2098 goto error_exit;
2101 sd_buf->sd_size = sd_size;
2102 sd_buf->sd = psd;
2104 *r->out.sd_buf = sd_buf;
2106 psd->dacl->revision = NT4_ACL_REVISION;
2108 unbecome_user();
2109 close_cnum(conn, user.vuid);
2110 return werr;
2112 error_exit:
2114 if (became_user)
2115 unbecome_user();
2117 if (conn)
2118 close_cnum(conn, user.vuid);
2120 return werr;
2123 /***********************************************************************************
2124 _srvsvc_NetSetFileSecurity
2125 Win9x NT tools set security descriptor.
2126 ***********************************************************************************/
2128 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
2129 struct srvsvc_NetSetFileSecurity *r)
2131 char *filename_in = NULL;
2132 char *filename = NULL;
2133 char *qualname = NULL;
2134 DATA_BLOB null_pw;
2135 files_struct *fsp = NULL;
2136 SMB_STRUCT_STAT st;
2137 NTSTATUS nt_status;
2138 WERROR werr;
2139 struct current_user user;
2140 connection_struct *conn = NULL;
2141 bool became_user = False;
2142 TALLOC_CTX *ctx = p->mem_ctx;
2144 ZERO_STRUCT(st);
2146 werr = WERR_OK;
2148 qualname = talloc_strdup(ctx, r->in.share);
2149 if (!qualname) {
2150 werr = WERR_ACCESS_DENIED;
2151 goto error_exit;
2154 /* Null password is ok - we are already an authenticated user... */
2155 null_pw = data_blob_null;
2157 get_current_user(&user, p);
2159 become_root();
2160 conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status);
2161 unbecome_root();
2163 if (conn == NULL) {
2164 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to connect to %s\n", qualname));
2165 werr = ntstatus_to_werror(nt_status);
2166 goto error_exit;
2169 if (!become_user(conn, conn->vuid)) {
2170 DEBUG(0,("_srvsvc_NetSetFileSecurity: Can't become connected user!\n"));
2171 werr = WERR_ACCESS_DENIED;
2172 goto error_exit;
2174 became_user = True;
2176 filename_in = talloc_strdup(ctx, r->in.file);
2177 if (!filename_in) {
2178 werr = WERR_ACCESS_DENIED;
2179 goto error_exit;
2182 nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st);
2183 if (!NT_STATUS_IS_OK(nt_status)) {
2184 DEBUG(3,("_srvsvc_NetSetFileSecurity: bad pathname %s\n", filename));
2185 werr = WERR_ACCESS_DENIED;
2186 goto error_exit;
2189 nt_status = check_name(conn, filename);
2190 if (!NT_STATUS_IS_OK(nt_status)) {
2191 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't access %s\n", filename));
2192 werr = WERR_ACCESS_DENIED;
2193 goto error_exit;
2196 nt_status = open_file_stat(conn, NULL, filename, &st, &fsp);
2198 if ( !NT_STATUS_IS_OK(nt_status) ) {
2199 /* Perhaps it is a directory */
2200 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2201 nt_status = open_directory(conn, NULL, filename, &st,
2202 FILE_READ_ATTRIBUTES,
2203 FILE_SHARE_READ|FILE_SHARE_WRITE,
2204 FILE_OPEN,
2206 FILE_ATTRIBUTE_DIRECTORY,
2207 NULL, &fsp);
2209 if ( !NT_STATUS_IS_OK(nt_status) ) {
2210 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to open file %s\n", filename));
2211 werr = ntstatus_to_werror(nt_status);
2212 goto error_exit;
2216 nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
2217 r->in.securityinformation,
2218 r->in.sd_buf->sd);
2220 if (!NT_STATUS_IS_OK(nt_status) ) {
2221 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL on file %s\n", filename));
2222 werr = WERR_ACCESS_DENIED;
2223 goto error_exit;
2226 close_file(fsp, NORMAL_CLOSE);
2227 unbecome_user();
2228 close_cnum(conn, user.vuid);
2229 return werr;
2231 error_exit:
2233 if(fsp) {
2234 close_file(fsp, NORMAL_CLOSE);
2237 if (became_user) {
2238 unbecome_user();
2241 if (conn) {
2242 close_cnum(conn, user.vuid);
2245 return werr;
2248 /***********************************************************************************
2249 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2250 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2251 These disks would the disks listed by this function.
2252 Users could then create shares relative to these disks. Watch out for moving these disks around.
2253 "Nigel Williams" <nigel@veritas.com>.
2254 ***********************************************************************************/
2256 static const char *server_disks[] = {"C:"};
2258 static uint32 get_server_disk_count(void)
2260 return sizeof(server_disks)/sizeof(server_disks[0]);
2263 static uint32 init_server_disk_enum(uint32 *resume)
2265 uint32 server_disk_count = get_server_disk_count();
2267 /*resume can be an offset into the list for now*/
2269 if(*resume & 0x80000000)
2270 *resume = 0;
2272 if(*resume > server_disk_count)
2273 *resume = server_disk_count;
2275 return server_disk_count - *resume;
2278 static const char *next_server_disk_enum(uint32 *resume)
2280 const char *disk;
2282 if(init_server_disk_enum(resume) == 0)
2283 return NULL;
2285 disk = server_disks[*resume];
2287 (*resume)++;
2289 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2291 return disk;
2294 /********************************************************************
2295 _srvsvc_NetDiskEnum
2296 ********************************************************************/
2298 WERROR _srvsvc_NetDiskEnum(pipes_struct *p,
2299 struct srvsvc_NetDiskEnum *r)
2301 uint32 i;
2302 const char *disk_name;
2303 TALLOC_CTX *ctx = p->mem_ctx;
2304 WERROR werr;
2305 uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
2307 werr = WERR_OK;
2309 *r->out.totalentries = init_server_disk_enum(&resume);
2311 r->out.info->disks = TALLOC_ZERO_ARRAY(ctx, struct srvsvc_NetDiskInfo0,
2312 MAX_SERVER_DISK_ENTRIES);
2313 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
2315 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2317 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
2319 r->out.info->count++;
2321 /*copy disk name into a unicode string*/
2323 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
2324 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2327 /* add a terminating null string. Is this there if there is more data to come? */
2329 r->out.info->count++;
2331 r->out.info->disks[i].disk = talloc_strdup(ctx, "");
2332 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
2334 if (r->out.resume_handle) {
2335 *r->out.resume_handle = resume;
2338 return werr;
2341 /********************************************************************
2342 _srvsvc_NetNameValidate
2343 ********************************************************************/
2345 WERROR _srvsvc_NetNameValidate(pipes_struct *p,
2346 struct srvsvc_NetNameValidate *r)
2348 switch (r->in.name_type) {
2349 case 0x9:
2350 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
2351 strlen_m(r->in.name)))
2353 DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
2354 r->in.name));
2355 return WERR_INVALID_NAME;
2357 break;
2359 default:
2360 return WERR_UNKNOWN_LEVEL;
2363 return WERR_OK;
2366 /*******************************************************************
2367 ********************************************************************/
2369 static void enum_file_close_fn( const struct share_mode_entry *e,
2370 const char *sharepath, const char *fname,
2371 void *private_data )
2373 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
2374 struct srvsvc_NetFileClose *r =
2375 (struct srvsvc_NetFileClose *)private_data;
2376 uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
2378 if (fid != r->in.fid) {
2379 return; /* Not this file. */
2382 if (!process_exists(e->pid) ) {
2383 return;
2386 /* Ok - send the close message. */
2387 DEBUG(10,("enum_file_close_fn: request to close file %s, %s\n",
2388 sharepath,
2389 share_mode_str(talloc_tos(), 0, e) ));
2391 share_mode_entry_to_message(msg, e);
2393 r->out.result = ntstatus_to_werror(
2394 messaging_send_buf(smbd_messaging_context(),
2395 e->pid, MSG_SMB_CLOSE_FILE,
2396 (uint8 *)msg,
2397 MSG_SMB_SHARE_MODE_ENTRY_SIZE));
2400 /********************************************************************
2401 Close a file given a 32-bit file id.
2402 ********************************************************************/
2404 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2406 struct current_user user;
2407 SE_PRIV se_diskop = SE_DISK_OPERATOR;
2408 bool is_disk_op;
2410 DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
2412 get_current_user(&user,p);
2414 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
2416 if (user.ut.uid != sec_initial_uid() && !is_disk_op) {
2417 return WERR_ACCESS_DENIED;
2420 /* enum_file_close_fn sends the close message to
2421 * the relevent smbd process. */
2423 r->out.result = WERR_BADFILE;
2424 share_mode_forall( enum_file_close_fn, (void *)r);
2425 return r->out.result;
2428 /********************************************************************
2429 ********************************************************************/
2431 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2433 p->rng_fault_state = True;
2434 return WERR_NOT_SUPPORTED;
2437 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2439 p->rng_fault_state = True;
2440 return WERR_NOT_SUPPORTED;
2443 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2445 p->rng_fault_state = True;
2446 return WERR_NOT_SUPPORTED;
2449 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2451 p->rng_fault_state = True;
2452 return WERR_NOT_SUPPORTED;
2455 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2457 p->rng_fault_state = True;
2458 return WERR_NOT_SUPPORTED;
2461 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2463 p->rng_fault_state = True;
2464 return WERR_NOT_SUPPORTED;
2467 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2469 p->rng_fault_state = True;
2470 return WERR_NOT_SUPPORTED;
2473 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2475 p->rng_fault_state = True;
2476 return WERR_NOT_SUPPORTED;
2479 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2481 p->rng_fault_state = True;
2482 return WERR_NOT_SUPPORTED;
2485 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2487 p->rng_fault_state = True;
2488 return WERR_NOT_SUPPORTED;
2491 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2493 p->rng_fault_state = True;
2494 return WERR_NOT_SUPPORTED;
2497 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2499 p->rng_fault_state = True;
2500 return WERR_NOT_SUPPORTED;
2503 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2505 p->rng_fault_state = True;
2506 return WERR_NOT_SUPPORTED;
2509 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2511 p->rng_fault_state = True;
2512 return WERR_NOT_SUPPORTED;
2515 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2517 p->rng_fault_state = True;
2518 return WERR_NOT_SUPPORTED;
2521 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2523 p->rng_fault_state = True;
2524 return WERR_NOT_SUPPORTED;
2527 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2529 p->rng_fault_state = True;
2530 return WERR_NOT_SUPPORTED;
2533 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2535 p->rng_fault_state = True;
2536 return WERR_NOT_SUPPORTED;
2539 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2541 p->rng_fault_state = True;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2547 p->rng_fault_state = True;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2553 p->rng_fault_state = True;
2554 return WERR_NOT_SUPPORTED;
2557 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2559 p->rng_fault_state = True;
2560 return WERR_NOT_SUPPORTED;
2563 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;
2569 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2571 p->rng_fault_state = True;
2572 return WERR_NOT_SUPPORTED;
2575 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2577 p->rng_fault_state = True;
2578 return WERR_NOT_SUPPORTED;
2581 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2583 p->rng_fault_state = True;
2584 return WERR_NOT_SUPPORTED;
2587 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2589 p->rng_fault_state = True;
2590 return WERR_NOT_SUPPORTED;
2593 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
2595 p->rng_fault_state = True;
2596 return WERR_NOT_SUPPORTED;
2599 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2601 p->rng_fault_state = True;
2602 return WERR_NOT_SUPPORTED;
2605 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2607 p->rng_fault_state = True;
2608 return WERR_NOT_SUPPORTED;
2611 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2613 p->rng_fault_state = True;
2614 return WERR_NOT_SUPPORTED;
2617 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2619 p->rng_fault_state = True;
2620 return WERR_NOT_SUPPORTED;
2623 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2625 p->rng_fault_state = True;
2626 return WERR_NOT_SUPPORTED;
2629 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2631 p->rng_fault_state = True;
2632 return WERR_NOT_SUPPORTED;
2635 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2637 p->rng_fault_state = True;
2638 return WERR_NOT_SUPPORTED;