SFTP client can't write to own home directory when chrooted there
Solution 1:
I found several working solutions to this problem, most of which were only usable because of my willingness to throw away the server after I got this one upload. But there's one that I think is pretty reasonable.
Ugliest solution first:
Bad idea #1 - Forget the chroot and chmod 777 /
. Openssh only checks for sane permissions when you're chrooting.
Bad idea #2 - Allowing the client to write to the real root directory (like in bad idea #1) can be done more subtly, with group permissions or a user ACL.
Bad idea #3 - As I wrote in the question, it is possible to hack out the permission check from sshd. Just search for the error message bad ownership or modes for chroot
in the source, change the nearby 022
to 002
and it won't notice loose group permissions and ACLs on the chroot any more.
Good idea(?) - That backslash is the source of the trouble. If the client would just upload to /SLA/SLA_Data_blah_blah.zip
everything would be fine. So let's just fix the backslash at the point where it hits the filesystem, by wrapping the open
syscall:
/* wrapopen.c */
#define _GNU_SOURCE
#include <string.h>
#include <sys/types.h>
#include <dlfcn.h>
static int (*libc_open)(const char *, int, mode_t);
/* Behave like normal open() but translate backslashes to slashes. */
int open(const char *fn, int flags, mode_t mode)
{
char fn_fixed[strlen(fn)+1], *p;
strcpy(fn_fixed, fn);
for(p=fn_fixed;*p;++p)
if(*p == '\\')
*p = '/';
if(!libc_open)
libc_open = dlsym(RTLD_NEXT, "open");
return libc_open(fn_fixed, flags, mode);
}
Usage:
$ gcc -fPIC -shared wrapopen.c -o wrapopen.so -ldl
$ /etc/init.d/ssh stop
$ LD_PRELOAD=$PWD/wrapopen.so /usr/sbin/sshd
Now when sshd tries to create SLA\SLA_Data_blah_blah
it actually creates SLA/SLA_Data_blah_blah
. The user can be chrooted, the chroot is owned by root mode 755, the SLA
directory under the chroot is owned by the user, and the upload works.