diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-19 13:24:13 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-19 13:24:13 +0000 |
commit | 7a60133c6c27d55a0bf87287eb3cf425ed483010 (patch) | |
tree | 5f613dd97c8df99a9a765927e92f9b14ce308db2 | |
parent | 403a5a298eaa5d1d827ad6ebbf38a7b765ba5b44 (diff) | |
download | busybox-w32-7a60133c6c27d55a0bf87287eb3cf425ed483010.tar.gz busybox-w32-7a60133c6c27d55a0bf87287eb3cf425ed483010.tar.bz2 busybox-w32-7a60133c6c27d55a0bf87287eb3cf425ed483010.zip |
tftpd: fix download: we must change user AFTER bind
tftp_protocol 1466 1468 +2
-rw-r--r-- | networking/tftp.c | 79 |
1 files changed, 42 insertions, 37 deletions
diff --git a/networking/tftp.c b/networking/tftp.c index 5fac48769..bea215c01 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -83,9 +83,7 @@ enum { | |||
83 | struct globals { | 83 | struct globals { |
84 | /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */ | 84 | /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */ |
85 | uint8_t error_pkt[4 + 32]; | 85 | uint8_t error_pkt[4 + 32]; |
86 | #if ENABLE_TFTPD | ||
87 | char *user_opt; | 86 | char *user_opt; |
88 | #endif | ||
89 | /* used in tftpd_main(), a bit big for stack: */ | 87 | /* used in tftpd_main(), a bit big for stack: */ |
90 | char block_buf[TFTP_BLKSIZE_DEFAULT]; | 88 | char block_buf[TFTP_BLKSIZE_DEFAULT]; |
91 | }; | 89 | }; |
@@ -183,7 +181,7 @@ static int tftp_protocol( | |||
183 | int open_mode, local_fd; | 181 | int open_mode, local_fd; |
184 | int retries, waittime_ms; | 182 | int retries, waittime_ms; |
185 | int io_bufsize = blksize + 4; | 183 | int io_bufsize = blksize + 4; |
186 | char *cp; | 184 | char *cp = cp; /* for compiler */ |
187 | /* Can't use RESERVE_CONFIG_BUFFER here since the allocation | 185 | /* Can't use RESERVE_CONFIG_BUFFER here since the allocation |
188 | * size varies meaning BUFFERS_GO_ON_STACK would fail */ | 186 | * size varies meaning BUFFERS_GO_ON_STACK would fail */ |
189 | /* We must keep the transmit and receive buffers seperate */ | 187 | /* We must keep the transmit and receive buffers seperate */ |
@@ -194,40 +192,8 @@ static int tftp_protocol( | |||
194 | socket_fd = xsocket(peer_lsa->u.sa.sa_family, SOCK_DGRAM, 0); | 192 | socket_fd = xsocket(peer_lsa->u.sa.sa_family, SOCK_DGRAM, 0); |
195 | setsockopt_reuseaddr(socket_fd); | 193 | setsockopt_reuseaddr(socket_fd); |
196 | 194 | ||
197 | #if ENABLE_TFTPD | ||
198 | if (user_opt) { | ||
199 | struct passwd *pw = getpwnam(user_opt); /* initgroups, setgid, setuid */ | ||
200 | if (!pw) | ||
201 | bb_error_msg_and_die("unknown user '%s'", user_opt); | ||
202 | change_identity(pw); | ||
203 | } | ||
204 | #endif | ||
205 | |||
206 | if (CMD_PUT(option_mask32)) { | ||
207 | open_mode = O_RDONLY; | ||
208 | } else { | ||
209 | open_mode = O_WRONLY | O_TRUNC | O_CREAT; | ||
210 | #if ENABLE_TFTPD | ||
211 | if ((option_mask32 & (TFTPD_OPT+TFTPD_OPT_c)) == TFTPD_OPT) { | ||
212 | /* tftpd without -c */ | ||
213 | open_mode = O_WRONLY | O_TRUNC; | ||
214 | } | ||
215 | #endif | ||
216 | } | ||
217 | if (!(option_mask32 & TFTPD_OPT)) { | ||
218 | local_fd = CMD_GET(option_mask32) ? STDOUT_FILENO : STDIN_FILENO; | ||
219 | if (NOT_LONE_DASH(local_file)) | ||
220 | local_fd = xopen(local_file, open_mode); | ||
221 | } else { | ||
222 | local_fd = open_or_warn(local_file, open_mode); | ||
223 | if (local_fd < 0) { | ||
224 | /*error_pkt_reason = ERR_NOFILE/ERR_ACCESS?*/ | ||
225 | strcpy(error_pkt_str, "can't open file"); | ||
226 | goto send_err_pkt; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | block_nr = 1; | 195 | block_nr = 1; |
196 | |||
231 | if (!ENABLE_TFTP || our_lsa) { | 197 | if (!ENABLE_TFTP || our_lsa) { |
232 | /* tftpd */ | 198 | /* tftpd */ |
233 | 199 | ||
@@ -258,9 +224,48 @@ static int tftp_protocol( | |||
258 | * that is, for "block 0" which is our OACK pkt */ | 224 | * that is, for "block 0" which is our OACK pkt */ |
259 | opcode = TFTP_OACK; | 225 | opcode = TFTP_OACK; |
260 | cp = xbuf + 2; | 226 | cp = xbuf + 2; |
227 | /* to be continued, see below */ | ||
228 | } | ||
229 | #endif | ||
230 | if (user_opt) { | ||
231 | struct passwd *pw = getpwnam(user_opt); | ||
232 | if (!pw) | ||
233 | bb_error_msg_and_die("unknown user '%s'", user_opt); | ||
234 | change_identity(pw); /* initgroups, setgid, setuid */ | ||
235 | } | ||
236 | } | ||
237 | |||
238 | /* Open local file (must be after changing user) */ | ||
239 | if (CMD_PUT(option_mask32)) { | ||
240 | open_mode = O_RDONLY; | ||
241 | } else { | ||
242 | open_mode = O_WRONLY | O_TRUNC | O_CREAT; | ||
243 | #if ENABLE_TFTPD | ||
244 | if ((option_mask32 & (TFTPD_OPT+TFTPD_OPT_c)) == TFTPD_OPT) { | ||
245 | /* tftpd without -c */ | ||
246 | open_mode = O_WRONLY | O_TRUNC; | ||
247 | } | ||
248 | #endif | ||
249 | } | ||
250 | if (!(option_mask32 & TFTPD_OPT)) { | ||
251 | local_fd = CMD_GET(option_mask32) ? STDOUT_FILENO : STDIN_FILENO; | ||
252 | if (NOT_LONE_DASH(local_file)) | ||
253 | local_fd = xopen(local_file, open_mode); | ||
254 | } else { | ||
255 | local_fd = open_or_warn(local_file, open_mode); | ||
256 | if (local_fd < 0) { | ||
257 | /*error_pkt_reason = ERR_NOFILE/ERR_ACCESS?*/ | ||
258 | strcpy(error_pkt_str, "can't open file"); | ||
259 | goto send_err_pkt; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | if (!ENABLE_TFTP || our_lsa) { | ||
264 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | ||
265 | if (blksize != TFTP_BLKSIZE_DEFAULT) { | ||
266 | /* Create and send OACK packet. continued */ | ||
261 | goto add_blksize_opt; | 267 | goto add_blksize_opt; |
262 | } | 268 | } |
263 | /* else: just fall into while (1) loop below */ | ||
264 | #endif | 269 | #endif |
265 | } else { | 270 | } else { |
266 | /* tftp */ | 271 | /* tftp */ |