From 35e18dba89ac0fd068f16388563861dccbeb527c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 17 Sep 2007 16:11:33 +1000 Subject: - djm@cvs.openbsd.org 2007/09/13 04:39:04 [sftp-server.c] fix incorrect test when setting syslog facility; from Jan Pechanec --- sftp-server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sftp-server.c') diff --git a/sftp-server.c b/sftp-server.c index 76edebc5a..ee0b4a62e 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.73 2007/05/17 07:55:29 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.74 2007/09/13 04:39:04 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1244,7 +1244,7 @@ main(int argc, char **argv) break; case 'f': log_facility = log_facility_number(optarg); - if (log_level == SYSLOG_FACILITY_NOT_SET) + if (log_facility == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; case 'h': -- cgit v1.2.3 From 3397d0e0c5820464bea4c96e91b5e02cca98330a Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 10 Feb 2008 22:26:51 +1100 Subject: - djm@cvs.openbsd.org 2008/01/21 17:24:30 [sftp-server.c] Remove the fixed 100 handle limit in sftp-server and allocate as many as we have available file descriptors. Patch from miklos AT szeredi.hu; ok dtucker@ markus@ --- ChangeLog | 7 ++++++- sftp-server.c | 57 +++++++++++++++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 27 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 82b1d8024..dd8f6abea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -49,6 +49,11 @@ When uploading, correctly handle the case of an unquoted filename with glob metacharacters that match a file exactly but not as a glob, e.g. a file called "[abcd]". report and test cases from duncan2nd AT gmx.de + - djm@cvs.openbsd.org 2008/01/21 17:24:30 + [sftp-server.c] + Remove the fixed 100 handle limit in sftp-server and allocate as many + as we have available file descriptors. Patch from miklos AT szeredi.hu; + ok dtucker@ markus@ 20080119 - (djm) Silence noice from expr in ssh-copy-id; patch from @@ -3577,4 +3582,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4829 2008/02/10 11:26:24 djm Exp $ +$Id: ChangeLog,v 1.4830 2008/02/10 11:26:51 djm Exp $ diff --git a/sftp-server.c b/sftp-server.c index ee0b4a62e..5c84c728c 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.74 2007/09/13 04:39:04 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.75 2008/01/21 17:24:30 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -169,6 +169,7 @@ struct Handle { int fd; char *name; u_int64_t bytes_read, bytes_write; + int next_unused; }; enum { @@ -177,40 +178,46 @@ enum { HANDLE_FILE }; -Handle handles[100]; +Handle *handles = NULL; +u_int num_handles = 0; +int first_unused_handle = -1; -static void -handle_init(void) +static void handle_unused(int i) { - u_int i; - - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) - handles[i].use = HANDLE_UNUSED; + handles[i].use = HANDLE_UNUSED; + handles[i].next_unused = first_unused_handle; + first_unused_handle = i; } static int handle_new(int use, const char *name, int fd, DIR *dirp) { - u_int i; + int i; - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) { - if (handles[i].use == HANDLE_UNUSED) { - handles[i].use = use; - handles[i].dirp = dirp; - handles[i].fd = fd; - handles[i].name = xstrdup(name); - handles[i].bytes_read = handles[i].bytes_write = 0; - return i; - } + if (first_unused_handle == -1) { + if (num_handles + 1 <= num_handles) + return -1; + num_handles++; + handles = xrealloc(handles, num_handles, sizeof(Handle)); + handle_unused(num_handles - 1); } - return -1; + + i = first_unused_handle; + first_unused_handle = handles[i].next_unused; + + handles[i].use = use; + handles[i].dirp = dirp; + handles[i].fd = fd; + handles[i].name = xstrdup(name); + handles[i].bytes_read = handles[i].bytes_write = 0; + + return i; } static int handle_is_ok(int i, int type) { - return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) && - handles[i].use == type; + return i >= 0 && (u_int)i < num_handles && handles[i].use == type; } static int @@ -300,12 +307,12 @@ handle_close(int handle) if (handle_is_ok(handle, HANDLE_FILE)) { ret = close(handles[handle].fd); - handles[handle].use = HANDLE_UNUSED; xfree(handles[handle].name); + handle_unused(handle); } else if (handle_is_ok(handle, HANDLE_DIR)) { ret = closedir(handles[handle].dirp); - handles[handle].use = HANDLE_UNUSED; xfree(handles[handle].name); + handle_unused(handle); } else { errno = ENOENT; } @@ -333,7 +340,7 @@ handle_log_exit(void) { u_int i; - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) + for (i = 0; i < num_handles; i++) if (handles[i].use != HANDLE_UNUSED) handle_log_close(i, "forced"); } @@ -1271,8 +1278,6 @@ main(int argc, char **argv) logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); - handle_init(); - in = dup(STDIN_FILENO); out = dup(STDOUT_FILENO); -- cgit v1.2.3 From dfc24258a75a06ea8a3f56d99d3669e1a012a1dc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 10 Feb 2008 22:29:40 +1100 Subject: - markus@cvs.openbsd.org 2008/02/04 21:53:00 [session.c sftp-server.c sftp.h] link sftp-server into sshd; feedback and ok djm@ --- ChangeLog | 5 ++++- session.c | 37 +++++++++++++++++++++++++++++++++---- sftp-server.c | 44 ++++++++++++++++++++++++++------------------ sftp.h | 5 ++++- 4 files changed, 67 insertions(+), 24 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 81ebc742b..0324cbbbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -68,6 +68,9 @@ explain how to handle local file names containing colons; requested by Tamas TEVESZ ok dtucker + - markus@cvs.openbsd.org 2008/02/04 21:53:00 + [session.c sftp-server.c sftp.h] + link sftp-server into sshd; feedback and ok djm@ 20080119 - (djm) Silence noice from expr in ssh-copy-id; patch from @@ -3596,4 +3599,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4833 2008/02/10 11:28:45 djm Exp $ +$Id: ChangeLog,v 1.4834 2008/02/10 11:29:40 djm Exp $ diff --git a/session.c b/session.c index 2b0580b45..a1319b384 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.224 2007/09/11 15:47:17 gilles Exp $ */ +/* $OpenBSD: session.c,v 1.225 2008/02/04 21:53:00 markus Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -87,6 +87,7 @@ #include "session.h" #include "kex.h" #include "monitor_wrap.h" +#include "sftp.h" #if defined(KRB5) && defined(USE_AFS) #include @@ -132,6 +133,10 @@ const char *original_command = NULL; #define MAX_SESSIONS 10 Session sessions[MAX_SESSIONS]; +#define SUBSYSTEM_NONE 0 +#define SUBSYSTEM_EXT 1 +#define SUBSYSTEM_INT_SFTP 2 + #ifdef HAVE_LOGIN_CAP login_cap_t *lc; #endif @@ -683,10 +688,14 @@ do_exec(Session *s, const char *command) if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; + if (s->is_subsystem) + s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (config) '%.900s'", command); } else if (forced_command) { original_command = command; command = forced_command; + if (s->is_subsystem) + s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (key option) '%.900s'", command); } @@ -1465,12 +1474,13 @@ child_close_fds(void) * environment, closing extra file descriptors, setting the user and group * ids, and executing the command or shell. */ +#define ARGV_MAX 10 void do_child(Session *s, const char *command) { extern char **environ; char **env; - char *argv[10]; + char *argv[ARGV_MAX]; const char *shell, *shell0, *hostname = NULL; struct passwd *pw = s->pw; @@ -1602,6 +1612,22 @@ do_child(Session *s, const char *command) /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); + if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { + extern int optind, optreset; + int i; + char *p, *args; + + setproctitle("%s@internal-sftp-server", s->pw->pw_name); + args = strdup(command ? command : "sftp-server"); + for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) + if (i < ARGV_MAX - 1) + argv[i++] = p; + argv[i] = NULL; + optind = optreset = 1; + __progname = argv[0]; + exit(sftp_server_main(i, argv)); + } + if (options.use_login) { launch_login(pw, hostname); /* NEVERREACHED */ @@ -1874,13 +1900,16 @@ session_subsystem_req(Session *s) if (strcmp(subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; - if (stat(prog, &st) < 0) { + if (!strcmp("internal-sftp", prog)) { + s->is_subsystem = SUBSYSTEM_INT_SFTP; + } else if (stat(prog, &st) < 0) { error("subsystem: cannot stat %s: %s", prog, strerror(errno)); break; + } else { + s->is_subsystem = SUBSYSTEM_EXT; } debug("subsystem: exec() %s", cmd); - s->is_subsystem = 1; do_exec(s, cmd); success = 1; break; diff --git a/sftp-server.c b/sftp-server.c index 5c84c728c..373bd5eda 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.75 2008/01/21 17:24:30 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.76 2008/02/04 21:53:00 markus Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1110,7 +1110,7 @@ process(void) if (msg_len > SFTP_MAX_MSG_LENGTH) { error("bad message from %s local user %s", client_addr, pw->pw_name); - cleanup_exit(11); + sftp_server_cleanup_exit(11); } if (buf_len < msg_len + 4) return; @@ -1183,18 +1183,22 @@ process(void) break; } /* discard the remaining bytes from the current packet */ - if (buf_len < buffer_len(&iqueue)) - fatal("iqueue grew unexpectedly"); + if (buf_len < buffer_len(&iqueue)) { + error("iqueue grew unexpectedly"); + sftp_server_cleanup_exit(255); + } consumed = buf_len - buffer_len(&iqueue); - if (msg_len < consumed) - fatal("msg_len %d < consumed %d", msg_len, consumed); + if (msg_len < consumed) { + error("msg_len %d < consumed %d", msg_len, consumed); + sftp_server_cleanup_exit(255); + } if (msg_len > consumed) buffer_consume(&iqueue, msg_len - consumed); } /* Cleanup handler that logs active handles upon normal exit */ void -cleanup_exit(int i) +sftp_server_cleanup_exit(int i) { if (pw != NULL && client_addr != NULL) { handle_log_exit(); @@ -1205,7 +1209,7 @@ cleanup_exit(int i) } static void -usage(void) +sftp_server_usage(void) { extern char *__progname; @@ -1215,7 +1219,7 @@ usage(void) } int -main(int argc, char **argv) +sftp_server_main(int argc, char **argv) { fd_set *rset, *wset; int in, out, max, ch, skipargs = 0, log_stderr = 0; @@ -1256,7 +1260,7 @@ main(int argc, char **argv) break; case 'h': default: - usage(); + sftp_server_usage(); } } @@ -1264,15 +1268,19 @@ main(int argc, char **argv) if ((cp = getenv("SSH_CONNECTION")) != NULL) { client_addr = xstrdup(cp); - if ((cp = strchr(client_addr, ' ')) == NULL) - fatal("Malformed SSH_CONNECTION variable: \"%s\"", + if ((cp = strchr(client_addr, ' ')) == NULL) { + error("Malformed SSH_CONNECTION variable: \"%s\"", getenv("SSH_CONNECTION")); + sftp_server_cleanup_exit(255); + } *cp = '\0'; } else client_addr = xstrdup("UNKNOWN"); - if ((pw = getpwuid(getuid())) == NULL) - fatal("No user found for uid %lu", (u_long)getuid()); + if ((pw = getpwuid(getuid())) == NULL) { + error("No user found for uid %lu", (u_long)getuid()); + sftp_server_cleanup_exit(255); + } pw = pwcopy(pw); logit("session opened for local user %s from [%s]", @@ -1320,7 +1328,7 @@ main(int argc, char **argv) if (errno == EINTR) continue; error("select: %s", strerror(errno)); - cleanup_exit(2); + sftp_server_cleanup_exit(2); } /* copy stdin to iqueue */ @@ -1328,10 +1336,10 @@ main(int argc, char **argv) len = read(in, buf, sizeof buf); if (len == 0) { debug("read eof"); - cleanup_exit(0); + sftp_server_cleanup_exit(0); } else if (len < 0) { error("read: %s", strerror(errno)); - cleanup_exit(1); + sftp_server_cleanup_exit(1); } else { buffer_append(&iqueue, buf, len); } @@ -1341,7 +1349,7 @@ main(int argc, char **argv) len = write(out, buffer_ptr(&oqueue), olen); if (len < 0) { error("write: %s", strerror(errno)); - cleanup_exit(1); + sftp_server_cleanup_exit(1); } else { buffer_consume(&oqueue, len); } diff --git a/sftp.h b/sftp.h index 610c0b758..12b9cc056 100644 --- a/sftp.h +++ b/sftp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.h,v 1.5 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: sftp.h,v 1.6 2008/02/04 21:53:00 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -90,3 +90,6 @@ #define SSH2_FX_CONNECTION_LOST 7 #define SSH2_FX_OP_UNSUPPORTED 8 #define SSH2_FX_MAX 8 + +int sftp_server_main(int, char **); +void sftp_server_cleanup_exit(int) __dead; -- cgit v1.2.3 From d8cb1f184f9acaae02bb4d15ce1e00ffbeeeac88 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 10 Feb 2008 22:40:12 +1100 Subject: - djm@cvs.openbsd.org 2008/02/08 23:24:07 [servconf.c servconf.h session.c sftp-server.c sftp.h sshd_config] [sshd_config.5] add sshd_config ChrootDirectory option to chroot(2) users to a directory and tweak internal sftp server to work with it (no special files in chroot required). ok markus@ --- Makefile.in | 6 +-- servconf.c | 12 +++++- servconf.h | 4 +- session.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++------- sftp-server-main.c | 50 +++++++++++++++++++++++++ sftp-server.c | 10 ++--- sftp.h | 6 ++- sshd_config | 3 +- sshd_config.5 | 54 ++++++++++++++++++++++++++- 9 files changed, 220 insertions(+), 31 deletions(-) create mode 100644 sftp-server-main.c (limited to 'sftp-server.c') diff --git a/Makefile.in b/Makefile.in index 2486edc95..1f78ea9cc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.285 2007/06/11 04:01:42 djm Exp $ +# $Id: Makefile.in,v 1.286 2008/02/10 11:40:12 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -156,8 +156,8 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o - $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o + $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) diff --git a/servconf.c b/servconf.c index 19c286c18..d38d0bfb1 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.175 2008/01/01 09:27:33 dtucker Exp $ */ +/* $OpenBSD: servconf.c,v 1.176 2008/02/08 23:24:08 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options) options->permit_tun = -1; options->num_permitted_opens = -1; options->adm_forced_command = NULL; + options->chroot_directory = NULL; } void @@ -291,7 +292,7 @@ typedef enum { sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, - sMatch, sPermitOpen, sForceCommand, + sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -403,6 +404,7 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, + { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1147,6 +1149,7 @@ parse_flag: case sBanner: charptr = &options->banner; goto parse_filename; + /* * These options can contain %X options expanded at * connect time, so that you can specify paths like: @@ -1255,6 +1258,10 @@ parse_flag: options->adm_forced_command = xstrdup(cp + len); return 0; + case sChrootDirectory: + charptr = &options->chroot_directory; + goto parse_filename; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1363,6 +1370,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) if (preauth) return; M_CP_STROPT(adm_forced_command); + M_CP_STROPT(chroot_directory); } #undef M_CP_INTOPT diff --git a/servconf.h b/servconf.h index 8a5b950ea..81a68be89 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.80 2007/02/19 10:45:58 dtucker Exp $ */ +/* $OpenBSD: servconf.h,v 1.81 2008/02/08 23:24:08 djm Exp $ */ /* * Author: Tatu Ylonen @@ -141,6 +141,8 @@ typedef struct { int permit_tun; int num_permitted_opens; + + char *chroot_directory; } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/session.c b/session.c index a1319b384..1768c8c2f 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.225 2008/02/04 21:53:00 markus Exp $ */ +/* $OpenBSD: session.c,v 1.226 2008/02/08 23:24:07 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -84,6 +84,7 @@ #include "sshlogin.h" #include "serverloop.h" #include "canohost.h" +#include "misc.h" #include "session.h" #include "kex.h" #include "monitor_wrap.h" @@ -93,6 +94,9 @@ #include #endif +/* Magic name for internal sftp-server */ +#define INTERNAL_SFTP_NAME "internal-sftp" + /* func */ Session *session_new(void); @@ -130,7 +134,7 @@ extern Buffer loginmsg; const char *original_command = NULL; /* data */ -#define MAX_SESSIONS 10 +#define MAX_SESSIONS 20 Session sessions[MAX_SESSIONS]; #define SUBSYSTEM_NONE 0 @@ -688,13 +692,17 @@ do_exec(Session *s, const char *command) if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; - if (s->is_subsystem) + if (strcmp(INTERNAL_SFTP_NAME, command) == 0) + s->is_subsystem = SUBSYSTEM_INT_SFTP; + else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (config) '%.900s'", command); } else if (forced_command) { original_command = command; command = forced_command; - if (s->is_subsystem) + if (strcmp(INTERNAL_SFTP_NAME, command) == 0) + s->is_subsystem = SUBSYSTEM_INT_SFTP; + else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (key option) '%.900s'", command); } @@ -710,7 +718,6 @@ do_exec(Session *s, const char *command) PRIVSEP(audit_run_command(shell)); } #endif - if (s->ttyfd != -1) do_exec_pty(s, command); else @@ -1293,6 +1300,61 @@ do_nologin(struct passwd *pw) } } +/* + * Chroot into a directory after checking it for safety: all path components + * must be root-owned directories with strict permissions. + */ +static void +safely_chroot(const char *path, uid_t uid) +{ + const char *cp; + char component[MAXPATHLEN]; + struct stat st; + + if (*path != '/') + fatal("chroot path does not begin at root"); + if (strlen(path) >= sizeof(component)) + fatal("chroot path too long"); + + /* + * Descend the path, checking that each component is a + * root-owned directory with strict permissions. + */ + for (cp = path; cp != NULL;) { + if ((cp = strchr(cp, '/')) == NULL) + strlcpy(component, path, sizeof(component)); + else { + cp++; + memcpy(component, path, cp - path); + component[cp - path] = '\0'; + } + + debug3("%s: checking '%s'", __func__, component); + + if (stat(component, &st) != 0) + fatal("%s: stat(\"%s\"): %s", __func__, + component, strerror(errno)); + if (st.st_uid != 0 || (st.st_mode & 022) != 0) + fatal("bad ownership or modes for chroot " + "directory %s\"%s\"", + cp == NULL ? "" : "component ", component); + if (!S_ISDIR(st.st_mode)) + fatal("chroot path %s\"%s\" is not a directory", + cp == NULL ? "" : "component ", component); + + } + + if (chdir(path) == -1) + fatal("Unable to chdir to chroot path \"%s\": " + "%s", path, strerror(errno)); + if (chroot(path) == -1) + fatal("chroot(\"%s\"): %s", path, strerror(errno)); + if (chdir("/") == -1) + fatal("%s: chdir(/) after chroot: %s", + __func__, strerror(errno)); + verbose("Changed root directory to \"%s\"", path); +} + /* Set login name, uid, gid, and groups. */ void do_setusercontext(struct passwd *pw) @@ -1324,7 +1386,7 @@ do_setusercontext(struct passwd *pw) } # endif /* USE_PAM */ if (setusercontext(lc, pw, pw->pw_uid, - (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { + (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { perror("unable to set user context"); exit(1); } @@ -1347,13 +1409,13 @@ do_setusercontext(struct passwd *pw) exit(1); } endgrent(); -#ifdef GSSAPI +# ifdef GSSAPI if (options.gss_authentication) { temporarily_use_uid(pw); ssh_gssapi_storecreds(); restore_uid(); } -#endif +# endif # ifdef USE_PAM /* * PAM credentials may take the form of supplementary groups. @@ -1367,15 +1429,33 @@ do_setusercontext(struct passwd *pw) # endif /* USE_PAM */ # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) irix_setusercontext(pw); -# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ +# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ # ifdef _AIX aix_usrinfo(pw); # endif /* _AIX */ -#ifdef USE_LIBIAF +# ifdef USE_LIBIAF if (set_id(pw->pw_name) != 0) { exit(1); } -#endif /* USE_LIBIAF */ +# endif /* USE_LIBIAF */ +#endif + + if (options.chroot_directory != NULL && + strcasecmp(options.chroot_directory, "none") != 0) { + char *chroot_path; + + chroot_path = percent_expand(options.chroot_directory, + "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL); + safely_chroot(chroot_path, pw->pw_uid); + free(chroot_path); + } + +#ifdef HAVE_LOGIN_CAP + if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { + perror("unable to set user context (setuser)"); + exit(1); + } +#else /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -1625,7 +1705,7 @@ do_child(Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; - exit(sftp_server_main(i, argv)); + exit(sftp_server_main(i, argv, s->pw)); } if (options.use_login) { @@ -1900,7 +1980,7 @@ session_subsystem_req(Session *s) if (strcmp(subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; - if (!strcmp("internal-sftp", prog)) { + if (!strcmp(INTERNAL_SFTP_NAME, prog)) { s->is_subsystem = SUBSYSTEM_INT_SFTP; } else if (stat(prog, &st) < 0) { error("subsystem: cannot stat %s: %s", prog, diff --git a/sftp-server-main.c b/sftp-server-main.c new file mode 100644 index 000000000..1d2ea6220 --- /dev/null +++ b/sftp-server-main.c @@ -0,0 +1,50 @@ +/* $OpenBSD: */ +/* + * Copyright (c) 2008 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include "log.h" +#include "sftp.h" +#include "misc.h" + +void +cleanup_exit(int i) +{ + sftp_server_cleanup_exit(i); +} + +int +main(int argc, char **argv) +{ + struct passwd *user_pw; + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + if ((user_pw = getpwuid(getuid())) == NULL) { + fprintf(stderr, "No user found for uid %lu", (u_long)getuid()); + return 1; + } + + return (sftp_server_main(argc, argv, user_pw)); +} diff --git a/sftp-server.c b/sftp-server.c index 373bd5eda..44ccefff8 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.76 2008/02/04 21:53:00 markus Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.77 2008/02/08 23:24:07 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1219,7 +1219,7 @@ sftp_server_usage(void) } int -sftp_server_main(int argc, char **argv) +sftp_server_main(int argc, char **argv, struct passwd *user_pw) { fd_set *rset, *wset; int in, out, max, ch, skipargs = 0, log_stderr = 0; @@ -1277,11 +1277,7 @@ sftp_server_main(int argc, char **argv) } else client_addr = xstrdup("UNKNOWN"); - if ((pw = getpwuid(getuid())) == NULL) { - error("No user found for uid %lu", (u_long)getuid()); - sftp_server_cleanup_exit(255); - } - pw = pwcopy(pw); + pw = pwcopy(user_pw); logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); diff --git a/sftp.h b/sftp.h index 12b9cc056..0835da6ed 100644 --- a/sftp.h +++ b/sftp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.h,v 1.6 2008/02/04 21:53:00 markus Exp $ */ +/* $OpenBSD: sftp.h,v 1.7 2008/02/08 23:24:07 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -91,5 +91,7 @@ #define SSH2_FX_OP_UNSUPPORTED 8 #define SSH2_FX_MAX 8 -int sftp_server_main(int, char **); +struct passwd; + +int sftp_server_main(int, char **, struct passwd *); void sftp_server_cleanup_exit(int) __dead; diff --git a/sshd_config b/sshd_config index c7094e775..ddfbbe91e 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.76 2007/08/23 03:22:16 djm Exp $ +# $OpenBSD: sshd_config,v 1.77 2008/02/08 23:24:07 djm Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -102,6 +102,7 @@ Protocol 2 #PidFile /var/run/sshd.pid #MaxStartups 10 #PermitTunnel no +#ChrootDirectory none # no default banner path #Banner none diff --git a/sshd_config.5 b/sshd_config.5 index aa6720dc3..2f83bf2e1 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.79 2008/01/01 09:27:33 dtucker Exp $ -.Dd $Mdocdate: January 1 2008 $ +.\" $OpenBSD: sshd_config.5,v 1.80 2008/02/08 23:24:07 djm Exp $ +.Dd $Mdocdate: February 8 2008 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -173,6 +173,45 @@ All authentication styles from are supported. The default is .Dq yes . +.It Cm ChrootDirectory +Specifies a path to +.Xr chroot 2 +to after authentication. +This path, and all its components, must be root-owned directories that are +not writable by any other user or group. +.Pp +The path may contain the following tokens that are expanded at runtime once +the connecting user has been authenticated: %% is replaced by a literal '%', +%h is replaced by the home directory of the user being authenticated, and +%u is replaced by the username of that user. +.Pp +The +.Cm ChrootDirectory +must contain the necessary files and directories to support the +users' session. +For an interactive session this requires at least a shell, typically +.Xr sh 1 , +and basic +.Pa /dev +nodes such as +.Xr null 4 , +.Xr zero 4 , +.Xr stdin 4 , +.Xr stdout 4 , +.Xr stderr 4 , +.Xr arandom 4 +and +.Xr tty 4 +devices. +For file transfer sessions using +.Dq sftp , +no additional configuration of the environment is necessary if the +in-process sftp server is used (see +.Cm Subsystem +for details. +.Pp +The default is not to +.Xr chroot 2 . .It Cm Ciphers Specifies the ciphers allowed for protocol version 2. Multiple ciphers must be comma-separated. @@ -740,11 +779,22 @@ The default is Configures an external subsystem (e.g. file transfer daemon). Arguments should be a subsystem name and a command (with optional arguments) to execute upon subsystem request. +.Pp The command .Xr sftp-server 8 implements the .Dq sftp file transfer subsystem. +.Pp +Alternately the name +.Dq internal-sftp +implements an in-process +.Dq sftp +server. +This may simplify configurations using +.Cm ChrootDirectory +to force a different filesystem root on clients. +.Pp By default no subsystems are defined. Note that this option applies to protocol version 2 only. .It Cm SyslogFacility -- cgit v1.2.3 From 62ca18d12fc815e760e8c73fcce764fef405b313 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 10 Feb 2008 22:44:20 +1100 Subject: - djm@cvs.openbsd.org 2008/02/08 23:24:07 [servconf.c servconf.h session.c sftp-server.c sftp.h sshd_config] [sshd_config.5] add sshd_config ChrootDirectory option to chroot(2) users to a directory and tweak internal sftp server to work with it (no special files in chroot required). ok markus@ --- Makefile.in | 4 ++-- sftp-server.c | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'sftp-server.c') diff --git a/Makefile.in b/Makefile.in index 1f78ea9cc..8049f1423 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.286 2008/02/10 11:40:12 djm Exp $ +# $Id: Makefile.in,v 1.287 2008/02/10 11:44:20 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -86,7 +86,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - audit.o audit-bsm.o platform.o + audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 diff --git a/sftp-server.c b/sftp-server.c index 44ccefff8..d3ae54428 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1230,9 +1230,6 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) extern char *optarg; extern char *__progname; - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); -- cgit v1.2.3 From 7c29661471d0a7590ed41dec76661174c99b1c94 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 7 Mar 2008 18:33:53 +1100 Subject: - djm@cvs.openbsd.org 2008/02/27 20:21:15 [sftp-server.c] add an extension method "posix-rename@openssh.com" to perform POSIX atomic rename() operations. based on patch from miklos AT szeredi.hu in bz#1400; ok dtucker@ markus@ --- ChangeLog | 7 ++++++- sftp-server.c | 27 +++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 533ee81cf..0aa5c9920 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,11 @@ [clientloop.c packet.c packet.h serverloop.c] Allow all SSH2 packet types, including UNIMPLEMENTED to reset the keepalive timer (bz #1307). ok markus@ + - djm@cvs.openbsd.org 2008/02/27 20:21:15 + [sftp-server.c] + add an extension method "posix-rename@openssh.com" to perform POSIX atomic + rename() operations. based on patch from miklos AT szeredi.hu in bz#1400; + ok dtucker@ markus@ 20080302 - (dtucker) [configure.ac] FreeBSD's glob() doesn't behave the way we expect @@ -3685,4 +3690,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4856 2008/03/07 07:33:30 djm Exp $ +$Id: ChangeLog,v 1.4857 2008/03/07 07:33:53 djm Exp $ diff --git a/sftp-server.c b/sftp-server.c index d3ae54428..d9549f5bc 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.77 2008/02/08 23:24:07 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.78 2008/02/27 20:21:15 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -487,6 +487,9 @@ process_init(void) buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_VERSION); buffer_put_int(&msg, SSH2_FILEXFER_VERSION); + /* POSIX rename extension */ + buffer_put_cstring(&msg, "posix-rename@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ send_msg(&msg); buffer_free(&msg); } @@ -1079,6 +1082,23 @@ process_symlink(void) xfree(newpath); } +static void +process_extended_posix_rename(u_int32_t id) +{ + char *oldpath, *newpath; + + oldpath = get_string(NULL); + newpath = get_string(NULL); + debug3("request %u: posix-rename", id); + logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); + if (rename(oldpath, newpath) == -1) + send_status(id, errno_to_portable(errno)); + else + send_status(id, SSH2_FX_OK); + xfree(oldpath); + xfree(newpath); +} + static void process_extended(void) { @@ -1087,7 +1107,10 @@ process_extended(void) id = get_int(); request = get_string(NULL); - send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ + if (strcmp(request, "posix-rename@openssh.com") == 0) + process_extended_posix_rename(id); + else + send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); } -- cgit v1.2.3 From d671e5a978efd5ba949d3fdcd03f728dcd68c636 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 19 May 2008 14:53:33 +1000 Subject: - djm@cvs.openbsd.org 2008/04/18 12:32:11 [sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c sftp.h] introduce sftp extension methods statvfs@openssh.com and fstatvfs@openssh.com that implement statvfs(2)-like operations, based on a patch from miklos AT szeredi.hu (bz#1399) also add a "df" command to the sftp client that uses the statvfs@openssh.com to produce a df(1)-like display of filesystem space and inode utilisation ok markus@ --- ChangeLog | 11 +++++- sftp-client.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- sftp-client.h | 6 ++- sftp-server.c | 75 +++++++++++++++++++++++++++++++++++- sftp.1 | 24 ++++++++++-- sftp.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++--- sftp.h | 6 ++- 7 files changed, 339 insertions(+), 15 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index b32f93f0c..eba49fee6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,15 @@ Use arc4random_uniform() when the desired random number upper bound is not a power of two ok deraadt@ millert@ + - djm@cvs.openbsd.org 2008/04/18 12:32:11 + [sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c sftp.h] + introduce sftp extension methods statvfs@openssh.com and + fstatvfs@openssh.com that implement statvfs(2)-like operations, + based on a patch from miklos AT szeredi.hu (bz#1399) + also add a "df" command to the sftp client that uses the + statvfs@openssh.com to produce a df(1)-like display of filesystem + space and inode utilisation + ok markus@ 20080403 - (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile- @@ -3881,4 +3890,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4910 2008/05/19 04:50:00 djm Exp $ +$Id: ChangeLog,v 1.4911 2008/05/19 04:53:33 djm Exp $ diff --git a/sftp-client.c b/sftp-client.c index 69c637785..1e54348b7 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.81 2008/03/23 12:54:01 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.82 2008/04/18 12:32:11 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -24,6 +24,7 @@ #include #include +#include #include "openbsd-compat/sys-queue.h" #ifdef HAVE_SYS_STAT_H # include @@ -65,7 +66,9 @@ struct sftp_conn { u_int num_requests; u_int version; u_int msg_id; -#define SFTP_EXT_POSIX_RENAME 1 +#define SFTP_EXT_POSIX_RENAME 0x00000001 +#define SFTP_EXT_STATVFS 0x00000002 +#define SFTP_EXT_FSTATVFS 0x00000004 u_int exts; }; @@ -238,6 +241,56 @@ get_decode_stat(int fd, u_int expected_id, int quiet) return(a); } +static int +get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) +{ + Buffer msg; + u_int type, id, flag; + + buffer_init(&msg); + get_msg(fd, &msg); + + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + debug3("Received statvfs reply T:%u I:%u", type, id); + if (id != expected_id) + fatal("ID mismatch (%u != %u)", id, expected_id); + if (type == SSH2_FXP_STATUS) { + int status = buffer_get_int(&msg); + + if (quiet) + debug("Couldn't statvfs: %s", fx2txt(status)); + else + error("Couldn't statvfs: %s", fx2txt(status)); + buffer_free(&msg); + return -1; + } else if (type != SSH2_FXP_EXTENDED_REPLY) { + fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", + SSH2_FXP_EXTENDED_REPLY, type); + } + + bzero(st, sizeof(*st)); + st->f_bsize = buffer_get_int(&msg); + st->f_frsize = buffer_get_int(&msg); + st->f_blocks = buffer_get_int64(&msg); + st->f_bfree = buffer_get_int64(&msg); + st->f_bavail = buffer_get_int64(&msg); + st->f_files = buffer_get_int64(&msg); + st->f_ffree = buffer_get_int64(&msg); + st->f_favail = buffer_get_int64(&msg); + st->f_fsid = buffer_get_int(&msg); + flag = buffer_get_int(&msg); + st->f_namemax = buffer_get_int(&msg); + + st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; + st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; + + buffer_free(&msg); + + return 0; +} + struct sftp_conn * do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) { @@ -272,8 +325,15 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) char *value = buffer_get_string(&msg, NULL); debug2("Init extension: \"%s\"", name); - if (strcmp(name, "posix-rename@openssh.com") == 0) + if (strcmp(name, "posix-rename@openssh.com") == 0 && + strcmp(value, "1") == 0) exts |= SFTP_EXT_POSIX_RENAME; + if (strcmp(name, "statvfs@openssh.com") == 0 && + strcmp(value, "1") == 0) + exts |= SFTP_EXT_STATVFS; + if (strcmp(name, "fstatvfs@openssh.com") == 0 && + strcmp(value, "1") == 0) + exts |= SFTP_EXT_FSTATVFS; xfree(name); xfree(value); } @@ -749,6 +809,60 @@ do_readlink(struct sftp_conn *conn, char *path) } #endif +int +do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st, + int quiet) +{ + Buffer msg; + u_int id; + + if ((conn->exts & SFTP_EXT_STATVFS) == 0) { + error("Server does not support statvfs@openssh.com extension"); + return -1; + } + + id = conn->msg_id++; + + buffer_init(&msg); + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "statvfs@openssh.com"); + buffer_put_cstring(&msg, path); + send_msg(conn->fd_out, &msg); + buffer_free(&msg); + + return get_decode_statvfs(conn->fd_in, st, id, quiet); +} + +#ifdef notyet +int +do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, + struct statvfs *st, int quiet) +{ + Buffer msg; + u_int id; + + if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) { + error("Server does not support fstatvfs@openssh.com extension"); + return -1; + } + + id = conn->msg_id++; + + buffer_init(&msg); + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "fstatvfs@openssh.com"); + buffer_put_string(&msg, handle, handle_len); + send_msg(conn->fd_out, &msg); + buffer_free(&msg); + + return get_decode_statvfs(conn->fd_in, st, id, quiet); +} +#endif + static void send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, char *handle, u_int handle_len) diff --git a/sftp-client.h b/sftp-client.h index fd0630e9a..b102e1180 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.15 2008/01/11 07:22:28 chl Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.16 2008/04/18 12:32:11 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -70,6 +70,10 @@ int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); /* Canonicalise 'path' - caller must free result */ char *do_realpath(struct sftp_conn *, char *); +/* Get statistics for filesystem hosting file at "path" */ +struct statvfs; +int do_statvfs(struct sftp_conn *, const char *, struct statvfs *, int); + /* Rename 'oldpath' to 'newpath' */ int do_rename(struct sftp_conn *, char *, char *); diff --git a/sftp-server.c b/sftp-server.c index d9549f5bc..300fd5cfd 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.78 2008/02/27 20:21:15 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.79 2008/04/18 12:32:11 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -23,6 +23,8 @@ #ifdef HAVE_SYS_TIME_H # include #endif +#include +#include #include #include @@ -475,6 +477,33 @@ send_attrib(u_int32_t id, const Attrib *a) buffer_free(&msg); } +static void +send_statvfs(u_int32_t id, struct statvfs *st) +{ + Buffer msg; + u_int64_t flag; + + flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; + flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); + buffer_put_int(&msg, id); + buffer_put_int(&msg, st->f_bsize); + buffer_put_int(&msg, st->f_frsize); + buffer_put_int64(&msg, st->f_blocks); + buffer_put_int64(&msg, st->f_bfree); + buffer_put_int64(&msg, st->f_bavail); + buffer_put_int64(&msg, st->f_files); + buffer_put_int64(&msg, st->f_ffree); + buffer_put_int64(&msg, st->f_favail); + buffer_put_int(&msg, st->f_fsid); + buffer_put_int(&msg, flag); + buffer_put_int(&msg, st->f_namemax); + send_msg(&msg); + buffer_free(&msg); +} + /* parse incoming */ static void @@ -490,6 +519,10 @@ process_init(void) /* POSIX rename extension */ buffer_put_cstring(&msg, "posix-rename@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ + buffer_put_cstring(&msg, "statvfs@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ + buffer_put_cstring(&msg, "fstatvfs@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ send_msg(&msg); buffer_free(&msg); } @@ -1099,6 +1132,42 @@ process_extended_posix_rename(u_int32_t id) xfree(newpath); } +static void +process_extended_statvfs(u_int32_t id) +{ + char *path; + struct statvfs st; + + path = get_string(NULL); + debug3("request %u: statfs", id); + logit("statfs \"%s\"", path); + + if (statvfs(path, &st) != 0) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); + xfree(path); +} + +static void +process_extended_fstatvfs(u_int32_t id) +{ + int handle, fd; + struct statvfs st; + + handle = get_handle(); + debug("request %u: fstatvfs \"%s\" (handle %u)", + id, handle_to_name(handle), handle); + if ((fd = handle_to_fd(handle)) < 0) { + send_status(id, SSH2_FX_FAILURE); + return; + } + if (fstatvfs(fd, &st) != 0) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); +} + static void process_extended(void) { @@ -1109,6 +1178,10 @@ process_extended(void) request = get_string(NULL); if (strcmp(request, "posix-rename@openssh.com") == 0) process_extended_posix_rename(id); + else if (strcmp(request, "statvfs@openssh.com") == 0) + process_extended_statvfs(id); + else if (strcmp(request, "fstatvfs@openssh.com") == 0) + process_extended_fstatvfs(id); else send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); diff --git a/sftp.1 b/sftp.1 index 1f517a40a..f34f58856 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.64 2007/05/31 19:20:16 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.65 2008/04/18 12:32:11 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: April 18 2008 $ .Dt SFTP 1 .Os .Sh NAME @@ -112,7 +112,7 @@ will abort if any of the following commands fail: .Ic get , put , rename , ln , .Ic rm , mkdir , chdir , ls , -.Ic lchdir , chmod , chown , chgrp , lpwd +.Ic lchdir , chmod , chown , chgrp , lpwd, df, and .Ic lmkdir . Termination on error can be suppressed on a command by command basis by @@ -272,6 +272,24 @@ may contain characters and may match multiple files. .Ar own must be a numeric UID. +.It Xo Ic df +.Op Fl hi +.Op Ar path +.Xc +Display usage information for the filesystem holding the current directory +(or +.Ar path +if specified). +If the +.Fl h +flag is specified, the capacity information will be displayed using +"human-readable" suffixes. +The +.Fl i +flag requests display of inode information in addition to capacity information. +This command is only supported on servers that implement the +.Dq statvfs@openssh.com +extension. .It Ic exit Quit .Nm sftp . diff --git a/sftp.c b/sftp.c index 861c3db05..0745baf08 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.99 2008/01/20 00:38:30 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.100 2008/04/18 12:32:11 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ typedef void EditLine; #include #include #include +#include #include #include "xmalloc.h" @@ -104,6 +106,7 @@ extern char *__progname; #define I_CHGRP 2 #define I_CHMOD 3 #define I_CHOWN 4 +#define I_DF 24 #define I_GET 5 #define I_HELP 6 #define I_LCHDIR 7 @@ -136,6 +139,7 @@ static const struct CMD cmds[] = { { "chgrp", I_CHGRP }, { "chmod", I_CHMOD }, { "chown", I_CHOWN }, + { "df", I_DF }, { "dir", I_LS }, { "exit", I_QUIT }, { "get", I_GET }, @@ -200,6 +204,8 @@ help(void) printf("chgrp grp path Change group of file 'path' to 'grp'\n"); printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); printf("chown own path Change owner of file 'path' to 'own'\n"); + printf("df [path] Display statistics for current directory or\n"); + printf(" filesystem containing 'path'\n"); printf("help Display this help text\n"); printf("get remote-path [local-path] Download file\n"); printf("lls [ls-options [path]] Display local directory listing\n"); @@ -421,6 +427,33 @@ parse_ls_flags(char **argv, int argc, int *lflag) return optind; } +static int +parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag) +{ + extern int optind, optreset, opterr; + int ch; + + optind = optreset = 1; + opterr = 0; + + *hflag = *iflag = 0; + while ((ch = getopt(argc, argv, "hi")) != -1) { + switch (ch) { + case 'h': + *hflag = 1; + break; + case 'i': + *iflag = 1; + break; + default: + error("%s: Invalid flag -%c", cmd, ch); + return -1; + } + } + + return optind; +} + static int is_dir(char *path) { @@ -797,6 +830,56 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, return (0); } +static int +do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) +{ + struct statvfs st; + char s_used[FMT_SCALED_STRSIZE]; + char s_avail[FMT_SCALED_STRSIZE]; + char s_root[FMT_SCALED_STRSIZE]; + char s_total[FMT_SCALED_STRSIZE]; + + if (do_statvfs(conn, path, &st, 1) == -1) + return -1; + if (iflag) { + printf(" Inodes Used Avail " + "(root) %%Capacity\n"); + printf("%11llu %11llu %11llu %11llu %3llu%%\n", + (unsigned long long)st.f_files, + (unsigned long long)(st.f_files - st.f_ffree), + (unsigned long long)st.f_favail, + (unsigned long long)st.f_ffree, + (unsigned long long)(100 * (st.f_files - st.f_ffree) / + st.f_files)); + } else if (hflag) { + strlcpy(s_used, "error", sizeof(s_used)); + strlcpy(s_avail, "error", sizeof(s_avail)); + strlcpy(s_root, "error", sizeof(s_root)); + strlcpy(s_total, "error", sizeof(s_total)); + fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used); + fmt_scaled(st.f_bavail * st.f_frsize, s_avail); + fmt_scaled(st.f_bfree * st.f_frsize, s_root); + fmt_scaled(st.f_blocks * st.f_frsize, s_total); + printf(" Size Used Avail (root) %%Capacity\n"); + printf("%7sB %7sB %7sB %7sB %3llu%%\n", + s_total, s_used, s_avail, s_root, + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } else { + printf(" Size Used Avail " + "(root) %%Capacity\n"); + printf("%12llu %12llu %12llu %12llu %3llu%%\n", + (unsigned long long)(st.f_frsize * st.f_blocks / 1024), + (unsigned long long)(st.f_frsize * + (st.f_blocks - st.f_bfree) / 1024), + (unsigned long long)(st.f_frsize * st.f_bavail / 1024), + (unsigned long long)(st.f_frsize * st.f_bfree / 1024), + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } + return 0; +} + /* * Undo escaping of glob sequences in place. Used to undo extra escaping * applied in makeargv() when the string is destined for a function that @@ -972,7 +1055,7 @@ makeargv(const char *arg, int *argcp) } static int -parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, +parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; @@ -1016,7 +1099,7 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, } /* Get arguments and parse flags */ - *lflag = *pflag = *n_arg = 0; + *lflag = *pflag = *hflag = *n_arg = 0; *path1 = *path2 = NULL; optidx = 1; switch (cmdnum) { @@ -1068,6 +1151,18 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, if (cmdnum != I_RM) undo_glob_escape(*path1); break; + case I_DF: + if ((optidx = parse_df_flags(cmd, argv, argc, hflag, + iflag)) == -1) + return -1; + /* Default to current directory if no path specified */ + if (argc - optidx < 1) + *path1 = NULL; + else { + *path1 = xstrdup(argv[optidx]); + undo_glob_escape(*path1); + } + break; case I_LS: if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1) return(-1); @@ -1130,7 +1225,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int pflag, lflag, iflag, cmdnum, i; + int pflag, lflag, iflag, hflag, cmdnum, i; unsigned long n_arg; Attrib a, *aa; char path_buf[MAXPATHLEN]; @@ -1138,7 +1233,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, + cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg, &path1, &path2); if (iflag != 0) @@ -1232,6 +1327,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, path1 = make_absolute(path1, *pwd); err = do_globbed_ls(conn, path1, tmp, lflag); break; + case I_DF: + /* Default to current directory if no path specified */ + if (path1 == NULL) + path1 = xstrdup(*pwd); + path1 = make_absolute(path1, *pwd); + err = do_df(conn, path1, hflag, iflag); + break; case I_LCHDIR: if (chdir(path1) == -1) { error("Couldn't change local directory to " diff --git a/sftp.h b/sftp.h index 0835da6ed..b101b95a0 100644 --- a/sftp.h +++ b/sftp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.h,v 1.7 2008/02/08 23:24:07 djm Exp $ */ +/* $OpenBSD: sftp.h,v 1.8 2008/04/18 12:32:11 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -79,6 +79,10 @@ #define SSH2_FXF_TRUNC 0x00000010 #define SSH2_FXF_EXCL 0x00000020 +/* statvfs@openssh.com f_flag flags */ +#define SSH2_FXE_STATVFS_ST_RDONLY 0x00000001 +#define SSH2_FXE_STATVFS_ST_NOSUID 0x00000002 + /* status messages */ #define SSH2_FX_OK 0 #define SSH2_FX_EOF 1 -- cgit v1.2.3 From a7e0d5a34a12dcfac0cf3b60b3696271861a586c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 19 May 2008 16:08:41 +1000 Subject: - djm@cvs.openbsd.org 2008/05/18 21:29:05 [sftp-server.c] comment extension announcement --- ChangeLog | 5 ++++- sftp-server.c | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 49caf7c08..7a64c2e63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -148,6 +148,9 @@ [nchan2.ms] document eow message in ssh protocol 2 channel state machine; feedback and ok markus@ + - djm@cvs.openbsd.org 2008/05/18 21:29:05 + [sftp-server.c] + comment extension announcement 20080403 - (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile- @@ -4008,4 +4011,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4932 2008/05/19 06:08:20 djm Exp $ +$Id: ChangeLog,v 1.4933 2008/05/19 06:08:41 djm Exp $ diff --git a/sftp-server.c b/sftp-server.c index 300fd5cfd..a2df09f53 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.79 2008/04/18 12:32:11 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.80 2008/05/18 21:29:05 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -519,8 +519,10 @@ process_init(void) /* POSIX rename extension */ buffer_put_cstring(&msg, "posix-rename@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ + /* statvfs extension */ buffer_put_cstring(&msg, "statvfs@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ + /* fstatvfs extension */ buffer_put_cstring(&msg, "fstatvfs@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ send_msg(&msg); -- cgit v1.2.3 From 5b2e2ba9e40d77d5876a96b248f9c526f8611b7c Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 8 Jun 2008 09:25:28 +1000 Subject: - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c] Do not enable statvfs extensions on platforms that do not have statvfs. ok djm@ --- ChangeLog | 4 +++- configure.ac | 8 ++++++-- defines.h | 6 +++++- sftp-client.c | 6 ++++++ sftp-server.c | 12 ++++++++++++ sftp.c | 7 +++++++ 6 files changed, 39 insertions(+), 4 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index c3c849c22..34cf9f2f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 20080607 - (dtucker) [mux.c] Include paths.h inside ifdef HAVE_PATHS_H. + - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c] + Do not enable statvfs extensions on platforms that do not have statvfs. 20080604 - (djm) [openbsd-compat/bsd-arc4random.c] Fix math bug that caused bias @@ -4031,4 +4033,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4937 2008/06/06 20:25:15 dtucker Exp $ +$Id: ChangeLog,v 1.4938 2008/06/07 23:25:28 dtucker Exp $ diff --git a/configure.ac b/configure.ac index 858aeaf42..3005e21b5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.399 2008/05/19 22:57:06 djm Exp $ +# $Id: configure.ac,v 1.400 2008/06/07 23:25:28 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.399 $) +AC_REVISION($Revision: 1.400 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -267,6 +267,7 @@ AC_CHECK_HEADERS( \ sys/cdefs.h \ sys/dir.h \ sys/mman.h \ + sys/mount.h \ sys/ndir.h \ sys/poll.h \ sys/prctl.h \ @@ -276,6 +277,7 @@ AC_CHECK_HEADERS( \ sys/stream.h \ sys/stropts.h \ sys/strtio.h \ + sys/statvfs.h \ sys/sysmacros.h \ sys/time.h \ sys/timers.h \ @@ -1354,6 +1356,8 @@ AC_CHECK_FUNCS( \ sigvec \ snprintf \ socketpair \ + statfs \ + statvfs \ strdup \ strerror \ strlcat \ diff --git a/defines.h b/defines.h index ac19095a2..a2cc28d98 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.146 2008/02/28 08:22:04 dtucker Exp $ */ +/* $Id: defines.h,v 1.147 2008/06/07 23:25:28 dtucker Exp $ */ /* Constants */ @@ -567,6 +567,10 @@ struct winsize { # define CUSTOM_SSH_AUDIT_EVENTS #endif +#if defined(HAVE_STATVFS) +# define USE_STATVFS +#endif + #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) # define __func__ __FUNCTION__ #elif !defined(HAVE___func__) diff --git a/sftp-client.c b/sftp-client.c index 1e54348b7..8593cb8ce 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -24,7 +24,9 @@ #include #include +#ifdef HAVE_SYS_STATVFS_H #include +#endif #include "openbsd-compat/sys-queue.h" #ifdef HAVE_SYS_STAT_H # include @@ -241,6 +243,7 @@ get_decode_stat(int fd, u_int expected_id, int quiet) return(a); } +#ifdef USE_STATVFS static int get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) { @@ -290,6 +293,7 @@ get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) return 0; } +#endif struct sftp_conn * do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) @@ -809,6 +813,7 @@ do_readlink(struct sftp_conn *conn, char *path) } #endif +#ifdef USE_STATVFS int do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st, int quiet) @@ -834,6 +839,7 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st, return get_decode_statvfs(conn->fd_in, st, id, quiet); } +#endif #ifdef notyet int diff --git a/sftp-server.c b/sftp-server.c index a2df09f53..a9cc9408a 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -23,8 +23,12 @@ #ifdef HAVE_SYS_TIME_H # include #endif +#ifdef HAVE_SYS_MOUNT_H #include +#endif +#ifdef HAVE_SYS_STATVFS_H #include +#endif #include #include @@ -477,6 +481,7 @@ send_attrib(u_int32_t id, const Attrib *a) buffer_free(&msg); } +#ifdef USE_STATVFS static void send_statvfs(u_int32_t id, struct statvfs *st) { @@ -503,6 +508,7 @@ send_statvfs(u_int32_t id, struct statvfs *st) send_msg(&msg); buffer_free(&msg); } +#endif /* parse incoming */ @@ -519,12 +525,14 @@ process_init(void) /* POSIX rename extension */ buffer_put_cstring(&msg, "posix-rename@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ +#ifdef USEE_STATVFS /* statvfs extension */ buffer_put_cstring(&msg, "statvfs@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ /* fstatvfs extension */ buffer_put_cstring(&msg, "fstatvfs@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ +#endif send_msg(&msg); buffer_free(&msg); } @@ -1134,6 +1142,7 @@ process_extended_posix_rename(u_int32_t id) xfree(newpath); } +#ifdef USE_STATVFS static void process_extended_statvfs(u_int32_t id) { @@ -1169,6 +1178,7 @@ process_extended_fstatvfs(u_int32_t id) else send_statvfs(id, &st); } +#endif static void process_extended(void) @@ -1180,10 +1190,12 @@ process_extended(void) request = get_string(NULL); if (strcmp(request, "posix-rename@openssh.com") == 0) process_extended_posix_rename(id); +#ifdef USE_STATVFS else if (strcmp(request, "statvfs@openssh.com") == 0) process_extended_statvfs(id); else if (strcmp(request, "fstatvfs@openssh.com") == 0) process_extended_fstatvfs(id); +#endif else send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); diff --git a/sftp.c b/sftp.c index ffc35cb83..c5c3b1443 100644 --- a/sftp.c +++ b/sftp.c @@ -25,7 +25,9 @@ #include #include #include +#ifdef HAVE_SYS_STATVFS_H #include +#endif #include #include @@ -840,6 +842,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, static int do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) { +#ifdef USE_STATVFS struct statvfs st; char s_used[FMT_SCALED_STRSIZE]; char s_avail[FMT_SCALED_STRSIZE]; @@ -885,6 +888,10 @@ do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) st.f_blocks)); } return 0; +#else + error("client does not support statvfs extension"); + return -1; +#endif } /* -- cgit v1.2.3 From 294b84183265a9be32971fce856e578160e1a825 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 8 Jun 2008 12:57:08 +1000 Subject: - djm@cvs.openbsd.org 2008/06/07 21:52:46 [sftp-server.c sftp-client.c] statvfs member fsid needs to be wider, increase it to 64 bits and crank extension revision number to 2; prodded and ok dtucker@ --- sftp-client.c | 8 ++++---- sftp-server.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'sftp-server.c') diff --git a/sftp-client.c b/sftp-client.c index 8593cb8ce..512a8ad4b 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.82 2008/04/18 12:32:11 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.83 2008/06/07 21:52:46 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -282,7 +282,7 @@ get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) st->f_files = buffer_get_int64(&msg); st->f_ffree = buffer_get_int64(&msg); st->f_favail = buffer_get_int64(&msg); - st->f_fsid = buffer_get_int(&msg); + st->f_fsid = buffer_get_int64(&msg); flag = buffer_get_int(&msg); st->f_namemax = buffer_get_int(&msg); @@ -333,10 +333,10 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) strcmp(value, "1") == 0) exts |= SFTP_EXT_POSIX_RENAME; if (strcmp(name, "statvfs@openssh.com") == 0 && - strcmp(value, "1") == 0) + strcmp(value, "2") == 0) exts |= SFTP_EXT_STATVFS; if (strcmp(name, "fstatvfs@openssh.com") == 0 && - strcmp(value, "1") == 0) + strcmp(value, "2") == 0) exts |= SFTP_EXT_FSTATVFS; xfree(name); xfree(value); diff --git a/sftp-server.c b/sftp-server.c index a9cc9408a..2c25df9de 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.80 2008/05/18 21:29:05 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.81 2008/06/07 21:52:46 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -502,7 +502,7 @@ send_statvfs(u_int32_t id, struct statvfs *st) buffer_put_int64(&msg, st->f_files); buffer_put_int64(&msg, st->f_ffree); buffer_put_int64(&msg, st->f_favail); - buffer_put_int(&msg, st->f_fsid); + buffer_put_int64(&msg, st->f_fsid); buffer_put_int(&msg, flag); buffer_put_int(&msg, st->f_namemax); send_msg(&msg); @@ -528,10 +528,10 @@ process_init(void) #ifdef USEE_STATVFS /* statvfs extension */ buffer_put_cstring(&msg, "statvfs@openssh.com"); - buffer_put_cstring(&msg, "1"); /* version */ + buffer_put_cstring(&msg, "2"); /* version */ /* fstatvfs extension */ buffer_put_cstring(&msg, "fstatvfs@openssh.com"); - buffer_put_cstring(&msg, "1"); /* version */ + buffer_put_cstring(&msg, "2"); /* version */ #endif send_msg(&msg); buffer_free(&msg); -- cgit v1.2.3 From 598eaa6c0c36c3169963c7e6505d53b4073590f5 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 9 Jun 2008 03:32:29 +1000 Subject: - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h openbsd-compat/bsd-statvfs.{c,h}] Add a null implementation of statvfs and fstatvfs and remove #defines around statvfs code. ok djm@ --- ChangeLog | 8 ++++- configure.ac | 17 +++++++++-- defines.h | 6 +--- openbsd-compat/Makefile.in | 4 +-- openbsd-compat/bsd-statvfs.c | 37 ++++++++++++++++++++++ openbsd-compat/bsd-statvfs.h | 68 +++++++++++++++++++++++++++++++++++++++++ openbsd-compat/openbsd-compat.h | 3 +- sftp-client.c | 4 --- sftp-server.c | 8 ----- sftp.c | 5 --- 10 files changed, 132 insertions(+), 28 deletions(-) create mode 100644 openbsd-compat/bsd-statvfs.c create mode 100644 openbsd-compat/bsd-statvfs.h (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index be3e104ee..9b3e1d6d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20080608 + - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c + openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h + openbsd-compat/bsd-statvfs.{c,h}] Add a null implementation of statvfs and + fstatvfs and remove #defines around statvfs code. ok djm@ + 20080607 - (dtucker) [mux.c] Include paths.h inside ifdef HAVE_PATHS_H. - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c] @@ -4054,4 +4060,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4942 2008/06/08 02:55:32 dtucker Exp $ +$Id: ChangeLog,v 1.4943 2008/06/08 17:32:29 dtucker Exp $ diff --git a/configure.ac b/configure.ac index 3005e21b5..4f3ec2a20 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.400 2008/06/07 23:25:28 dtucker Exp $ +# $Id: configure.ac,v 1.401 2008/06/08 17:32:29 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.400 $) +AC_REVISION($Revision: 1.401 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -1305,6 +1305,7 @@ AC_CHECK_FUNCS( \ fchmod \ fchown \ freeaddrinfo \ + fstatvfs \ futimes \ getaddrinfo \ getcwd \ @@ -2651,6 +2652,18 @@ fi TYPE_SOCKLEN_T AC_CHECK_TYPES(sig_atomic_t,,,[#include ]) +AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t],,,[ +#include +#ifdef HAVE_SYS_BITYPES_H +#include +#endif +#ifdef HAVE_SYS_STATFS_H +#include +#endif +#ifdef HAVE_SYS_STATVFS_H +#include +#endif +]) AC_CHECK_TYPES(in_addr_t,,, [#include diff --git a/defines.h b/defines.h index a2cc28d98..7bb3a55e8 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.147 2008/06/07 23:25:28 dtucker Exp $ */ +/* $Id: defines.h,v 1.148 2008/06/08 17:32:29 dtucker Exp $ */ /* Constants */ @@ -567,10 +567,6 @@ struct winsize { # define CUSTOM_SSH_AUDIT_EVENTS #endif -#if defined(HAVE_STATVFS) -# define USE_STATVFS -#endif - #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) # define __func__ __FUNCTION__ #elif !defined(HAVE___func__) diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index d1ec47b6e..a60e5a68d 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.42 2008/05/19 22:57:08 djm Exp $ +# $Id: Makefile.in,v 1.43 2008/06/08 17:32:29 dtucker Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o -COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o +COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o diff --git a/openbsd-compat/bsd-statvfs.c b/openbsd-compat/bsd-statvfs.c new file mode 100644 index 000000000..844d5b464 --- /dev/null +++ b/openbsd-compat/bsd-statvfs.c @@ -0,0 +1,37 @@ +/* $Id: bsd-statvfs.c,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */ + +/* + * Copyright (c) 2008 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include + +#ifndef HAVE_STATVFS +int statvfs(const char *path, struct statvfs *buf) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_FSTATVFS +int fstatvfs(int fd, struct statvfs *buf) +{ + errno = ENOSYS; + return -1; +} +#endif diff --git a/openbsd-compat/bsd-statvfs.h b/openbsd-compat/bsd-statvfs.h new file mode 100644 index 000000000..da215ffc6 --- /dev/null +++ b/openbsd-compat/bsd-statvfs.h @@ -0,0 +1,68 @@ +/* $Id: bsd-statvfs.h,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */ + +/* + * Copyright (c) 2008 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include + +#ifdef HAVE_SYS_STATFS_H +#include +#endif + +#ifndef HAVE_STATVFS + +#ifndef HAVE_FSBLKCNT_T +typedef unsigned long fsblkcnt_t; +#endif +#ifndef HAVE_FSFILCNT_T +typedef unsigned long fsfilcnt_t; +#endif + +#ifndef ST_RDONLY +#define ST_RDONLY 1 +#endif +#ifndef ST_NOSUID +#define ST_NOSUID 2 +#endif + + /* as defined in IEEE Std 1003.1, 2004 Edition */ +struct statvfs { + unsigned long f_bsize; /* File system block size. */ + unsigned long f_frsize; /* Fundamental file system block size. */ + fsblkcnt_t f_blocks; /* Total number of blocks on file system in */ + /* units of f_frsize. */ + fsblkcnt_t f_bfree; /* Total number of free blocks. */ + fsblkcnt_t f_bavail; /* Number of free blocks available to */ + /* non-privileged process. */ + fsfilcnt_t f_files; /* Total number of file serial numbers. */ + fsfilcnt_t f_ffree; /* Total number of free file serial numbers. */ + fsfilcnt_t f_favail; /* Number of file serial numbers available to */ + /* non-privileged process. */ + unsigned long f_fsid; /* File system ID. */ + unsigned long f_flag; /* BBit mask of f_flag values. */ + unsigned long f_namemax;/* Maximum filename length. */ +}; +#endif + +#ifndef HAVE_STATVFS +int statvfs(const char *, struct statvfs *); +#endif + +#ifndef HAVE_FSTATVFS +int fstatvfs(int, struct statvfs *); +#endif diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 0b7d979e0..50c6d990b 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.45 2008/05/19 22:57:08 djm Exp $ */ +/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -144,6 +144,7 @@ int writev(int, struct iovec *, int); /* Home grown routines */ #include "bsd-misc.h" +#include "bsd-statvfs.h" #include "bsd-waitpid.h" #include "bsd-poll.h" diff --git a/sftp-client.c b/sftp-client.c index 512a8ad4b..1fda576b4 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -243,7 +243,6 @@ get_decode_stat(int fd, u_int expected_id, int quiet) return(a); } -#ifdef USE_STATVFS static int get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) { @@ -293,7 +292,6 @@ get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) return 0; } -#endif struct sftp_conn * do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) @@ -813,7 +811,6 @@ do_readlink(struct sftp_conn *conn, char *path) } #endif -#ifdef USE_STATVFS int do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st, int quiet) @@ -839,7 +836,6 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st, return get_decode_statvfs(conn->fd_in, st, id, quiet); } -#endif #ifdef notyet int diff --git a/sftp-server.c b/sftp-server.c index 2c25df9de..9c3128347 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -481,7 +481,6 @@ send_attrib(u_int32_t id, const Attrib *a) buffer_free(&msg); } -#ifdef USE_STATVFS static void send_statvfs(u_int32_t id, struct statvfs *st) { @@ -508,7 +507,6 @@ send_statvfs(u_int32_t id, struct statvfs *st) send_msg(&msg); buffer_free(&msg); } -#endif /* parse incoming */ @@ -525,14 +523,12 @@ process_init(void) /* POSIX rename extension */ buffer_put_cstring(&msg, "posix-rename@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ -#ifdef USEE_STATVFS /* statvfs extension */ buffer_put_cstring(&msg, "statvfs@openssh.com"); buffer_put_cstring(&msg, "2"); /* version */ /* fstatvfs extension */ buffer_put_cstring(&msg, "fstatvfs@openssh.com"); buffer_put_cstring(&msg, "2"); /* version */ -#endif send_msg(&msg); buffer_free(&msg); } @@ -1142,7 +1138,6 @@ process_extended_posix_rename(u_int32_t id) xfree(newpath); } -#ifdef USE_STATVFS static void process_extended_statvfs(u_int32_t id) { @@ -1178,7 +1173,6 @@ process_extended_fstatvfs(u_int32_t id) else send_statvfs(id, &st); } -#endif static void process_extended(void) @@ -1190,12 +1184,10 @@ process_extended(void) request = get_string(NULL); if (strcmp(request, "posix-rename@openssh.com") == 0) process_extended_posix_rename(id); -#ifdef USE_STATVFS else if (strcmp(request, "statvfs@openssh.com") == 0) process_extended_statvfs(id); else if (strcmp(request, "fstatvfs@openssh.com") == 0) process_extended_fstatvfs(id); -#endif else send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); diff --git a/sftp.c b/sftp.c index c5c3b1443..50ac03798 100644 --- a/sftp.c +++ b/sftp.c @@ -842,7 +842,6 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, static int do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) { -#ifdef USE_STATVFS struct statvfs st; char s_used[FMT_SCALED_STRSIZE]; char s_avail[FMT_SCALED_STRSIZE]; @@ -888,10 +887,6 @@ do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) st.f_blocks)); } return 0; -#else - error("client does not support statvfs extension"); - return -1; -#endif } /* -- cgit v1.2.3 From 77001384cc067a4613dd6d7a07b9a786f7d7f1bb Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 9 Jun 2008 06:17:53 +1000 Subject: - (dtucker) [configure.ac defines.h sftp-client.c M sftp-server.c] Add a macro to convert fsid to unsigned long for platforms where fsid is a 2-member array. --- ChangeLog | 5 ++++- configure.ac | 14 ++++++++++++-- defines.h | 11 ++++++++++- sftp-server.c | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 9b3e1d6d3..31abe27b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h openbsd-compat/bsd-statvfs.{c,h}] Add a null implementation of statvfs and fstatvfs and remove #defines around statvfs code. ok djm@ + - (dtucker) [configure.ac defines.h sftp-client.c M sftp-server.c] Add a + macro to convert fsid to unsigned long for platforms where fsid is a + 2-member array. 20080607 - (dtucker) [mux.c] Include paths.h inside ifdef HAVE_PATHS_H. @@ -4060,4 +4063,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4943 2008/06/08 17:32:29 dtucker Exp $ +$Id: ChangeLog,v 1.4944 2008/06/08 20:17:53 dtucker Exp $ diff --git a/configure.ac b/configure.ac index 4f3ec2a20..9f39b2333 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.401 2008/06/08 17:32:29 dtucker Exp $ +# $Id: configure.ac,v 1.402 2008/06/08 20:17:53 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.401 $) +AC_REVISION($Revision: 1.402 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -3026,6 +3026,16 @@ if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then file descriptor passing]) fi +AC_MSG_CHECKING(if f_fsid has val members) +AC_TRY_COMPILE([ +#include +#include ], +[struct fsid_t t; t.val[0] = 0;], + [ AC_MSG_RESULT(yes) + AC_DEFINE(FSID_HAS_VAL, 1, f_fsid has members) ], + [ AC_MSG_RESULT(no) ] +) + AC_CACHE_CHECK([for msg_control field in struct msghdr], ac_cv_have_control_in_msghdr, [ AC_COMPILE_IFELSE( diff --git a/defines.h b/defines.h index 7bb3a55e8..0665d2b51 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.148 2008/06/08 17:32:29 dtucker Exp $ */ +/* $Id: defines.h,v 1.149 2008/06/08 20:17:53 dtucker Exp $ */ /* Constants */ @@ -590,6 +590,15 @@ struct winsize { # define SSH_SYSFDMAX 10000 #endif +#ifdef FSID_HAS_VAL +/* encode f_fsid into a 64 bit value */ +#define FSID_TO_ULONG(f) \ + ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \ + ((f).val[1] & 0xffffffffUL)) +#else +# define FSID_TO_ULONG(f) ((f)) +#endif + #if defined(__Lynx__) /* * LynxOS defines these in param.h which we do not want to include since diff --git a/sftp-server.c b/sftp-server.c index 9c3128347..f69926164 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -501,7 +501,7 @@ send_statvfs(u_int32_t id, struct statvfs *st) buffer_put_int64(&msg, st->f_files); buffer_put_int64(&msg, st->f_ffree); buffer_put_int64(&msg, st->f_favail); - buffer_put_int64(&msg, st->f_fsid); + buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid)); buffer_put_int(&msg, flag); buffer_put_int(&msg, st->f_namemax); send_msg(&msg); -- cgit v1.2.3 From 422c34c96dd7e6dcb507747bdbb499e96000aa5f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 9 Jun 2008 22:48:31 +1000 Subject: - dtucker@cvs.openbsd.org 2008/06/08 17:04:41 [sftp-server.c] Add case for ENOSYS in errno_to_portable; ok deraadt --- ChangeLog | 8 +++++++- sftp-server.c | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 31abe27b1..f183a83e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +20080609 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2008/06/08 17:04:41 + [sftp-server.c] + Add case for ENOSYS in errno_to_portable; ok deraadt + 20080608 - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h @@ -4063,4 +4069,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4944 2008/06/08 20:17:53 dtucker Exp $ +$Id: ChangeLog,v 1.4945 2008/06/09 12:48:31 dtucker Exp $ diff --git a/sftp-server.c b/sftp-server.c index f69926164..fbf620989 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.81 2008/06/07 21:52:46 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.82 2008/06/08 17:04:41 dtucker Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -104,6 +104,9 @@ errno_to_portable(int unixerrno) case EINVAL: ret = SSH2_FX_BAD_MESSAGE; break; + case ENOSYS: + ret = SSH2_FX_OP_UNSUPPORTED; + break; default: ret = SSH2_FX_FAILURE; break; -- cgit v1.2.3 From 3463acaebfe90c10d22c0baaff556559bfd66fd6 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 9 Jun 2008 23:06:55 +1000 Subject: - dtucker@cvs.openbsd.org 2008/06/09 13:02:39 Extend 32bit -> 64bit values for statvfs extension missed in previous commit. --- ChangeLog | 5 ++++- sftp-server.c | 10 +++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 88be1a8fa..95552945e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,9 @@ client's. Also extends the sizes of the remaining 32bit wire format to 64bit, they're specified as unsigned long in the standard. + - dtucker@cvs.openbsd.org 2008/06/09 13:02:39 + Extend 32bit -> 64bit values for statvfs extension missed in previous + commit. 20080608 - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c @@ -4076,4 +4079,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4946 2008/06/09 12:49:36 dtucker Exp $ +$Id: ChangeLog,v 1.4947 2008/06/09 13:06:55 dtucker Exp $ diff --git a/sftp-server.c b/sftp-server.c index fbf620989..4022b93b6 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.82 2008/06/08 17:04:41 dtucker Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.83 2008/06/09 13:02:39 dtucker Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -496,8 +496,8 @@ send_statvfs(u_int32_t id, struct statvfs *st) buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); buffer_put_int(&msg, id); - buffer_put_int(&msg, st->f_bsize); - buffer_put_int(&msg, st->f_frsize); + buffer_put_int64(&msg, st->f_bsize); + buffer_put_int64(&msg, st->f_frsize); buffer_put_int64(&msg, st->f_blocks); buffer_put_int64(&msg, st->f_bfree); buffer_put_int64(&msg, st->f_bavail); @@ -505,8 +505,8 @@ send_statvfs(u_int32_t id, struct statvfs *st) buffer_put_int64(&msg, st->f_ffree); buffer_put_int64(&msg, st->f_favail); buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid)); - buffer_put_int(&msg, flag); - buffer_put_int(&msg, st->f_namemax); + buffer_put_int64(&msg, flag); + buffer_put_int64(&msg, st->f_namemax); send_msg(&msg); buffer_free(&msg); } -- cgit v1.2.3 From 9e720284fe63aa8e59983b880447ed4ae768387c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 29 Jun 2008 22:46:35 +1000 Subject: - djm@cvs.openbsd.org 2008/06/26 06:10:09 [sftp-client.c sftp-server.c] allow the sftp chmod(2)-equivalent operation to set set[ug]id/sticky bits. Note that this only affects explicit setting of modes (e.g. via sftp(1)'s chmod command) and not file transfers. (bz#1310) ok deraadt@ at c2k8 --- ChangeLog | 8 +++++++- sftp-client.c | 4 ++-- sftp-server.c | 10 +++++----- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 5cde1b698..ce856bc7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,12 @@ [key.c] add key length to visual fingerprint; zap magical constants; ok grunk@ djm@ + - djm@cvs.openbsd.org 2008/06/26 06:10:09 + [sftp-client.c sftp-server.c] + allow the sftp chmod(2)-equivalent operation to set set[ug]id/sticky + bits. Note that this only affects explicit setting of modes (e.g. via + sftp(1)'s chmod command) and not file transfers. (bz#1310) + ok deraadt@ at c2k8 20080628 - (djm) [RFC.nroff contrib/cygwin/Makefile contrib/suse/openssh.spec] @@ -4428,4 +4434,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.5026 2008/06/29 12:45:37 djm Exp $ +$Id: ChangeLog,v 1.5027 2008/06/29 12:46:35 djm Exp $ diff --git a/sftp-client.c b/sftp-client.c index 2565a704d..42bf0c813 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.85 2008/06/12 20:47:04 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.86 2008/06/26 06:10:09 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -920,7 +920,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, if (a == NULL) return(-1); - /* XXX: should we preserve set[ug]id? */ + /* Do not preserve set[ug]id here, as we do not preserve ownership */ if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) mode = a->perm & 0777; else diff --git a/sftp-server.c b/sftp-server.c index 4022b93b6..a4c4f168f 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.83 2008/06/09 13:02:39 dtucker Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.84 2008/06/26 06:10:09 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -763,7 +763,7 @@ process_setstat(void) } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a->perm); - ret = chmod(name, a->perm & 0777); + ret = chmod(name, a->perm & 07777); if (ret == -1) status = errno_to_portable(errno); } @@ -817,9 +817,9 @@ process_fsetstat(void) if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a->perm); #ifdef HAVE_FCHMOD - ret = fchmod(fd, a->perm & 0777); + ret = fchmod(fd, a->perm & 07777); #else - ret = chmod(name, a->perm & 0777); + ret = chmod(name, a->perm & 07777); #endif if (ret == -1) status = errno_to_portable(errno); @@ -970,7 +970,7 @@ process_mkdir(void) name = get_string(NULL); a = get_attrib(); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? - a->perm & 0777 : 0777; + a->perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); ret = mkdir(name, mode); -- cgit v1.2.3 From f7fa706e70cc3d005acca995d022d65227185dcd Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 4 Jul 2008 14:10:19 +1000 Subject: - (dtucker) [sftp-server.c] Bug #1447: fall back to racy rename if link returns EXDEV. Patch from Mike Garrison, ok djm@ --- ChangeLog | 4 +++- sftp-server.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index b86b5e498..46785b799 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,8 @@ - dtucker@cvs.openbsd.org 2008/07/04 03:47:02 [monitor.c] Make debug a little clearer. ok djm@ + - (dtucker) [sftp-server.c] Bug #1447: fall back to racy rename if link + returns EXDEV. Patch from Mike Garrison, ok djm@ 20080702 - (dtucker) OpenBSD CVS Sync @@ -4553,4 +4555,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.5053 2008/07/04 03:51:45 dtucker Exp $ +$Id: ChangeLog,v 1.5054 2008/07/04 04:10:19 dtucker Exp $ diff --git a/sftp-server.c b/sftp-server.c index a4c4f168f..24c4ff717 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1042,6 +1042,9 @@ process_rename(void) /* Race-free rename of regular files */ if (link(oldpath, newpath) == -1) { if (errno == EOPNOTSUPP +#ifdef EXDEV + || errno == EXDEV +#endif #ifdef LINK_OPNOTSUPP_ERRNO || errno == LINK_OPNOTSUPP_ERRNO #endif -- cgit v1.2.3