diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-19 16:24:13 +0300 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-19 16:24:13 +0300 |
commit | 7a60133c6c27d55a0bf87287eb3cf425ed483010 (patch) | |
tree | 5f613dd97c8df99a9a765927e92f9b14ce308db2 /networking | |
parent | 403a5a298eaa5d1d827ad6ebbf38a7b765ba5b44 (diff) |
tftpd: fix download: we must change user AFTER bind
tftp_protocol 1466 1468 +2
Diffstat (limited to 'networking')
-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 { struct globals { /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */ uint8_t error_pkt[4 + 32]; -#if ENABLE_TFTPD char *user_opt; -#endif /* used in tftpd_main(), a bit big for stack: */ char block_buf[TFTP_BLKSIZE_DEFAULT]; }; @@ -183,7 +181,7 @@ static int tftp_protocol( int open_mode, local_fd; int retries, waittime_ms; int io_bufsize = blksize + 4; - char *cp; + char *cp = cp; /* for compiler */ /* Can't use RESERVE_CONFIG_BUFFER here since the allocation * size varies meaning BUFFERS_GO_ON_STACK would fail */ /* We must keep the transmit and receive buffers seperate */ @@ -194,40 +192,8 @@ static int tftp_protocol( socket_fd = xsocket(peer_lsa->u.sa.sa_family, SOCK_DGRAM, 0); setsockopt_reuseaddr(socket_fd); -#if ENABLE_TFTPD - if (user_opt) { - struct passwd *pw = getpwnam(user_opt); /* initgroups, setgid, setuid */ - if (!pw) - bb_error_msg_and_die("unknown user '%s'", user_opt); - change_identity(pw); - } -#endif - - if (CMD_PUT(option_mask32)) { - open_mode = O_RDONLY; - } else { - open_mode = O_WRONLY | O_TRUNC | O_CREAT; -#if ENABLE_TFTPD - if ((option_mask32 & (TFTPD_OPT+TFTPD_OPT_c)) == TFTPD_OPT) { - /* tftpd without -c */ - open_mode = O_WRONLY | O_TRUNC; - } -#endif - } - if (!(option_mask32 & TFTPD_OPT)) { - local_fd = CMD_GET(option_mask32) ? STDOUT_FILENO : STDIN_FILENO; - if (NOT_LONE_DASH(local_file)) - local_fd = xopen(local_file, open_mode); - } else { - local_fd = open_or_warn(local_file, open_mode); - if (local_fd < 0) { - /*error_pkt_reason = ERR_NOFILE/ERR_ACCESS?*/ - strcpy(error_pkt_str, "can't open file"); - goto send_err_pkt; - } - } - block_nr = 1; + if (!ENABLE_TFTP || our_lsa) { /* tftpd */ @@ -258,9 +224,48 @@ static int tftp_protocol( * that is, for "block 0" which is our OACK pkt */ opcode = TFTP_OACK; cp = xbuf + 2; + /* to be continued, see below */ + } +#endif + if (user_opt) { + struct passwd *pw = getpwnam(user_opt); + if (!pw) + bb_error_msg_and_die("unknown user '%s'", user_opt); + change_identity(pw); /* initgroups, setgid, setuid */ + } + } + + /* Open local file (must be after changing user) */ + if (CMD_PUT(option_mask32)) { + open_mode = O_RDONLY; + } else { + open_mode = O_WRONLY | O_TRUNC | O_CREAT; +#if ENABLE_TFTPD + if ((option_mask32 & (TFTPD_OPT+TFTPD_OPT_c)) == TFTPD_OPT) { + /* tftpd without -c */ + open_mode = O_WRONLY | O_TRUNC; + } +#endif + } + if (!(option_mask32 & TFTPD_OPT)) { + local_fd = CMD_GET(option_mask32) ? STDOUT_FILENO : STDIN_FILENO; + if (NOT_LONE_DASH(local_file)) + local_fd = xopen(local_file, open_mode); + } else { + local_fd = open_or_warn(local_file, open_mode); + if (local_fd < 0) { + /*error_pkt_reason = ERR_NOFILE/ERR_ACCESS?*/ + strcpy(error_pkt_str, "can't open file"); + goto send_err_pkt; + } + } + + if (!ENABLE_TFTP || our_lsa) { +#if ENABLE_FEATURE_TFTP_BLOCKSIZE + if (blksize != TFTP_BLKSIZE_DEFAULT) { + /* Create and send OACK packet. continued */ goto add_blksize_opt; } - /* else: just fall into while (1) loop below */ #endif } else { /* tftp */ |