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
);
29 static void cmd_process_pasv_cleanup(struct vsf_session
* p_sess
);
30 static void cmd_process_pasv_active(struct vsf_session
* p_sess
);
31 static void cmd_process_pasv_listen(struct vsf_session
* p_sess
);
32 static void cmd_process_pasv_accept(struct vsf_session
* p_sess
);
35 vsf_priv_parent_postlogin(struct vsf_session
* p_sess
)
37 minimize_privilege(p_sess
);
38 /* We're still here... */
41 process_post_login_req(p_sess
);
46 process_post_login_req(struct vsf_session
* p_sess
)
50 cmd
= priv_sock_get_cmd(p_sess
->parent_fd
);
51 if (tunable_chown_uploads
&& cmd
== PRIV_SOCK_CHOWN
)
53 cmd_process_chown(p_sess
);
55 else if (cmd
== PRIV_SOCK_GET_DATA_SOCK
)
57 cmd_process_get_data_sock(p_sess
);
59 else if (cmd
== PRIV_SOCK_PASV_CLEANUP
)
61 cmd_process_pasv_cleanup(p_sess
);
63 else if (cmd
== PRIV_SOCK_PASV_ACTIVE
)
65 cmd_process_pasv_active(p_sess
);
67 else if (cmd
== PRIV_SOCK_PASV_LISTEN
)
69 cmd_process_pasv_listen(p_sess
);
71 else if (cmd
== PRIV_SOCK_PASV_ACCEPT
)
73 cmd_process_pasv_accept(p_sess
);
77 die("bad request in process_post_login_req");
82 minimize_privilege(struct vsf_session
* p_sess
)
84 /* So, we logged in and forked a totally unprivileged child. Our job
85 * now is to minimize the privilege we need in order to act as a helper
88 if (!p_sess
->is_anonymous
&& tunable_session_support
)
90 /* Need to hang around to update logs, utmp, wtmp etc. on logout.
91 * Need to keep privs to do this. */
95 unsigned int caps
= 0;
96 struct mystr user_str
= INIT_MYSTR
;
97 struct mystr dir_str
= INIT_MYSTR
;
98 str_alloc_text(&user_str
, tunable_nopriv_user
);
99 str_alloc_text(&dir_str
, tunable_secure_chroot_dir
);
100 if (tunable_chown_uploads
)
102 caps
|= kCapabilityCAP_CHOWN
;
104 if (tunable_connect_from_port_20
)
106 caps
|= kCapabilityCAP_NET_BIND_SERVICE
;
108 vsf_secutil_change_credentials(&user_str
, &dir_str
, 0, caps
,
109 VSF_SECUTIL_OPTION_CHROOT
);
116 cmd_process_chown(struct vsf_session
* p_sess
)
118 int the_fd
= priv_sock_recv_fd(p_sess
->parent_fd
);
119 vsf_privop_do_file_chown(p_sess
, the_fd
);
120 vsf_sysutil_close(the_fd
);
121 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_OK
);
125 cmd_process_get_data_sock(struct vsf_session
* p_sess
)
127 unsigned short port
= (unsigned short) priv_sock_get_int(p_sess
->parent_fd
);
128 int sock_fd
= vsf_privop_get_ftp_port_sock(p_sess
, port
, 0);
131 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_BAD
);
134 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_OK
);
135 priv_sock_send_fd(p_sess
->parent_fd
, sock_fd
);
136 vsf_sysutil_close(sock_fd
);
140 cmd_process_pasv_cleanup(struct vsf_session
* p_sess
)
142 vsf_privop_pasv_cleanup(p_sess
);
143 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_OK
);
147 cmd_process_pasv_active(struct vsf_session
* p_sess
)
149 int active
= vsf_privop_pasv_active(p_sess
);
150 priv_sock_send_int(p_sess
->parent_fd
, active
);
154 cmd_process_pasv_listen(struct vsf_session
* p_sess
)
156 unsigned short port
= vsf_privop_pasv_listen(p_sess
);
157 priv_sock_send_int(p_sess
->parent_fd
, port
);
161 cmd_process_pasv_accept(struct vsf_session
* p_sess
)
163 int fd
= vsf_privop_accept_pasv(p_sess
);
166 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_BAD
);
167 priv_sock_send_int(p_sess
->parent_fd
, fd
);
170 priv_sock_send_result(p_sess
->parent_fd
, PRIV_SOCK_RESULT_OK
);
171 priv_sock_send_fd(p_sess
->parent_fd
, fd
);
172 vsf_sysutil_close(fd
);