2 * Part of Very Secure FTPd
13 #include "sysdeputil.h"
16 vsf_secutil_change_credentials(const struct mystr
* p_user_str
,
17 const struct mystr
* p_dir_str
,
18 const struct mystr
* p_ext_dir_str
,
19 unsigned int caps
, unsigned int options
)
21 struct vsf_sysutil_user
* p_user
;
22 if (!vsf_sysutil_running_as_root())
24 bug("vsf_secutil_change_credentials: not running as root");
26 p_user
= str_getpwnam(p_user_str
);
29 die2("cannot locate user entry:", str_getbuf(p_user_str
));
32 struct mystr dir_str
= INIT_MYSTR
;
33 /* Work out where the chroot() jail is */
34 if (p_dir_str
== 0 || str_isempty(p_dir_str
))
36 str_alloc_text(&dir_str
, vsf_sysutil_user_get_homedir(p_user
));
40 str_copy(&dir_str
, p_dir_str
);
42 /* Sort out supplementary groups before the chroot(). We need to access
45 if (options
& VSF_SECUTIL_OPTION_USE_GROUPS
)
47 vsf_sysutil_initgroups(p_user
);
51 vsf_sysutil_clear_supp_groups();
53 /* Always do the chdir() regardless of whether we are chroot()'ing */
55 /* Do chdir() with the target effective IDs to cater for NFS mounted
61 if (options
& VSF_SECUTIL_OPTION_CHANGE_EUID
)
63 saved_euid
= vsf_sysutil_geteuid();
64 saved_egid
= vsf_sysutil_getegid();
65 vsf_sysutil_setegid(p_user
);
66 vsf_sysutil_seteuid(p_user
);
68 retval
= str_chdir(&dir_str
);
71 die2("cannot change directory:", str_getbuf(&dir_str
));
73 if (p_ext_dir_str
&& !str_isempty(p_ext_dir_str
))
75 retval
= str_chdir(p_ext_dir_str
);
76 /* Failure on the extra directory is OK as long as we're not in
79 if (retval
!= 0 && !(options
& VSF_SECUTIL_OPTION_CHROOT
))
86 die2("cannot change directory:", str_getbuf(p_ext_dir_str
));
88 if (options
& VSF_SECUTIL_OPTION_CHANGE_EUID
)
90 vsf_sysutil_seteuid_numeric(saved_euid
);
91 vsf_sysutil_setegid_numeric(saved_egid
);
93 /* Do the chroot() if required */
94 if (options
& VSF_SECUTIL_OPTION_CHROOT
)
96 vsf_sysutil_chroot(".");
101 /* Handle capabilities */
104 if (!vsf_sysdep_has_capabilities())
106 /* Need privilege but OS has no capabilities - have to keep root */
109 if (!vsf_sysdep_has_capabilities_as_non_root())
111 vsf_sysdep_adopt_capabilities(caps
);
114 vsf_sysdep_keep_capabilities();
117 vsf_sysutil_setgid(p_user
);
118 /* Finally set user id */
119 vsf_sysutil_setuid(p_user
);
122 vsf_sysdep_adopt_capabilities(caps
);