2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Jeremy Allison 2001.
6 * Copyright (C) Nigel Williams 2001.
7 * Copyright (C) Gerald (Jerry) Carter 2006.
8 * Copyright (C) Jelmer Vernooij 2006.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* This is the implementation of the srvsvc pipe. */
29 #define MAX_SERVER_DISK_ENTRIES 15
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
35 #define DBGC_CLASS DBGC_RPC_SRV
37 /* Use for enumerating connections, pipes, & files */
39 struct file_enum_count {
42 struct srvsvc_NetFileInfo3 *info;
45 struct sess_file_count {
51 /****************************************************************************
52 Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
55 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
57 struct pipe_open_rec prec;
58 struct file_enum_count *fenum = (struct file_enum_count *)p;
60 if (dbuf.dsize != sizeof(struct pipe_open_rec))
63 memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
65 if ( process_exists(prec.pid) ) {
66 struct srvsvc_NetFileInfo3 *f;
70 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
72 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
74 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
80 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82 fenum->info[i].num_locks = 0;
83 fenum->info[i].user = uidtoname( prec.uid );
84 fenum->info[i].path = fullpath;
92 /*******************************************************************
93 ********************************************************************/
95 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
96 uint32 *count, uint32 *resume )
98 struct file_enum_count fenum;
99 TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
102 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103 return WERR_ACCESS_DENIED;
108 fenum.count = *count;
110 if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
111 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112 tdb_errorstr(conn_tdb) ));
117 *count = fenum.count;
121 /*******************************************************************
122 ********************************************************************/
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt;
127 static void enum_file_fn( const struct share_mode_entry *e,
128 const char *sharepath, const char *fname,
131 struct file_enum_count *fenum = &f_enum_cnt;
133 /* If the pid was not found delete the entry from connections.tdb */
135 if ( process_exists(e->pid) ) {
136 struct srvsvc_NetFileInfo3 *f;
137 int i = fenum->count;
139 struct byte_range_lock *brl;
144 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
146 DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
151 /* need to count the number of locks on a file */
155 fsp.inode = e->inode;
157 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158 num_locks = brl->num_locks;
162 if ( strcmp( fname, "." ) == 0 ) {
163 pstr_sprintf( fullpath, "C:%s", sharepath );
165 pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
167 string_replace( fullpath, '/', '\\' );
169 /* mask out create (what ever that is) */
170 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
172 fenum->info[i].fid = e->share_file_id;
173 fenum->info[i].permissions = permissions;
174 fenum->info[i].num_locks = num_locks;
175 fenum->info[i].user = uidtoname(e->uid);
176 fenum->info[i].path = fullpath;
185 /*******************************************************************
186 ********************************************************************/
188 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info,
189 uint32 *count, uint32 *resume )
191 f_enum_cnt.ctx = ctx;
192 f_enum_cnt.count = *count;
193 f_enum_cnt.info = *info;
195 share_mode_forall( enum_file_fn, NULL );
197 *info = f_enum_cnt.info;
198 *count = f_enum_cnt.count;
203 /*******************************************************************
204 Utility function to get the 'type' of a share from a share definition.
205 ********************************************************************/
206 static uint32 get_share_type(const struct share_params *params)
208 char *net_name = lp_servicename(params->service);
209 int len_net_name = strlen(net_name);
211 /* work out the share type */
212 uint32 type = STYPE_DISKTREE;
214 if (lp_print_ok(params->service))
216 if (strequal(lp_fstype(params->service), "IPC"))
218 if (net_name[len_net_name-1] == '$')
219 type |= STYPE_HIDDEN;
224 /*******************************************************************
225 Fill in a share info level 0 structure.
226 ********************************************************************/
228 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
229 const struct share_params *params)
231 sh0->name = lp_servicename(params->service);
234 /*******************************************************************
235 Fill in a share info level 1 structure.
236 ********************************************************************/
238 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
239 const struct share_params *params)
241 connection_struct *conn = p->conn;
243 sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
244 conn->user, conn->connectpath, conn->gid,
245 get_current_username(),
246 current_user_info.domain,
247 lp_comment(params->service));
249 sh1->name = lp_servicename(params->service);
250 sh1->type = get_share_type(params);
253 /*******************************************************************
254 Fill in a share info level 2 structure.
255 ********************************************************************/
257 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
258 const struct share_params *params)
260 connection_struct *conn = p->conn;
263 int max_connections = lp_max_connections(params->service);
264 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
266 char *net_name = lp_servicename(params->service);
268 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
269 conn->user, conn->connectpath, conn->gid,
270 get_current_username(),
271 current_user_info.domain,
272 lp_comment(params->service));
273 path = talloc_asprintf(p->mem_ctx, "C:%s",
274 lp_pathname(params->service));
277 * Change / to \\ so that win2k will see it as a valid path. This was
278 * added to enable use of browsing in win2k add share dialog.
281 string_replace(path, '/', '\\');
283 count = count_current_connections( net_name, False );
284 sh2->name = net_name;
285 sh2->type = get_share_type(params);
286 sh2->comment = remark;
287 sh2->permissions = 0;
288 sh2->max_users = max_uses;
289 sh2->current_users = count;
294 /*******************************************************************
295 Map any generic bits to file specific bits.
296 ********************************************************************/
298 static void map_generic_share_sd_bits(SEC_DESC *psd)
301 SEC_ACL *ps_dacl = NULL;
310 for (i = 0; i < ps_dacl->num_aces; i++) {
311 SEC_ACE *psa = &ps_dacl->aces[i];
312 uint32 orig_mask = psa->access_mask;
314 se_map_generic(&psa->access_mask, &file_generic_mapping);
315 psa->access_mask |= orig_mask;
319 /*******************************************************************
320 Fill in a share info level 501 structure.
321 ********************************************************************/
323 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
324 const struct share_params *params)
326 connection_struct *conn = p->conn;
328 const char *net_name = lp_servicename(params->service);
330 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
331 conn->user, conn->connectpath, conn->gid,
332 get_current_username(),
333 current_user_info.domain,
334 lp_comment(params->service));
337 sh501->name = net_name;
338 sh501->type = get_share_type(params);
339 sh501->comment = remark;
340 sh501->csc_policy = (lp_csc_policy(params->service) << 4);
343 /*******************************************************************
344 Fill in a share info level 502 structure.
345 ********************************************************************/
347 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
348 const struct share_params *params)
350 int max_connections = lp_max_connections(params->service);
351 uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
352 connection_struct *conn = p->conn;
359 TALLOC_CTX *ctx = p->mem_ctx;
364 net_name = lp_servicename(params->service);
365 count = count_current_connections( net_name, False );
367 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
368 conn->user, conn->connectpath, conn->gid,
369 get_current_username(),
370 current_user_info.domain,
371 lp_comment(params->service));
373 path = talloc_asprintf(p->mem_ctx, "C:%s",
374 lp_pathname(params->service));
377 * Change / to \\ so that win2k will see it as a valid path. This was
378 * added to enable use of browsing in win2k add share dialog.
381 string_replace(path, '/', '\\');
383 sd = get_share_security(ctx, lp_servicename(params->service),
386 sh502->name = net_name;
387 sh502->type = get_share_type(params);
388 sh502->comment = remark;
390 sh502->password = "";
392 sh502->permissions = 0;
393 sh502->max_users = max_uses;
394 sh502->current_users = count;
398 /***************************************************************************
399 Fill in a share info level 1004 structure.
400 ***************************************************************************/
402 static void init_srv_share_info_1004(pipes_struct *p,
403 struct srvsvc_NetShareInfo1004* sh1004,
404 const struct share_params *params)
406 connection_struct *conn = p->conn;
409 remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
410 conn->user, conn->connectpath, conn->gid,
411 get_current_username(),
412 current_user_info.domain,
413 lp_comment(params->service));
415 ZERO_STRUCTP(sh1004);
417 sh1004->comment = remark;
420 /***************************************************************************
421 Fill in a share info level 1005 structure.
422 ***************************************************************************/
424 static void init_srv_share_info_1005(pipes_struct *p,
425 struct srvsvc_NetShareInfo1005* sh1005,
426 const struct share_params *params)
428 sh1005->dfs_flags = 0;
430 if(lp_host_msdfs() && lp_msdfs_root(params->service))
432 SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
434 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
436 /***************************************************************************
437 Fill in a share info level 1006 structure.
438 ***************************************************************************/
440 static void init_srv_share_info_1006(pipes_struct *p,
441 struct srvsvc_NetShareInfo1006* sh1006,
442 const struct share_params *params)
444 sh1006->max_users = -1;
447 /***************************************************************************
448 Fill in a share info level 1007 structure.
449 ***************************************************************************/
451 static void init_srv_share_info_1007(pipes_struct *p,
452 struct srvsvc_NetShareInfo1007* sh1007,
453 const struct share_params *params)
457 ZERO_STRUCTP(sh1007);
459 sh1007->flags = flags;
460 sh1007->alternate_directory_name = "";
463 /*******************************************************************
464 Fill in a share info level 1501 structure.
465 ********************************************************************/
467 static void init_srv_share_info_1501(pipes_struct *p,
468 struct sec_desc_buf *sh1501,
469 const struct share_params *params)
473 TALLOC_CTX *ctx = p->mem_ctx;
475 ZERO_STRUCTP(sh1501);
477 sd = get_share_security(ctx, lp_servicename(params->service),
483 /*******************************************************************
484 True if it ends in '$'.
485 ********************************************************************/
487 static BOOL is_hidden_share(const struct share_params *params)
489 const char *net_name = lp_servicename(params->service);
491 return (net_name[strlen(net_name) - 1] == '$');
494 /*******************************************************************
495 Fill in a share info structure.
496 ********************************************************************/
498 static WERROR init_srv_share_info_ctr(pipes_struct *p,
499 union srvsvc_NetShareCtr *ctr,
500 uint32 info_level, uint32 *resume_hnd,
501 uint32 *total_entries, BOOL all_shares)
503 TALLOC_CTX *ctx = p->mem_ctx;
504 struct share_iterator *shares;
505 struct share_params *share;
506 WERROR result = WERR_NOMEM;
508 DEBUG(5,("init_srv_share_info_ctr\n"));
516 /* Ensure all the usershares are loaded. */
518 load_usershare_shares();
519 load_registry_shares();
524 if (!(shares = share_list_all(ctx))) {
525 DEBUG(5, ("Could not list shares\n"));
526 return WERR_ACCESS_DENIED;
529 switch (info_level) {
531 if (!(ctr->ctr0 = talloc_zero(
532 p->mem_ctx, struct srvsvc_NetShareCtr0))) {
537 if (!(ctr->ctr1 = talloc_zero(
538 p->mem_ctx, struct srvsvc_NetShareCtr1))) {
543 if (!(ctr->ctr2 = talloc_zero(
544 p->mem_ctx, struct srvsvc_NetShareCtr2))) {
549 if (!(ctr->ctr501 = talloc_zero(
550 p->mem_ctx, struct srvsvc_NetShareCtr501))) {
555 if (!(ctr->ctr502 = talloc_zero(
556 p->mem_ctx, struct srvsvc_NetShareCtr502))) {
561 if (!(ctr->ctr1004 = talloc_zero(
562 p->mem_ctx, struct srvsvc_NetShareCtr1004))) {
567 if (!(ctr->ctr1005 = talloc_zero(
568 p->mem_ctx, struct srvsvc_NetShareCtr1005))) {
573 if (!(ctr->ctr1006 = talloc_zero(
574 p->mem_ctx, struct srvsvc_NetShareCtr1006))) {
579 if (!(ctr->ctr1007 = talloc_zero(
580 p->mem_ctx, struct srvsvc_NetShareCtr1007))) {
585 if (!(ctr->ctr1501 = talloc_zero(
586 p->mem_ctx, struct srvsvc_NetShareCtr1501))) {
591 DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
592 "value %d\n", info_level));
593 return WERR_UNKNOWN_LEVEL;
596 while ((share = next_share(shares)) != NULL) {
597 if (!lp_browseable(share->service)) {
600 if (!all_shares && is_hidden_share(share)) {
604 switch (info_level) {
607 struct srvsvc_NetShareInfo0 i;
608 init_srv_share_info_0(p, &i, share);
609 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
610 &ctr->ctr0->array, &ctr->ctr0->count);
611 if (ctr->ctr0->array == NULL) {
614 *total_entries = ctr->ctr0->count;
620 struct srvsvc_NetShareInfo1 i;
621 init_srv_share_info_1(p, &i, share);
622 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
623 &ctr->ctr1->array, &ctr->ctr1->count);
624 if (ctr->ctr1->array == NULL) {
627 *total_entries = ctr->ctr1->count;
633 struct srvsvc_NetShareInfo2 i;
634 init_srv_share_info_2(p, &i, share);
635 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
636 &ctr->ctr2->array, &ctr->ctr2->count);
637 if (ctr->ctr2->array == NULL) {
640 *total_entries = ctr->ctr2->count;
646 struct srvsvc_NetShareInfo501 i;
647 init_srv_share_info_501(p, &i, share);
648 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
649 &ctr->ctr501->array, &ctr->ctr501->count);
650 if (ctr->ctr501->array == NULL) {
653 *total_entries = ctr->ctr501->count;
659 struct srvsvc_NetShareInfo502 i;
660 init_srv_share_info_502(p, &i, share);
661 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
662 &ctr->ctr502->array, &ctr->ctr502->count);
663 if (ctr->ctr502->array == NULL) {
666 *total_entries = ctr->ctr502->count;
670 /* here for completeness but not currently used with enum
675 struct srvsvc_NetShareInfo1004 i;
676 init_srv_share_info_1004(p, &i, share);
677 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
678 &ctr->ctr1004->array, &ctr->ctr1004->count);
679 if (ctr->ctr1004->array == NULL) {
682 *total_entries = ctr->ctr1004->count;
688 struct srvsvc_NetShareInfo1005 i;
689 init_srv_share_info_1005(p, &i, share);
690 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
691 &ctr->ctr1005->array, &ctr->ctr1005->count);
692 if (ctr->ctr1005->array == NULL) {
695 *total_entries = ctr->ctr1005->count;
701 struct srvsvc_NetShareInfo1006 i;
702 init_srv_share_info_1006(p, &i, share);
703 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
704 &ctr->ctr1006->array, &ctr->ctr1006->count);
705 if (ctr->ctr1006->array == NULL) {
708 *total_entries = ctr->ctr1006->count;
714 struct srvsvc_NetShareInfo1007 i;
715 init_srv_share_info_1007(p, &i, share);
716 ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
717 &ctr->ctr1007->array, &ctr->ctr1007->count);
718 if (ctr->ctr1007->array == NULL) {
721 *total_entries = ctr->ctr1007->count;
727 struct sec_desc_buf i;
728 init_srv_share_info_1501(p, &i, share);
729 ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
730 &ctr->ctr1501->array, &ctr->ctr1501->count);
731 if (ctr->ctr1501->array == NULL) {
734 *total_entries = ctr->ctr1501->count;
748 /*******************************************************************
749 fill in a sess info level 0 structure.
750 ********************************************************************/
752 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
754 struct sessionid *session_list;
755 uint32 num_entries = 0;
756 (*stot) = list_sessions(&session_list);
762 SAFE_FREE(session_list);
766 DEBUG(5,("init_srv_sess_0_ss0\n"));
768 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
771 for (; (*snum) < (*stot); (*snum)++) {
772 ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
776 ss0->count = num_entries;
778 if ((*snum) >= (*stot)) {
786 SAFE_FREE(session_list);
789 /*******************************************************************
790 ********************************************************************/
792 static void sess_file_fn( const struct share_mode_entry *e,
793 const char *sharepath, const char *fname,
796 struct sess_file_count *sess = (struct sess_file_count *)private_data;
798 if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
805 /*******************************************************************
806 ********************************************************************/
808 static int net_count_files( uid_t uid, pid_t pid )
810 struct sess_file_count s_file_cnt;
812 s_file_cnt.count = 0;
813 s_file_cnt.uid = uid;
814 s_file_cnt.pid = pid;
816 share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
818 return s_file_cnt.count;
821 /*******************************************************************
822 fill in a sess info level 1 structure.
823 ********************************************************************/
825 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
827 struct sessionid *session_list;
828 uint32 num_entries = 0;
829 time_t now = time(NULL);
846 (*stot) = list_sessions(&session_list);
848 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
850 for (; (*snum) < (*stot); (*snum)++) {
853 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
857 DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
858 session_list[*snum].username));
862 connect_time = (uint32)(now - session_list[*snum].connect_start);
863 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
864 guest = strequal( session_list[*snum].username, lp_guestaccount() );
866 ss1->array[num_entries].client = session_list[*snum].remote_machine;
867 ss1->array[num_entries].user = session_list[*snum].username;
868 ss1->array[num_entries].num_open = num_files;
869 ss1->array[num_entries].time = connect_time;
870 ss1->array[num_entries].idle_time = 0;
871 ss1->array[num_entries].user_flags = guest;
876 ss1->count = num_entries;
878 if ((*snum) >= (*stot)) {
882 SAFE_FREE(session_list);
885 /*******************************************************************
886 makes a SRV_R_NET_SESS_ENUM structure.
887 ********************************************************************/
889 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
890 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
892 WERROR status = WERR_OK;
893 DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
895 switch (switch_value) {
897 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
898 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
901 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
902 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
905 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
906 if (resume_hnd != NULL)
908 (*total_entries) = 0;
910 status = WERR_UNKNOWN_LEVEL;
917 /*******************************************************************
918 fill in a conn info level 0 structure.
919 ********************************************************************/
921 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
923 uint32 num_entries = 0;
932 DEBUG(5,("init_srv_conn_0_ss0\n"));
935 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
936 for (; (*snum) < (*stot); (*snum)++) {
938 ss0->array[num_entries].conn_id = (*stot);
940 /* move on to creating next connection */
941 /* move on to creating next conn */
945 ss0->count = num_entries;
947 if ((*snum) >= (*stot)) {
959 /*******************************************************************
960 fill in a conn info level 1 structure.
961 ********************************************************************/
963 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
965 uint32 num_entries = 0;
974 DEBUG(5,("init_srv_conn_1_ss1\n"));
977 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
978 for (; (*snum) < (*stot); (*snum)++) {
979 ss1->array[num_entries].conn_id = (*stot);
980 ss1->array[num_entries].conn_type = 0x3;
981 ss1->array[num_entries].num_open = 1;
982 ss1->array[num_entries].num_users = 1;
983 ss1->array[num_entries].conn_time = 3;
984 ss1->array[num_entries].user = "dummy_user";
985 ss1->array[num_entries].share = "IPC$";
987 /* move on to creating next connection */
988 /* move on to creating next conn */
992 ss1->count = num_entries;
994 if ((*snum) >= (*stot)) {
1006 /*******************************************************************
1007 makes a SRV_R_NET_CONN_ENUM structure.
1008 ********************************************************************/
1010 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
1011 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
1013 WERROR status = WERR_OK;
1014 DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
1016 switch (switch_value) {
1018 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
1021 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
1024 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
1027 (*total_entries) = 0;
1028 status = WERR_UNKNOWN_LEVEL;
1035 /*******************************************************************
1036 makes a SRV_R_NET_FILE_ENUM structure.
1037 ********************************************************************/
1039 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
1041 TALLOC_CTX *ctx = get_talloc_ctx();
1044 /* TODO -- Windows enumerates
1046 (c) open directories and files */
1048 ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1050 status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1051 if ( !W_ERROR_IS_OK(status))
1054 status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1055 if ( !W_ERROR_IS_OK(status))
1058 ctr->ctr3->count = *num_entries;
1063 /*******************************************************************
1064 *******************************************************************/
1066 WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r)
1068 switch ( *r->in.level ) {
1070 return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, r->out.totalentries );
1072 return WERR_UNKNOWN_LEVEL;
1078 /*******************************************************************
1080 ********************************************************************/
1082 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r)
1084 WERROR status = WERR_OK;
1086 ZERO_STRUCTP(r->out.info);
1088 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1090 if (!pipe_access_check(p)) {
1091 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1092 return WERR_ACCESS_DENIED;
1095 switch (r->in.level) {
1097 /* Technically level 102 should only be available to
1098 Administrators but there isn't anything super-secret
1099 here, as most of it is made up. */
1102 r->out.info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1104 r->out.info->info102->platform_id = 500;
1105 r->out.info->info102->version_major = lp_major_announce_version();
1106 r->out.info->info102->version_minor = lp_minor_announce_version();
1107 r->out.info->info102->server_name = global_myname();
1108 r->out.info->info102->server_type = lp_default_server_announce();
1109 r->out.info->info102->userpath = "C:\\";
1110 r->out.info->info102->licenses = 10000;
1111 r->out.info->info102->anndelta = 3000;
1112 r->out.info->info102->disc = 0xf;
1113 r->out.info->info102->users = 0xffffffff;
1114 r->out.info->info102->hidden = 0;
1115 r->out.info->info102->announce = 240;
1116 r->out.info->info102->comment = lp_serverstring();
1119 r->out.info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1120 r->out.info->info101->platform_id = 500;
1121 r->out.info->info101->server_name = global_myname();
1122 r->out.info->info101->version_major = lp_major_announce_version();
1123 r->out.info->info101->version_minor = lp_minor_announce_version();
1124 r->out.info->info101->server_type = lp_default_server_announce();
1125 r->out.info->info101->comment = lp_serverstring();
1128 r->out.info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1129 r->out.info->info100->platform_id = 500;
1130 r->out.info->info100->server_name = global_myname();
1133 return WERR_UNKNOWN_LEVEL;
1137 DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1142 /*******************************************************************
1144 ********************************************************************/
1146 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r)
1148 /* Set up the net server set info structure. */
1149 if (r->out.parm_error) {
1150 *r->out.parm_error = 0;
1155 /*******************************************************************
1157 ********************************************************************/
1159 WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r)
1161 DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1163 ZERO_STRUCTP(r->out.ctr);
1166 return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries);
1169 /*******************************************************************
1171 ********************************************************************/
1173 WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r)
1175 DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1177 ZERO_STRUCTP(r->out.ctr);
1180 return init_srv_sess_info_ctr(p, r->out.ctr,
1182 r->in.resume_handle,
1183 r->out.totalentries);
1186 /*******************************************************************
1188 ********************************************************************/
1190 WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r)
1192 struct sessionid *session_list;
1193 int num_sessions, snum;
1196 char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc);
1198 /* strip leading backslashes if any */
1199 while (machine[0] == '\\') {
1200 memmove(machine, &machine[1], strlen(machine));
1203 num_sessions = list_sessions(&session_list);
1205 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1207 status = WERR_ACCESS_DENIED;
1209 /* fail out now if you are not root or not a domain admin */
1211 if ((p->pipe_user.ut.uid != sec_initial_uid()) &&
1212 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1217 for (snum = 0; snum < num_sessions; snum++) {
1219 if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) &&
1220 strequal(session_list[snum].remote_machine, machine)) {
1222 if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)))
1227 DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1231 SAFE_FREE(session_list);
1236 /*******************************************************************
1238 ********************************************************************/
1240 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r)
1242 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1244 if (!pipe_access_check(p)) {
1245 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1246 return WERR_ACCESS_DENIED;
1249 /* Create the list of shares for the response. */
1250 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1251 r->in.resume_handle, r->out.totalentries, True);
1254 /*******************************************************************
1256 ********************************************************************/
1258 WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r)
1260 DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1262 if (!pipe_access_check(p)) {
1263 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1264 return WERR_ACCESS_DENIED;
1267 /* Create the list of shares for the response. */
1268 return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level,
1269 r->in.resume_handle, r->out.totalentries, False);
1272 /*******************************************************************
1274 ********************************************************************/
1276 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r)
1278 const struct share_params *params;
1280 params = get_share_params(p->mem_ctx, r->in.share_name);
1282 if (params != NULL) {
1283 switch (r->in.level) {
1285 r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1286 init_srv_share_info_0(p, r->out.info->info0, params);
1289 r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1290 init_srv_share_info_1(p, r->out.info->info1, params);
1293 r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1294 init_srv_share_info_2(p, r->out.info->info2, params);
1297 r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1298 init_srv_share_info_501(p, r->out.info->info501, params);
1301 r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1302 init_srv_share_info_502(p, r->out.info->info502, params);
1305 /* here for completeness */
1307 r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1308 init_srv_share_info_1004(p, r->out.info->info1004, params);
1311 r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1312 init_srv_share_info_1005(p, r->out.info->info1005, params);
1315 /* here for completeness 1006 - 1501 */
1317 r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1318 init_srv_share_info_1006(p, r->out.info->info1006,
1322 r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1323 init_srv_share_info_1007(p, r->out.info->info1007,
1327 r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1328 init_srv_share_info_1501(p, r->out.info->info1501,
1332 DEBUG(5,("init_srv_net_share_get_info: unsupported "
1333 "switch value %d\n", r->in.level));
1334 return WERR_UNKNOWN_LEVEL;
1338 return WERR_INVALID_NAME;
1344 /*******************************************************************
1345 Check a given DOS pathname is valid for a share.
1346 ********************************************************************/
1348 char *valid_share_pathname(char *dos_pathname)
1352 /* Convert any '\' paths to '/' */
1353 unix_format(dos_pathname);
1354 unix_clean_name(dos_pathname);
1356 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1358 if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1361 /* Only absolute paths allowed. */
1368 static void setval_helper(struct registry_key *key, const char *name,
1369 const char *value, WERROR *err)
1371 struct registry_value val;
1373 if (!W_ERROR_IS_OK(*err)) {
1379 val.v.sz.str = CONST_DISCARD(char *, value);
1380 val.v.sz.len = strlen(value)+1;
1382 *err = reg_setvalue(key, name, &val);
1385 static WERROR add_share(const char *share_name, const char *path,
1386 const char *comment, uint32 max_connections,
1387 const struct nt_user_token *token,
1390 if (lp_add_share_cmd() && *lp_add_share_cmd()) {
1394 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1395 lp_add_share_cmd(), dyn_CONFIGFILE, share_name,
1396 path, comment, max_connections) == -1) {
1400 DEBUG(10,("add_share: Running [%s]\n", command ));
1402 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1407 if ( (ret = smbrun(command, NULL)) == 0 ) {
1408 /* Tell everyone we updated smb.conf. */
1409 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1410 NULL, 0, False, NULL);
1416 /********* END SeDiskOperatorPrivilege BLOCK *********/
1418 DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n",
1422 * No fallback to registry shares, the user did define a add
1423 * share command, so fail here.
1427 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1430 if (lp_registry_shares()) {
1432 struct registry_key *key;
1433 enum winreg_CreateAction action;
1435 TALLOC_CTX *mem_ctx;
1437 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1442 mem_ctx = (TALLOC_CTX *)keyname;
1444 err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE,
1445 is_disk_op ? get_root_nt_token():token,
1448 if (action != REG_CREATED_NEW_KEY) {
1449 err = WERR_ALREADY_EXISTS;
1452 if (!W_ERROR_IS_OK(err)) {
1453 TALLOC_FREE(mem_ctx);
1457 setval_helper(key, "path", path, &err);
1458 if ((comment != NULL) && (comment[0] != '\0')) {
1459 setval_helper(key, "comment", comment, &err);
1461 if (max_connections != 0) {
1463 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1464 setval_helper(key, "max connections", tmp, &err);
1467 if (!W_ERROR_IS_OK(err)) {
1469 * Hmmmm. We'd need transactions on the registry to
1470 * get this right....
1472 reg_delete_path(is_disk_op ? get_root_nt_token():token,
1475 TALLOC_FREE(mem_ctx);
1479 return WERR_ACCESS_DENIED;
1482 static WERROR delete_share(const char *sharename,
1483 const struct nt_user_token *token,
1486 if (lp_delete_share_cmd() && *lp_delete_share_cmd()) {
1490 if (asprintf(&command, "%s \"%s\" \"%s\"",
1491 lp_delete_share_cmd(), dyn_CONFIGFILE,
1496 DEBUG(10,("delete_share: Running [%s]\n", command ));
1498 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1503 if ( (ret = smbrun(command, NULL)) == 0 ) {
1504 /* Tell everyone we updated smb.conf. */
1505 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1506 NULL, 0, False, NULL);
1512 /********* END SeDiskOperatorPrivilege BLOCK *********/
1516 DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n",
1518 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1521 if (lp_registry_shares()) {
1525 if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF,
1530 err = reg_delete_path(is_disk_op ? get_root_nt_token():token,
1536 return WERR_ACCESS_DENIED;
1539 static WERROR change_share(const char *share_name, const char *path,
1540 const char *comment, uint32 max_connections,
1541 const struct nt_user_token *token,
1544 if (lp_change_share_cmd() && *lp_change_share_cmd()) {
1548 if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1549 lp_change_share_cmd(), dyn_CONFIGFILE, share_name,
1550 path, comment, max_connections) == -1) {
1554 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command));
1556 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1561 if ( (ret = smbrun(command, NULL)) == 0 ) {
1562 /* Tell everyone we updated smb.conf. */
1563 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED,
1564 NULL, 0, False, NULL);
1570 /********* END SeDiskOperatorPrivilege BLOCK *********/
1572 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned "
1573 "(%d)\n", command, ret ));
1577 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
1580 if (lp_registry_shares()) {
1582 struct registry_key *key;
1584 TALLOC_CTX *mem_ctx;
1586 if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF,
1591 mem_ctx = (TALLOC_CTX *)keyname;
1593 err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE,
1594 is_disk_op ? get_root_nt_token():token,
1596 if (!W_ERROR_IS_OK(err)) {
1597 TALLOC_FREE(mem_ctx);
1601 setval_helper(key, "path", path, &err);
1603 reg_deletevalue(key, "comment");
1604 if ((comment != NULL) && (comment[0] != '\0')) {
1605 setval_helper(key, "comment", comment, &err);
1608 reg_deletevalue(key, "max connections");
1609 if (max_connections != 0) {
1611 snprintf(tmp, sizeof(tmp), "%d", max_connections);
1612 setval_helper(key, "max connections", tmp, &err);
1615 TALLOC_FREE(mem_ctx);
1619 return WERR_ACCESS_DENIED;
1622 /*******************************************************************
1623 Net share set info. Modify share details.
1624 ********************************************************************/
1626 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r)
1633 SEC_DESC *psd = NULL;
1634 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1635 BOOL is_disk_op = False;
1636 int max_connections = 0;
1637 fstring tmp_share_name;
1639 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1641 if (r->out.parm_error) {
1642 *r->out.parm_error = 0;
1645 if ( strequal(r->in.share_name,"IPC$")
1646 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1647 || strequal(r->in.share_name,"global") )
1649 return WERR_ACCESS_DENIED;
1652 fstrcpy(tmp_share_name, r->in.share_name);
1653 snum = find_service(tmp_share_name);
1655 /* Does this share exist ? */
1657 return WERR_NET_NAME_NOT_FOUND;
1659 /* No change to printer shares. */
1660 if (lp_print_ok(snum))
1661 return WERR_ACCESS_DENIED;
1663 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1666 /* fail out now if you are not root and not a disk op */
1668 if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1669 return WERR_ACCESS_DENIED;
1671 switch (r->in.level) {
1673 pstrcpy(pathname, lp_pathname(snum));
1674 pstrcpy(comment, r->in.info.info1->comment);
1675 type = r->in.info.info1->type;
1679 pstrcpy(comment, r->in.info.info2->comment);
1680 pstrcpy(pathname, r->in.info.info2->path);
1681 type = r->in.info.info2->type;
1682 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1683 0 : r->in.info.info2->max_users;
1687 pstrcpy(comment, r->in.info.info502->comment);
1688 pstrcpy(pathname, r->in.info.info502->path);
1689 type = r->in.info.info502->type;
1690 psd = r->in.info.info502->sd;
1691 map_generic_share_sd_bits(psd);
1694 pstrcpy(pathname, lp_pathname(snum));
1695 pstrcpy(comment, r->in.info.info1004->comment);
1696 type = STYPE_DISKTREE;
1699 /* XP re-sets the csc policy even if it wasn't changed by the
1700 user, so we must compare it to see if it's what is set in
1701 smb.conf, so that we can contine other ops like setting
1703 if (((r->in.info.info1005->dfs_flags &
1704 SHARE_1005_CSC_POLICY_MASK) >>
1705 SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1708 DEBUG(3, ("_srv_net_share_set_info: client is trying "
1709 "to change csc policy from the network; "
1710 "must be done with smb.conf\n"));
1711 return WERR_ACCESS_DENIED;
1715 return WERR_ACCESS_DENIED;
1717 pstrcpy(pathname, lp_pathname(snum));
1718 pstrcpy(comment, lp_comment(snum));
1719 psd = r->in.info.info1501->sd;
1720 map_generic_share_sd_bits(psd);
1721 type = STYPE_DISKTREE;
1724 DEBUG(5,("_srv_net_share_set_info: unsupported switch value "
1725 "%d\n", r->in.level));
1726 return WERR_UNKNOWN_LEVEL;
1729 /* We can only modify disk shares. */
1730 if (type != STYPE_DISKTREE)
1731 return WERR_ACCESS_DENIED;
1733 /* Check if the pathname is valid. */
1734 if (!(path = valid_share_pathname( pathname )))
1735 return WERR_OBJECT_PATH_INVALID;
1737 /* Ensure share name, pathname and comment don't contain '"'
1739 string_replace(tmp_share_name, '"', ' ');
1740 string_replace(path, '"', ' ');
1741 string_replace(comment, '"', ' ');
1743 DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1744 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1746 /* Only call modify function if something changed. */
1748 if (strcmp(path, lp_pathname(snum))
1749 || strcmp(comment, lp_comment(snum))
1750 || (lp_max_connections(snum) != max_connections) ) {
1753 err = change_share(tmp_share_name, path, comment,
1754 max_connections, p->pipe_user.nt_user_token,
1757 if (!W_ERROR_IS_OK(err)) {
1762 /* Replace SD if changed. */
1767 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1770 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1771 if (!set_share_security(r->in.share_name, psd)) {
1772 DEBUG(0,("_srv_net_share_set_info: Failed to "
1773 "change security info in share %s.\n",
1774 r->in.share_name ));
1779 DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1785 /*******************************************************************
1786 Net share add. Call 'add_share_command "sharename" "pathname"
1787 "comment" "max connections = "
1788 ********************************************************************/
1790 WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r)
1797 SEC_DESC *psd = NULL;
1798 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1800 uint32 max_connections = 0;
1803 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1805 if (r->out.parm_error) {
1806 *r->out.parm_error = 0;
1809 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1812 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1813 return WERR_ACCESS_DENIED;
1815 switch (r->in.level) {
1817 /* No path. Not enough info in a level 0 to do anything. */
1818 return WERR_ACCESS_DENIED;
1820 /* Not enough info in a level 1 to do anything. */
1821 return WERR_ACCESS_DENIED;
1823 pstrcpy(share_name, r->in.info.info2->name);
1824 pstrcpy(comment, r->in.info.info2->comment);
1825 pstrcpy(pathname, r->in.info.info2->path);
1826 max_connections = (r->in.info.info2->max_users == 0xffffffff) ?
1827 0 : r->in.info.info2->max_users;
1828 type = r->in.info.info2->type;
1831 /* No path. Not enough info in a level 501 to do anything. */
1832 return WERR_ACCESS_DENIED;
1834 pstrcpy(share_name, r->in.info.info502->name);
1835 pstrcpy(comment, r->in.info.info502->comment);
1836 pstrcpy(pathname, r->in.info.info502->path);
1837 type = r->in.info.info502->type;
1838 psd = r->in.info.info502->sd;
1839 map_generic_share_sd_bits(psd);
1842 /* none of the following contain share names. NetShareAdd
1843 * does not have a separate parameter for the share name */
1849 return WERR_ACCESS_DENIED;
1851 /* DFS only level. */
1852 return WERR_ACCESS_DENIED;
1854 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n",
1856 return WERR_UNKNOWN_LEVEL;
1859 /* check for invalid share names */
1861 if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS,
1862 sizeof(share_name) ) ) {
1863 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n",
1865 return WERR_INVALID_NAME;
1868 if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1869 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1871 return WERR_ACCESS_DENIED;
1874 if (get_share_params(p->mem_ctx, share_name) != NULL) {
1875 /* Share already exists. */
1876 return WERR_ALREADY_EXISTS;
1879 /* We can only add disk shares. */
1880 if (type != STYPE_DISKTREE)
1881 return WERR_ACCESS_DENIED;
1883 /* Check if the pathname is valid. */
1884 if (!(path = valid_share_pathname( pathname )))
1885 return WERR_OBJECT_PATH_INVALID;
1887 /* Ensure share name, pathname and comment don't contain '"'
1890 string_replace(share_name, '"', ' ');
1891 string_replace(path, '"', ' ');
1892 string_replace(comment, '"', ' ');
1894 err = add_share(share_name, path, comment, max_connections,
1895 p->pipe_user.nt_user_token, is_disk_op);
1897 if (!W_ERROR_IS_OK(err)) {
1902 if (!set_share_security(share_name, psd)) {
1903 DEBUG(0,("_srv_net_share_add: Failed to add security "
1904 "info to share %s.\n", share_name ));
1909 * We don't call reload_services() here, the message will
1910 * cause this to be done before the next packet is read
1911 * from the client. JRA.
1914 DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1919 /*******************************************************************
1920 Net share delete. Call "delete share command" with the share name as
1922 ********************************************************************/
1924 WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r)
1926 struct share_params *params;
1927 SE_PRIV se_diskop = SE_DISK_OPERATOR;
1931 DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1933 if ( strequal(r->in.share_name, "IPC$")
1934 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
1935 || strequal(r->in.share_name, "global") )
1937 return WERR_ACCESS_DENIED;
1940 if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) {
1941 return WERR_NO_SUCH_SHARE;
1944 /* No change to printer shares. */
1945 if (lp_print_ok(params->service))
1946 return WERR_ACCESS_DENIED;
1948 is_disk_op = user_has_privileges( p->pipe_user.nt_user_token,
1951 if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1952 return WERR_ACCESS_DENIED;
1954 err = delete_share(lp_servicename(params->service),
1955 p->pipe_user.nt_user_token, is_disk_op);
1957 if (!W_ERROR_IS_OK(err)) {
1961 /* Delete the SD in the database. */
1962 delete_share_security(params);
1964 lp_killservice(params->service);
1969 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r)
1971 struct srvsvc_NetShareDel s;
1973 DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1975 s.in.server_unc = r->in.server_unc;
1976 s.in.share_name = r->in.share_name;
1977 s.in.reserved = r->in.reserved;
1979 return _srvsvc_NetShareDel(p, &s);
1982 /*******************************************************************
1984 ********************************************************************/
1986 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r)
1989 time_t unixdate = time(NULL);
1990 WERROR status = WERR_OK;
1992 /* We do this call first as if we do it *after* the gmtime call
1993 it overwrites the pointed-to values. JRA */
1995 uint32 zone = get_time_zone(unixdate)/60;
1997 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1999 t = gmtime(&unixdate);
2002 r->out.info->elapsed = unixdate;
2003 r->out.info->msecs = 0;
2004 r->out.info->hours = t->tm_hour;
2005 r->out.info->mins = t->tm_min;
2006 r->out.info->secs = t->tm_sec;
2007 r->out.info->hunds = 0;
2008 r->out.info->timezone = zone;
2009 r->out.info->tinterval = 10000;
2010 r->out.info->day = t->tm_mday;
2011 r->out.info->month = t->tm_mon + 1;
2012 r->out.info->year = 1900+t->tm_year;
2013 r->out.info->weekday = t->tm_wday;
2015 DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
2020 /***********************************************************************************
2021 Win9x NT tools get security descriptor.
2022 ***********************************************************************************/
2024 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r)
2026 SEC_DESC *psd = NULL;
2029 files_struct *fsp = NULL;
2032 connection_struct *conn = NULL;
2033 BOOL became_user = False;
2034 WERROR status = WERR_OK;
2040 /* Null password is ok - we are already an authenticated user... */
2041 null_pw = data_blob(NULL, 0);
2044 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2048 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share));
2049 status = ntstatus_to_werror(nt_status);
2053 if (!become_user(conn, conn->vuid)) {
2054 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
2055 status = WERR_ACCESS_DENIED;
2060 pstrcpy(tmp_file, r->in.file);
2061 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2062 if (!NT_STATUS_IS_OK(nt_status)) {
2063 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file));
2064 status = WERR_ACCESS_DENIED;
2068 nt_status = check_name(conn, r->in.file);
2069 if (!NT_STATUS_IS_OK(nt_status)) {
2070 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", r->in.file));
2071 status = WERR_ACCESS_DENIED;
2075 nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2076 if (!NT_STATUS_IS_OK(nt_status)) {
2077 /* Perhaps it is a directory */
2078 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2079 nt_status = open_directory(conn, r->in.file, &st,
2080 READ_CONTROL_ACCESS,
2081 FILE_SHARE_READ|FILE_SHARE_WRITE,
2084 FILE_ATTRIBUTE_DIRECTORY,
2087 if (!NT_STATUS_IS_OK(nt_status)) {
2088 DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", r->in.file));
2089 status = WERR_ACCESS_DENIED;
2094 sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
2097 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", r->in.file));
2098 status = WERR_ACCESS_DENIED;
2102 r->out.sd_buf->sd_size= sd_size;
2103 r->out.sd_buf->sd = psd;
2105 psd->dacl->revision = (uint16) NT4_ACL_REVISION;
2107 close_file(fsp, NORMAL_CLOSE);
2109 close_cnum(conn, p->pipe_user.vuid);
2115 close_file(fsp, NORMAL_CLOSE);
2122 close_cnum(conn, p->pipe_user.vuid);
2127 /***********************************************************************************
2128 Win9x NT tools set security descriptor.
2129 ***********************************************************************************/
2131 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r)
2135 files_struct *fsp = NULL;
2138 connection_struct *conn = NULL;
2139 BOOL became_user = False;
2140 WERROR status = WERR_OK;
2145 /* Null password is ok - we are already an authenticated user... */
2146 null_pw = data_blob(NULL, 0);
2149 conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
2153 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share));
2154 status = ntstatus_to_werror(nt_status);
2158 if (!become_user(conn, conn->vuid)) {
2159 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
2160 status = WERR_ACCESS_DENIED;
2165 pstrcpy(tmp_file, r->in.file);
2166 nt_status = unix_convert(conn, tmp_file, False, NULL, &st);
2167 if (!NT_STATUS_IS_OK(nt_status)) {
2168 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file));
2169 status = WERR_ACCESS_DENIED;
2173 nt_status = check_name(conn, r->in.file);
2174 if (!NT_STATUS_IS_OK(nt_status)) {
2175 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", r->in.file));
2176 status = WERR_ACCESS_DENIED;
2181 nt_status = open_file_stat(conn, r->in.file, &st, &fsp);
2183 if (!NT_STATUS_IS_OK(nt_status)) {
2184 /* Perhaps it is a directory */
2185 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
2186 nt_status = open_directory(conn, r->in.file, &st,
2187 FILE_READ_ATTRIBUTES,
2188 FILE_SHARE_READ|FILE_SHARE_WRITE,
2191 FILE_ATTRIBUTE_DIRECTORY,
2194 if (!NT_STATUS_IS_OK(nt_status)) {
2195 DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", r->in.file));
2196 status = WERR_ACCESS_DENIED;
2201 ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd);
2204 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file));
2205 status = WERR_ACCESS_DENIED;
2209 close_file(fsp, NORMAL_CLOSE);
2211 close_cnum(conn, p->pipe_user.vuid);
2217 close_file(fsp, NORMAL_CLOSE);
2225 close_cnum(conn, p->pipe_user.vuid);
2231 /***********************************************************************************
2232 It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2233 We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2234 These disks would the disks listed by this function.
2235 Users could then create shares relative to these disks. Watch out for moving these disks around.
2236 "Nigel Williams" <nigel@veritas.com>.
2237 ***********************************************************************************/
2239 static const char *server_disks[] = {"C:"};
2241 static uint32 get_server_disk_count(void)
2243 return sizeof(server_disks)/sizeof(server_disks[0]);
2246 static uint32 init_server_disk_enum(uint32 *resume)
2248 uint32 server_disk_count = get_server_disk_count();
2250 /*resume can be an offset into the list for now*/
2252 if(*resume & 0x80000000)
2255 if(*resume > server_disk_count)
2256 *resume = server_disk_count;
2258 return server_disk_count - *resume;
2261 static const char *next_server_disk_enum(uint32 *resume)
2265 if(init_server_disk_enum(resume) == 0)
2268 disk = server_disks[*resume];
2272 DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2277 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r)
2280 const char *disk_name;
2282 WERROR status = WERR_OK;
2284 *r->out.totalentries = init_server_disk_enum(r->in.resume_handle);
2285 r->out.info->count = 0;
2287 if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2291 /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2293 for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) {
2295 r->out.info->count++;
2296 (*r->out.totalentries)++;
2298 /*copy disk name into a unicode string*/
2300 r->out.info->disks[i].disk = disk_name;
2303 /* add a terminating null string. Is this there if there is more data to come? */
2305 r->out.info->count++;
2306 (*r->out.totalentries)++;
2308 r->out.info->disks[i].disk = "";
2313 /********************************************************************
2314 ********************************************************************/
2316 WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r)
2320 if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) {
2321 return WERR_INVALID_PARAM;
2324 switch ( r->in.name_type ) {
2326 len = strlen_m(r->in.name);
2328 if ((r->in.flags == 0x0) && (len > 81)) {
2329 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name));
2330 return WERR_INVALID_NAME;
2332 if ((r->in.flags == 0x80000000) && (len > 13)) {
2333 DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name));
2334 return WERR_INVALID_NAME;
2337 if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) {
2338 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name));
2339 return WERR_INVALID_NAME;
2344 return WERR_UNKNOWN_LEVEL;
2351 /********************************************************************
2352 ********************************************************************/
2354 WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
2356 return WERR_ACCESS_DENIED;
2359 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r)
2361 p->rng_fault_state = True;
2362 return WERR_NOT_SUPPORTED;
2365 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, struct srvsvc_NetCharDevGetInfo *r)
2367 p->rng_fault_state = True;
2368 return WERR_NOT_SUPPORTED;
2371 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, struct srvsvc_NetCharDevControl *r)
2373 p->rng_fault_state = True;
2374 return WERR_NOT_SUPPORTED;
2377 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, struct srvsvc_NetCharDevQEnum *r)
2379 p->rng_fault_state = True;
2380 return WERR_NOT_SUPPORTED;
2383 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, struct srvsvc_NetCharDevQGetInfo *r)
2385 p->rng_fault_state = True;
2386 return WERR_NOT_SUPPORTED;
2389 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, struct srvsvc_NetCharDevQSetInfo *r)
2391 p->rng_fault_state = True;
2392 return WERR_NOT_SUPPORTED;
2395 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, struct srvsvc_NetCharDevQPurge *r)
2397 p->rng_fault_state = True;
2398 return WERR_NOT_SUPPORTED;
2401 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPurgeSelf *r)
2403 p->rng_fault_state = True;
2404 return WERR_NOT_SUPPORTED;
2407 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r)
2409 p->rng_fault_state = True;
2410 return WERR_NOT_SUPPORTED;
2413 WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r)
2415 p->rng_fault_state = True;
2416 return WERR_NOT_SUPPORTED;
2419 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r)
2421 p->rng_fault_state = True;
2422 return WERR_NOT_SUPPORTED;
2425 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, struct srvsvc_NetTransportAdd *r)
2427 p->rng_fault_state = True;
2428 return WERR_NOT_SUPPORTED;
2431 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, struct srvsvc_NetTransportEnum *r)
2433 p->rng_fault_state = True;
2434 return WERR_NOT_SUPPORTED;
2437 WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r)
2439 p->rng_fault_state = True;
2440 return WERR_NOT_SUPPORTED;
2443 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r)
2445 p->rng_fault_state = True;
2446 return WERR_NOT_SUPPORTED;
2449 WERROR _srvsvc_NetPathType(pipes_struct *p, struct srvsvc_NetPathType *r)
2451 p->rng_fault_state = True;
2452 return WERR_NOT_SUPPORTED;
2455 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, struct srvsvc_NetPathCanonicalize *r)
2457 p->rng_fault_state = True;
2458 return WERR_NOT_SUPPORTED;
2461 WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r)
2463 p->rng_fault_state = True;
2464 return WERR_NOT_SUPPORTED;
2467 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r)
2469 p->rng_fault_state = True;
2470 return WERR_NOT_SUPPORTED;
2473 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare *r)
2475 p->rng_fault_state = True;
2476 return WERR_NOT_SUPPORTED;
2479 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r)
2481 p->rng_fault_state = True;
2482 return WERR_NOT_SUPPORTED;
2485 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommit *r)
2487 p->rng_fault_state = True;
2488 return WERR_NOT_SUPPORTED;
2491 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r)
2493 p->rng_fault_state = True;
2494 return WERR_NOT_SUPPORTED;
2497 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, struct srvsvc_NetServerSetServiceBitsEx *r)
2499 p->rng_fault_state = True;
2500 return WERR_NOT_SUPPORTED;
2503 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p, struct srvsvc_NETRDFSGETVERSION *r)
2505 p->rng_fault_state = True;
2506 return WERR_NOT_SUPPORTED;
2509 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
2511 p->rng_fault_state = True;
2512 return WERR_NOT_SUPPORTED;
2515 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
2517 p->rng_fault_state = True;
2518 return WERR_NOT_SUPPORTED;
2521 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R)
2523 p->rng_fault_state = True;
2524 return WERR_NOT_SUPPORTED;
2527 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p, struct srvsvc_NETRDFSSETSERVERINFO *r)
2529 p->rng_fault_state = True;
2530 return WERR_NOT_SUPPORTED;
2533 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSCREATEEXITPOINT *r)
2535 p->rng_fault_state = True;
2536 return WERR_NOT_SUPPORTED;
2539 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELETEEXITPOINT *r)
2541 p->rng_fault_state = True;
2542 return WERR_NOT_SUPPORTED;
2545 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
2547 p->rng_fault_state = True;
2548 return WERR_NOT_SUPPORTED;
2551 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
2553 p->rng_fault_state = True;
2554 return WERR_NOT_SUPPORTED;
2557 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r)
2559 p->rng_fault_state = True;
2560 return WERR_NOT_SUPPORTED;
2563 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
2565 p->rng_fault_state = True;
2566 return WERR_NOT_SUPPORTED;