curl-library
Re: sftp postquote command rename fix/diff question
Date: Thu, 10 May 2007 11:59:23 +0200
* Dan Fandrich <dan_at_coneharvesters.com> [2007-05-10 11:29:32]:
> On Thu, May 10, 2007 at 12:24:22AM +0200, Kristian Gunstone wrote:
> > This patch has modifications to the rename and rm handlers in lib/ssh.c.
> > As tipped, I'm now just returning an error if rename fails due to
> > destination already existing.
> >
> > In order to test this, I also had to make modifications to the file
> > delete handler at the same time, since it also returns an unknown error
> > to the user application if the file does _not_ exist, and thus I added
> > support for this return code at the same time.
> >
> > Seems to work properly now, but it sure makes renaming slow for user
> > applications since the entire connection has to be reestablished between
> > rename, delete, and reattempt to rename (that's how it is right now for
> > sftp it seems)
>
> That does seem like an annoying limitation. Can't you simply look at the
> error code returned by sftp_libssh2_strerror after a failed
> libssh2_sftp_rename? Doesn't that provide a sane error status of some sort?
> Failing that, how about just doing the stat call after the rename fails
> instead of before?
>
> In any case, calling libssh2_sftp_stat in this way opens up a race condition;
> even if stat shows no file exists, a process on the server might create
> the file before the rename can be executed and it will *still* return an
> error.
>
> > Well, hope you prefer this method.
>
> Not quite sure I do...
Ok, I've just spent this morning looking through code in both libcurl
and openssh2.
I was wondering why libssh2_sftp_last_error after a rename still
returned LIBSSH2_FX_FAILURE and not a proper error code.
As you probably know, libssh2_sftp_rename is just a macro to
libssh2_sftp_rename_ex.
If you have a look at the spec,
http://www.libssh2.org/wiki/index.php/Libssh2_sftp_rename_ex
you can clearly see that libssh2_sftp_rename actually has
LIBSSH2_SFTP_RENAME_OVERWRITE set, so by all means the rename issued
from libssh2 _should_ overwrite the file.
I then had a look why it wasn't - and why we were getting that ambiguous
error.
in libssh2's src/sftp.c, line 1664, we can clearly see that libssh2
won't send the flags to the server unless the sshd version is >= 5.
In my testing environment I'm running sshd v4.2p1!
If we then look further down in that code, we can see where
sftp->last_errno is set.
the return is received from libssh2_ntohu32(data + 5).
And surely enough, it checks for LIBSSH2_FX_FILE_ALREADY_EXISTS and
should set the appropriate error, but according to the error string,
"File already exists and SSH_FXP_RENAME_OVERWRITE not specified",
it only does this is SSH_FXP_RENAME_OVERWRITE is not set.
I'm still a but confused about the code in libssh2, but it seems to me
that we should either get an LIBSSH2_FX_OP_UNSUPPORTED or
LIBSSH2_FX_FILE_ALREADY_EXISTS regardless of sshd versions.
What do you think of this information?
-- Kristian Gunstone http://www.pulia.nuReceived on 2007-05-10