2 * Part of Very Secure FTPd
7 * This file contains all privileged parent services offered after logging
8 * in. This includes e.g. chown() of uploaded files, issuing of port 20
12 #include "postprivparent.h"
23 #include "sysdeputil.h"
25 static void minimize_privilege(struct vsf_session
* p_sess
);
26 static void process_post_login_req(struct vsf_session
* p_sess
);
27 static void cmd_process_chown(struct vsf_session
* p_sess
);
28 static void cmd_process_get_data_sock(struct vsf_session
* p_sess
);
31 vsf_priv_parent_postlogin(struct vsf_session
* p_sess
)
33 minimize_privilege(p_sess
);
34 /* We're still here... */
37 process_post_login_req(p_sess
);
42 process_post_login_req(struct vsf_session
* p_sess
)
45 vsf_sysutil_unblock_sig(kVSFSysUtilSigCHLD
);
47 cmd
= priv_sock_get_cmd(p_sess
->parent_fd
);
48 vsf_sysutil_block_sig(kVSFSysUtilSigCHLD
);
49 if (tunable_chown_uploads
&& cmd
== PRIV_SOCK_CHOWN
)
51 cmd_process_chown(p_sess
);
53 else if (tunable_connect_from_port_20
&& cmd
== PRIV_SOCK_GET_DATA_SOCK
)
55 cmd_process_get_data_sock(p_sess
);
59 die("bad request in process_post_login_req");
64 minimize_privilege(struct vsf_session
* p_sess
)
66 /* So, we logged in and forked a totally unprivileged child. Our job
67 * now is to minimize the privilege we need in order to act as a helper
70 * In some happy circumstances, we can exit and be done with root
73 if (!p_sess
->is_anonymous
&& tunable_session_support
)
75 /* Need to hang around to update logs, utmp, wtmp etc. on logout.
76 * Need to keep privs to do this. */
79 if (!tunable_chown_uploads
&& !tunable_connect_from_port_20
&&
80 !tunable_max_per_ip
&& !tunable_max_clients
)
82 /* Cool. We're outta here. */
86 unsigned int caps
= 0;
87 struct mystr user_str
= INIT_MYSTR
;
88 struct mystr dir_str
= INIT_MYSTR
;
89 str_alloc_text(&user_str
, tunable_nopriv_user
);
90 str_alloc_text(&dir_str
, tunable_secure_chroot_dir
);
91 if (tunable_chown_uploads
)
93 caps
|= kCapabilityCAP_CHOWN
;
95 if (tunable_connect_from_port_20
)
97 caps
|= kCapabilityCAP_NET_BIND_SERVICE
;
99 vsf_secutil_change_credentials(&user_str
, &dir_str
, 0, caps
,
100 VSF_SECUTIL_OPTION_CHROOT
);
107 cmd_process_chown(struct vsf_session
* p_sess
)
109 int the_fd
= priv_sock_recv_fd(p_sess
->parent_fd
);
110 vsf_privop_do_file_chown(p_sess
, the_fd
);
111 vsf_sysutil_close(the_fd
);
112 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_OK
);
116 cmd_process_get_data_sock(struct vsf_session
* p_sess
)
118 int sock_fd
= vsf_privop_get_ftp_port_sock(p_sess
);
119 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_OK
);
120 priv_sock_send_fd(p_sess
->parent_fd
, sock_fd
);
121 vsf_sysutil_close(sock_fd
);