diff options
author | Nikolaus Rath <Nikolaus@rath.org> | 2016-02-10 19:53:49 -0800 |
---|---|---|
committer | Nikolaus Rath <Nikolaus@rath.org> | 2016-02-10 19:53:49 -0800 |
commit | e812e29d39f0e7aaf9ead9a19a9a4f288300a7e2 (patch) | |
tree | ff8fd1c17b9be6d1aba7ff365614b10e41a1223b /sshfs.c | |
parent | b10d21db3185a2b25e3bd35579f57d3c7b8d882e (diff) | |
parent | 80db43d7dce4f3979fe5e92b2d616d635f21029d (diff) | |
download | sshfs-e812e29d39f0e7aaf9ead9a19a9a4f288300a7e2.tar sshfs-e812e29d39f0e7aaf9ead9a19a9a4f288300a7e2.tar.gz sshfs-e812e29d39f0e7aaf9ead9a19a9a4f288300a7e2.tar.bz2 sshfs-e812e29d39f0e7aaf9ead9a19a9a4f288300a7e2.zip |
Merge pull request #5 from jmmv/merge-osxfuse
Merge osxfuse.
Diffstat (limited to 'sshfs.c')
-rw-r--r-- | sshfs.c | 114 |
1 files changed, 109 insertions, 5 deletions
@@ -12,6 +12,9 @@ #include <fuse.h> #include <fuse_opt.h> #include <fuse_lowlevel.h> +#ifdef __APPLE__ +# include <fuse_darwin.h> +#endif #include <assert.h> #include <stdio.h> #include <stdlib.h> @@ -20,7 +23,9 @@ #include <string.h> #include <stdint.h> #include <errno.h> -#include <semaphore.h> +#ifndef __APPLE__ +# include <semaphore.h> +#endif #include <pthread.h> #include <netdb.h> #include <signal.h> @@ -38,6 +43,11 @@ #include <pwd.h> #include <grp.h> #include <limits.h> +#ifdef __APPLE__ +# include <strings.h> +# include <libgen.h> +# include <darwin_compat.h> +#endif #include "cache.h" @@ -127,6 +137,10 @@ #define MAX_PASSWORD 1024 +#ifdef __APPLE__ +static char sshfs_program_path[PATH_MAX] = { 0 }; +#endif /* __APPLE__ */ + struct buffer { uint8_t *p; size_t len; @@ -243,6 +257,10 @@ struct sshfs { int server_version; unsigned remote_uid; unsigned local_uid; +#ifdef __APPLE__ + unsigned remote_gid; + unsigned local_gid; +#endif int remote_uid_detected; unsigned blksize; char *progname; @@ -739,8 +757,17 @@ static int buf_get_attrs(struct buffer *buf, struct stat *stbuf, int *flagsp) } } +#ifdef __APPLE__ + if (sshfs.remote_uid_detected) { + if (uid == sshfs.remote_uid) + uid = sshfs.local_uid; + if (gid == sshfs.remote_gid) + gid = sshfs.local_gid; + } +#else /* !__APPLE__ */ if (sshfs.remote_uid_detected && uid == sshfs.remote_uid) uid = sshfs.local_uid; +#endif /* __APPLE__ */ if (sshfs.idmap == IDMAP_FILE && sshfs.uid_map) if (translate_id(&uid, sshfs.uid_map) == -1) return -EPERM; @@ -849,11 +876,35 @@ static void ssh_add_arg(const char *arg) #ifdef SSH_NODELAY_WORKAROUND static int do_ssh_nodelay_workaround(void) { +#ifdef __APPLE__ + char *oldpreload = getenv("DYLD_INSERT_LIBRARIES"); +#else char *oldpreload = getenv("LD_PRELOAD"); +#endif char *newpreload; char sopath[PATH_MAX]; int res; +#ifdef __APPLE__ + char *sshfs_program_path_base = NULL; + if (!sshfs_program_path[0]) { + goto nobundle; + } + sshfs_program_path_base = dirname(sshfs_program_path); + if (!sshfs_program_path_base) { + goto nobundle; + } + snprintf(sopath, sizeof(sopath), "%s/%s", sshfs_program_path_base, + SSHNODELAY_SO); + res = access(sopath, R_OK); + if (res == -1) { + goto nobundle; + } + goto pathok; + +nobundle: +#endif /* __APPLE__ */ + snprintf(sopath, sizeof(sopath), "%s/%s", LIBDIR, SSHNODELAY_SO); res = access(sopath, R_OK); if (res == -1) { @@ -879,15 +930,24 @@ static int do_ssh_nodelay_workaround(void) } } +#ifdef __APPLE__ +pathok: +#endif + newpreload = g_strdup_printf("%s%s%s", oldpreload ? oldpreload : "", oldpreload ? " " : "", sopath); +#ifdef __APPLE__ + if (!newpreload || setenv("DYLD_INSERT_LIBRARIES", newpreload, 1) == -1) + fprintf(stderr, "warning: failed set DYLD_INSERT_LIBRARIES for ssh nodelay workaround\n"); +#else /* !__APPLE__ */ if (!newpreload || setenv("LD_PRELOAD", newpreload, 1) == -1) { fprintf(stderr, "warning: failed set LD_PRELOAD " "for ssh nodelay workaround\n"); } +#endif /* __APPLE__ */ g_free(newpreload); return 0; } @@ -1607,6 +1667,10 @@ static void sftp_detect_uid() sshfs.remote_uid = stbuf.st_uid; sshfs.local_uid = getuid(); +#ifdef __APPLE__ + sshfs.remote_gid = stbuf.st_gid; + sshfs.local_gid = getgid(); +#endif sshfs.remote_uid_detected = 1; DEBUG("remote_uid = %i\n", sshfs.remote_uid); @@ -2364,8 +2428,17 @@ static int sshfs_chown(const char *path, uid_t uid, gid_t gid) int err; struct buffer buf; +#ifdef __APPLE__ + if (sshfs.remote_uid_detected) { + if (uid == sshfs.local_uid) + uid = sshfs.remote_uid; + if (gid == sshfs.local_gid) + gid = sshfs.remote_gid; + } +#else /* !__APPLE__ */ if (sshfs.remote_uid_detected && uid == sshfs.local_uid) uid = sshfs.remote_uid; +#endif /* __APPLE__ */ if (sshfs.idmap == IDMAP_FILE && sshfs.r_uid_map) if(translate_id(&uid, sshfs.r_uid_map) == -1) return -EPERM; @@ -3316,9 +3389,9 @@ static void usage(const char *progname) " [no]nodelaysrv set nodelay tcp flag in sshd (default: off)\n" " [no]truncate fix truncate for old servers (default: off)\n" " [no]buflimit fix buffer fillup bug in server (default: on)\n" -" -o idmap=TYPE user/group ID mapping, possible types are:\n" -" none no translation of the ID space (default)\n" -" user only translate UID of connecting user\n" +" -o idmap=TYPE user/group ID mapping (default: " IDMAP_DEFAULT ")\n" +" none no translation of the ID space\n" +" user only translate UID/GID of connecting user\n" " file translate UIDs/GIDs contained in uidfile/gidfile\n" " -o uidfile=FILE file containing username:remote_uid mappings\n" " -o gidfile=FILE file containing groupname:remote_gid mappings\n" @@ -3494,6 +3567,13 @@ static int read_password(void) perror("Failed to allocate locked page for password"); return -1; } + if (mlock(sshfs.password, size) != 0) { + memset(sshfs.password, 0, size); + munmap(sshfs.password, size); + sshfs.password = NULL; + perror("Failed to allocate locked page for password"); + return -1; + } /* Don't use fgets() because password might stay in memory */ for (n = 0; n < max_password; n++) { @@ -3819,7 +3899,11 @@ static inline void load_gid_map(void) read_id_map(sshfs.gid_file, &groupname_to_gid, "gid", &sshfs.gid_map, &sshfs.r_gid_map); } +#ifdef __APPLE__ +int main(int argc, char *argv[], __unused char *envp[], char **exec_path) +#else int main(int argc, char *argv[]) +#endif { int res; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); @@ -3828,6 +3912,14 @@ int main(int argc, char *argv[]) const char *sftp_server; int libver; +#ifdef __APPLE__ + if (!realpath(*exec_path, sshfs_program_path)) { + memset(sshfs_program_path, 0, PATH_MAX); + } + + /* Until this gets fixed somewhere else. */ + g_slice_set_config(G_SLICE_CONFIG_ALWAYS_MALLOC, TRUE); +#endif /* __APPLE__ */ g_thread_init(NULL); sshfs.blksize = 4096; @@ -3836,7 +3928,11 @@ int main(int argc, char *argv[]) sshfs.max_write = 32768; sshfs.nodelay_workaround = 1; sshfs.nodelaysrv_workaround = 0; +#ifdef __APPLE__ + sshfs.rename_workaround = 1; +#else sshfs.rename_workaround = 0; +#endif sshfs.truncate_workaround = 0; sshfs.buflimit_workaround = 1; sshfs.ssh_ver = 2; @@ -3848,7 +3944,15 @@ int main(int argc, char *argv[]) sshfs.delay_connect = 0; sshfs.slave = 0; sshfs.detect_uid = 0; - sshfs.idmap = IDMAP_NONE; + if (strcmp(IDMAP_DEFAULT, "none") == 0) { + sshfs.idmap = IDMAP_NONE; + } else if (strcmp(IDMAP_DEFAULT, "user") == 0) { + sshfs.idmap = IDMAP_USER; + } else { + fprintf(stderr, "bad idmap default value built into sshfs; " + "assuming none (bad logic in configure script?)\n"); + sshfs.idmap = IDMAP_NONE; + } sshfs.nomap = NOMAP_ERROR; ssh_add_arg("ssh"); ssh_add_arg("-x"); |