switch4g: completely re-writen
[tomato.git] / release / src / router / vsftpd / oneprocess.c
blob5dbabeaad461dd5632e580b8840ff98840c93039
1 /*
2 * Part of Very Secure FTPd
3 * Licence: GPL v2
4 * Author: Chris Evans
5 * oneprocess.c
7 * Code for the "one process" security model. The one process security model
8 * is born for the purposes of raw speed at the expense of compromising the
9 * purity of the security model.
10 * The one process model will typically be disabled, for security reasons.
11 * Only sites with huge numbers of concurrent users are likely to feel the
12 * pain of two processes per session.
15 #include "prelogin.h"
16 #include "postlogin.h"
17 #include "privops.h"
18 #include "session.h"
19 #include "secutil.h"
20 #include "str.h"
21 #include "tunables.h"
22 #include "utility.h"
23 #include "sysstr.h"
24 #include "sysdeputil.h"
25 #include "sysutil.h"
26 #include "ptracesandbox.h"
27 #include "ftppolicy.h"
29 static void one_process_start(void* p_arg);
31 void
32 vsf_one_process_start(struct vsf_session* p_sess)
34 if (tunable_sandbox)
36 struct pt_sandbox* p_sandbox = ptrace_sandbox_alloc();
37 if (p_sandbox == 0)
39 die("could not allocate sandbox (only works for 32-bit builds)");
41 policy_setup(p_sandbox, p_sess);
42 if (ptrace_sandbox_launch_process(p_sandbox,
43 one_process_start,
44 (void*) p_sess) <= 0)
46 die("could not launch sandboxed child");
48 /* TODO - could drop privs here. For now, run as root as the attack surface
49 * is negligible, and running as root permits us to correctly deliver the
50 * parent death signal upon unexpected crash.
52 (void) ptrace_sandbox_run_processes(p_sandbox);
53 ptrace_sandbox_free(p_sandbox);
54 vsf_sysutil_exit(0);
56 else
58 one_process_start((void*) p_sess);
62 static void
63 one_process_start(void* p_arg)
65 struct vsf_session* p_sess = (struct vsf_session*) p_arg;
66 unsigned int caps = 0;
67 if (tunable_chown_uploads)
69 caps |= kCapabilityCAP_CHOWN;
71 if (tunable_connect_from_port_20)
73 caps |= kCapabilityCAP_NET_BIND_SERVICE;
76 struct mystr user_name = INIT_MYSTR;
77 struct mystr chdir_str = INIT_MYSTR;
78 str_alloc_text(&user_name, tunable_ftp_username);
79 if (tunable_anon_root)
81 str_alloc_text(&chdir_str, tunable_anon_root);
83 if (tunable_run_as_launching_user)
85 if (!str_isempty(&chdir_str))
87 str_chdir(&chdir_str);
90 else
92 vsf_secutil_change_credentials(&user_name, 0, &chdir_str, caps,
93 VSF_SECUTIL_OPTION_CHROOT |
94 VSF_SECUTIL_OPTION_USE_GROUPS |
95 VSF_SECUTIL_OPTION_NO_PROCS);
97 str_free(&user_name);
98 str_free(&chdir_str);
100 if (tunable_sandbox)
102 ptrace_sandbox_attach_point();
104 init_connection(p_sess);
107 void
108 vsf_one_process_login(struct vsf_session* p_sess,
109 const struct mystr* p_pass_str)
111 enum EVSFPrivopLoginResult login_result =
112 vsf_privop_do_login(p_sess, p_pass_str);
113 switch (login_result)
115 case kVSFLoginFail:
116 return;
117 break;
118 case kVSFLoginAnon:
119 p_sess->is_anonymous = 1;
120 process_post_login(p_sess);
121 break;
122 default:
123 bug("bad state in vsf_one_process_login");
124 break;
129 vsf_one_process_get_priv_data_sock(struct vsf_session* p_sess)
131 unsigned short port = vsf_sysutil_sockaddr_get_port(p_sess->p_port_sockaddr);
132 return vsf_privop_get_ftp_port_sock(p_sess, port, 1);
135 void
136 vsf_one_process_pasv_cleanup(struct vsf_session* p_sess)
138 vsf_privop_pasv_cleanup(p_sess);
142 vsf_one_process_pasv_active(struct vsf_session* p_sess)
144 return vsf_privop_pasv_active(p_sess);
147 unsigned short
148 vsf_one_process_listen(struct vsf_session* p_sess)
150 return vsf_privop_pasv_listen(p_sess);
154 vsf_one_process_get_pasv_fd(struct vsf_session* p_sess)
156 return vsf_privop_accept_pasv(p_sess);
159 void
160 vsf_one_process_chown_upload(struct vsf_session* p_sess, int fd)
162 vsf_privop_do_file_chown(p_sess, fd);