summaryrefslogtreecommitdiff
path: root/sftp-server.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2003-02-24 11:58:44 +1100
committerDamien Miller <djm@mindrot.org>2003-02-24 11:58:44 +1100
commit9e51a73122fdb06c14068017d8f2a04179bf6bf6 (patch)
treea3d6a177b5e76ec09ff24d0fe6c0d71f42d6e6a9 /sftp-server.c
parent9f1e33a6b295f46dba45b0eefac173f699480943 (diff)
- markus@cvs.openbsd.org 2003/02/06 09:29:18
[sftp-server.c] fix races in rename/symlink; from Tony Finch; ok djm@
Diffstat (limited to 'sftp-server.c')
-rw-r--r--sftp-server.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/sftp-server.c b/sftp-server.c
index 84264693d..4eb31d94e 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -22,7 +22,7 @@
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24#include "includes.h" 24#include "includes.h"
25RCSID("$OpenBSD: sftp-server.c,v 1.38 2002/09/11 22:41:50 djm Exp $"); 25RCSID("$OpenBSD: sftp-server.c,v 1.39 2003/02/06 09:29:18 markus Exp $");
26 26
27#include "buffer.h" 27#include "buffer.h"
28#include "bufaux.h" 28#include "bufaux.h"
@@ -832,19 +832,22 @@ static void
832process_rename(void) 832process_rename(void)
833{ 833{
834 u_int32_t id; 834 u_int32_t id;
835 struct stat st;
836 char *oldpath, *newpath; 835 char *oldpath, *newpath;
837 int ret, status = SSH2_FX_FAILURE; 836 int status;
838 837
839 id = get_int(); 838 id = get_int();
840 oldpath = get_string(NULL); 839 oldpath = get_string(NULL);
841 newpath = get_string(NULL); 840 newpath = get_string(NULL);
842 TRACE("rename id %u old %s new %s", id, oldpath, newpath); 841 TRACE("rename id %u old %s new %s", id, oldpath, newpath);
843 /* fail if 'newpath' exists */ 842 /* fail if 'newpath' exists */
844 if (stat(newpath, &st) == -1) { 843 if (link(oldpath, newpath) == -1)
845 ret = rename(oldpath, newpath); 844 status = errno_to_portable(errno);
846 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; 845 else if (unlink(oldpath) == -1) {
847 } 846 status = errno_to_portable(errno);
847 /* clean spare link */
848 unlink(newpath);
849 } else
850 status = SSH2_FX_OK;
848 send_status(id, status); 851 send_status(id, status);
849 xfree(oldpath); 852 xfree(oldpath);
850 xfree(newpath); 853 xfree(newpath);
@@ -878,19 +881,16 @@ static void
878process_symlink(void) 881process_symlink(void)
879{ 882{
880 u_int32_t id; 883 u_int32_t id;
881 struct stat st;
882 char *oldpath, *newpath; 884 char *oldpath, *newpath;
883 int ret, status = SSH2_FX_FAILURE; 885 int ret, status;
884 886
885 id = get_int(); 887 id = get_int();
886 oldpath = get_string(NULL); 888 oldpath = get_string(NULL);
887 newpath = get_string(NULL); 889 newpath = get_string(NULL);
888 TRACE("symlink id %u old %s new %s", id, oldpath, newpath); 890 TRACE("symlink id %u old %s new %s", id, oldpath, newpath);
889 /* fail if 'newpath' exists */ 891 /* this will fail if 'newpath' exists */
890 if (stat(newpath, &st) == -1) { 892 ret = symlink(oldpath, newpath);
891 ret = symlink(oldpath, newpath); 893 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
892 status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
893 }
894 send_status(id, status); 894 send_status(id, status);
895 xfree(oldpath); 895 xfree(oldpath);
896 xfree(newpath); 896 xfree(newpath);