Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-updates-src > by-pkgid > 765b0ce55b9baa6c70749f0319c589c7 > files > 8

openssh-6.6p1-5.3.mga5.src.rpm

diff -Naurp openssh-4.9p1/servconf.c openssh-4.9p1.oden/servconf.c
--- openssh-4.9p1/servconf.c	2008-02-10 12:48:55.000000000 +0100
+++ openssh-4.9p1.oden/servconf.c	2008-04-01 13:21:17.000000000 +0200
@@ -118,6 +118,15 @@ initialize_server_options(ServerOptions 
 	options->client_alive_count_max = -1;
 	options->authorized_keys_file = NULL;
 	options->authorized_keys_file2 = NULL;
+	options->log_sftp = LOG_SFTP_NOT_SET;
+ 	options->sftp_log_facility = SYSLOG_FACILITY_NOT_SET;
+ 	options->sftp_log_level = SYSLOG_LEVEL_NOT_SET;
+
+ 	memset(options->sftp_umask, 0, SFTP_UMASK_LENGTH);
+
+	options->sftp_permit_chmod = SFTP_PERMIT_NOT_SET;
+	options->sftp_permit_chown = SFTP_PERMIT_NOT_SET;
+
 	options->num_accept_env = 0;
 	options->permit_tun = -1;
 	options->num_permitted_opens = -1;
@@ -251,6 +260,24 @@ fill_default_server_options(ServerOption
 	if (options->permit_tun == -1)
 		options->permit_tun = SSH_TUNMODE_NO;
 
+	/* Turn sftp-server logging off by default */
+	if (options->log_sftp == LOG_SFTP_NOT_SET)
+		options->log_sftp = LOG_SFTP_NO;
+        if (options->sftp_log_facility == SYSLOG_FACILITY_NOT_SET)
+                options->sftp_log_facility = SYSLOG_FACILITY_AUTH;
+        if (options->sftp_log_level == SYSLOG_LEVEL_NOT_SET)
+                options->sftp_log_level = SYSLOG_LEVEL_INFO;
+
+	/* Don't set sftp-server umask */
+	if (!options->sftp_umask)
+		memset(options->sftp_umask, 0, SFTP_UMASK_LENGTH);
+
+	/* allow sftp client to issue chmod, chown / chgrp commands */
+	if (options->sftp_permit_chmod == SFTP_PERMIT_NOT_SET)
+		options->sftp_permit_chmod = SFTP_PERMIT_YES;
+	if (options->sftp_permit_chown == SFTP_PERMIT_NOT_SET)
+		options->sftp_permit_chown = SFTP_PERMIT_YES;
+
 	/* Turn privilege separation on by default */
 	if (use_privsep == -1)
 		use_privsep = 1;
@@ -294,6 +321,9 @@ typedef enum {
 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
 	sUsePrivilegeSeparation,
+	sLogSftp, sSftpLogFacility, sSftpLogLevel,
+	sSftpUmask,
+	sSftpPermitChown, sSftpPermitChmod,
 	sDeprecated, sUnsupported
 } ServerOpCodes;
 
@@ -400,6 +430,12 @@ static struct {
 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
+	{ "logsftp", sLogSftp},
+	{ "sftplogfacility", sSftpLogFacility},
+	{ "sftploglevel", sSftpLogLevel},
+	{ "sftpumask", sSftpUmask},
+	{ "sftppermitchmod", sSftpPermitChmod},
+	{ "sftppermitchown", sSftpPermitChown},
 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
  	{ "match", sMatch, SSHCFG_ALL },
 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
@@ -626,6 +662,8 @@ process_server_config_line(ServerOptions
 	SyslogFacility *log_facility_ptr;
 	LogLevel *log_level_ptr;
 	ServerOpCodes opcode;
+	unsigned int umaskvalue = 0;
+	char *umaskptr;
 	u_short port;
 	u_int i, flags = 0;
 	size_t len;
@@ -1150,6 +1188,57 @@ parse_flag:
 		charptr = &options->banner;
 		goto parse_filename;
 
+        case sLogSftp:
+                intptr = &options->log_sftp;
+                goto parse_flag;
+
+        case sSftpLogFacility:
+                intptr = (int *) &options->sftp_log_facility;
+                arg = strdelim(&cp);
+                value = log_facility_number(arg);
+                if (value == SYSLOG_FACILITY_NOT_SET)
+                        fatal("%.200s line %d: unsupported log facility '%s'",
+                            filename, linenum, arg ? arg : "<NONE>");
+                if (*intptr == -1)
+                        *intptr = (SyslogFacility) value;
+                break;
+
+        case sSftpLogLevel:
+                intptr = (int *) &options->sftp_log_level;
+                arg = strdelim(&cp);
+                value = log_level_number(arg);
+                if (value == SYSLOG_LEVEL_NOT_SET)
+                        fatal("%.200s line %d: unsupported log level '%s'",
+                            filename, linenum, arg ? arg : "<NONE>");
+                if (*intptr == -1)
+                        *intptr = (LogLevel) value;
+                break;
+
+        case sSftpUmask:
+                arg = strdelim(&cp);
+		umaskptr = arg;
+                while (*arg && *arg >= '0' && *arg <= '9')
+                    umaskvalue = umaskvalue * 8 + *arg++ - '0';
+                if (*arg || umaskvalue > 0777)
+                    fatal("%s line %d: bad value for umask",
+			    filename, linenum);
+		else {
+			while (*umaskptr && *umaskptr == '0')
+					*umaskptr++;
+			strncpy(options->sftp_umask, umaskptr,
+				SFTP_UMASK_LENGTH);
+		}
+
+                break;
+
+        case sSftpPermitChmod:
+                intptr = &options->sftp_permit_chmod;
+                goto parse_flag;
+
+        case sSftpPermitChown:
+                intptr = &options->sftp_permit_chown;
+                goto parse_flag;
+
 	/*
 	 * These options can contain %X options expanded at
 	 * connect time, so that you can specify paths like:
diff -Naurp openssh-4.9p1/servconf.h openssh-4.9p1.oden/servconf.h
--- openssh-4.9p1/servconf.h	2008-03-07 08:31:24.000000000 +0100
+++ openssh-4.9p1.oden/servconf.h	2008-04-01 13:18:51.000000000 +0200
@@ -34,6 +34,18 @@
 #define	PERMIT_NO_PASSWD	2
 #define	PERMIT_YES		3
 
+/* sftp-server logging */
+#define LOG_SFTP_NOT_SET	-1
+#define LOG_SFTP_NO		0
+#define LOG_SFTP_YES		1
+
+/* sftp-server umask control */
+#define SFTP_UMASK_LENGTH	5
+
+/* sftp-server client priviledge */
+#define SFTP_PERMIT_NOT_SET	-1
+#define SFTP_PERMIT_NO		0
+#define SFTP_PERMIT_YES		1
 #define DEFAULT_AUTH_FAIL_MAX	6	/* Default for MaxAuthTries */
 
 /* Magic name for internal sftp-server */
@@ -137,6 +149,12 @@ typedef struct {
 	char   *authorized_keys_file;	/* File containing public keys */
 	char   *authorized_keys_file2;
 
+	int	log_sftp;		/* perform sftp-server logging */
+	SyslogFacility sftp_log_facility;    /* Facility for sftp subsystem logging. */
+	LogLevel sftp_log_level;     /* Level for sftp subsystem logging. */
+	char	sftp_umask[SFTP_UMASK_LENGTH];		/* Sftp Umask */
+	int	sftp_permit_chmod;
+	int	sftp_permit_chown;
 	char   *adm_forced_command;
 
 	int	use_pam;		/* Enable auth via PAM */
diff -Naurp openssh-4.9p1/session.c openssh-4.9p1.oden/session.c
--- openssh-4.9p1/session.c	2008-03-27 01:03:05.000000000 +0100
+++ openssh-4.9p1.oden/session.c	2008-04-01 13:18:51.000000000 +0200
@@ -144,6 +144,15 @@ login_cap_t *lc;
 
 static int is_child = 0;
 
+/* so SFTP_LOG_FACILITY and SFTP_LOG_LEVEL can be passed through the 
+   environment to the sftp-server subsystem. */
+static const char *sysfac_to_int[] = { "0", "1", "2", "3", "4", "5", "6",
+	"7", "8", "9", "10", "11", "-1" };
+static const char *syslevel_to_int[] = { "0", "1", "2", "3", "4", "5", "6",
+	"7", "-1" };
+
+static char *sftpumask;
+
 /* Name and directory of socket for authentication agent forwarding. */
 static char *auth_sock_name = NULL;
 static char *auth_sock_dir = NULL;
@@ -1172,6 +1181,67 @@ do_setup_env(Session *s, const char *she
 		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
 		    auth_sock_name);
 
+	/* LOG_SFTP */
+	if (options.log_sftp == -1 )
+		child_set_env(&env, &envsize, "LOG_SFTP", "-1");
+	else if (options.log_sftp == 0)
+		child_set_env(&env, &envsize, "LOG_SFTP", "0");
+	else
+		child_set_env(&env, &envsize, "LOG_SFTP", "1");
+
+	/* SFTP_LOG_FACILITY */
+	if (options.sftp_log_facility < 0)
+		child_set_env(&env, &envsize, "SFTP_LOG_FACILITY",
+			"-1");
+	else
+		child_set_env(&env, &envsize, "SFTP_LOG_FACILITY", 
+			sysfac_to_int[options.sftp_log_facility]);
+
+	/* SFTP_LOG_LEVEL */
+        if (options.sftp_log_level < 0)
+                child_set_env(&env, &envsize, "SFTP_LOG_LEVEL",
+                        "-1");
+        else
+                child_set_env(&env, &envsize, "SFTP_LOG_LEVEL",
+                        syslevel_to_int[options.sftp_log_level]);
+
+	/* SFTP_UMASK */
+
+	if (options.sftp_umask[0] == '\0')
+		child_set_env(&env, &envsize, "SFTP_UMASK", 
+			"" );
+	else {
+		if (!(sftpumask = calloc(SFTP_UMASK_LENGTH,1))) {
+
+logit("session.c: unabled to allocate memory for SftpUmask. SftpUmask control \
+will be turned off.");
+
+		child_set_env(&env, &envsize, "SFTP_UMASK", 
+			"" );
+		} else {
+			strncpy(sftpumask, options.sftp_umask,
+				SFTP_UMASK_LENGTH);
+			child_set_env(&env, &envsize, "SFTP_UMASK", 
+				sftpumask );
+		}
+	}
+
+        /* SFTP_PERMIT_CHMOD */
+        if (options.sftp_permit_chmod == -1 )
+                child_set_env(&env, &envsize, "SFTP_PERMIT_CHMOD", "-1");
+        else if (options.sftp_permit_chmod == 0)
+                child_set_env(&env, &envsize, "SFTP_PERMIT_CHMOD", "0");
+        else
+                child_set_env(&env, &envsize, "SFTP_PERMIT_CHMOD", "1");
+
+        /* SFTP_PERMIT_CHOWN */
+        if (options.sftp_permit_chown == -1 )
+                child_set_env(&env, &envsize, "SFTP_PERMIT_CHOWN", "-1");
+        else if (options.sftp_permit_chown == 0)
+                child_set_env(&env, &envsize, "SFTP_PERMIT_CHOWN", "0");
+        else
+                child_set_env(&env, &envsize, "SFTP_PERMIT_CHOWN", "1");
+
 	/* read $HOME/.ssh/environment. */
 	if (options.permit_user_env && !options.use_login) {
 		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
diff -Naurp openssh-4.9p1/sftp-server.8 openssh-4.9p1.oden/sftp-server.8
--- openssh-4.9p1/sftp-server.8	2007-06-05 10:27:13.000000000 +0200
+++ openssh-4.9p1.oden/sftp-server.8	2008-04-01 13:18:51.000000000 +0200
@@ -50,6 +50,20 @@ should be specified in the
 declaration.
 See
 .Xr sshd_config 5
+for more information. Sftp-server transactions may be logged
+using the
+.Cm LogSftp ,
+.Cm SftpLogFacility ,
+and
+.Cm SftpLogLevel
+options. The administrator may exert control over the file and directory
+permission and ownership, with
+.Cm SftpUmask ,
+.Cm SftpPermitChmod ,
+and
+.Cm SftpPermitChown
+. See
+.Xr sshd_config 5
 for more information.
 .Pp
 Valid options are:
@@ -76,7 +90,8 @@ The default is ERROR.
 .Xr sftp 1 ,
 .Xr ssh 1 ,
 .Xr sshd_config 5 ,
-.Xr sshd 8
+.Xr sshd 8,
+.Xr sshd_config 5
 .Rs
 .%A T. Ylonen
 .%A S. Lehtinen
diff -Naurp openssh-4.9p1/sftp-server.c openssh-4.9p1.oden/sftp-server.c
--- openssh-4.9p1/sftp-server.c	2008-03-07 08:33:53.000000000 +0100
+++ openssh-4.9p1.oden/sftp-server.c	2008-04-01 13:27:43.000000000 +0200
@@ -50,6 +50,13 @@
 #define get_int()			buffer_get_int(&iqueue);
 #define get_string(lenp)		buffer_get_string(&iqueue, lenp);
 
+/* SFTP_UMASK */
+static mode_t setumask = 0;
+
+static int permit_chmod = 1;
+static int permit_chown = 1;
+static int permit_logging = 0;
+
 /* Our verbosity */
 LogLevel log_level = SYSLOG_LEVEL_ERROR;
 
@@ -509,6 +516,14 @@ process_open(void)
 	a = get_attrib();
 	flags = flags_from_portable(pflags);
 	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
+
+	if (setumask != 0) {
+		if ( permit_logging == 1 )
+		logit("setting file creation mode to 0666 and umask to %o", setumask);
+		mode = 0666;
+		umask(setumask);
+	}
+
 	logit("open \"%s\" flags %s mode 0%o",
 	    name, string_from_portable(pflags), mode);
 	fd = open(name, flags, mode);
@@ -523,6 +538,8 @@ process_open(void)
 			status = SSH2_FX_OK;
 		}
 	}
+	if ( permit_logging == 1 )
+	logit("open %s", name);
 	if (status != SSH2_FX_OK)
 		send_status(id, status);
 	xfree(name);
@@ -560,7 +577,8 @@ process_read(void)
 	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
 	if (len > sizeof buf) {
 		len = sizeof buf;
-		debug2("read change len %d", len);
+ 		if (permit_logging == 1)
+ 		logit("read change len %d", len);
 	}
 	fd = handle_to_fd(handle);
 	if (fd >= 0) {
@@ -580,6 +598,8 @@ process_read(void)
 			}
 		}
 	}
+	if ( permit_logging == 1 )
+	logit("reading %d bytes from file", ret);
 	if (status != SSH2_FX_OK)
 		send_status(id, status);
 }
@@ -615,10 +635,13 @@ process_write(void)
 				status = SSH2_FX_OK;
 				handle_update_write(handle, ret);
 			} else {
-				debug2("nothing at all written");
+				if ( permit_logging == 1 )
+				logit("nothing at all written");
 			}
 		}
 	}
+	if ( permit_logging == 1 )
+	logit("writing %d bytes to file", ret);
 	send_status(id, status);
 	xfree(data);
 }
@@ -720,15 +743,25 @@ process_setstat(void)
 			status = errno_to_portable(errno);
 	}
 	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
-		logit("set \"%s\" mode %04o", name, a->perm);
-		ret = chmod(name, a->perm & 0777);
-		if (ret == -1)
-			status = errno_to_portable(errno);
+		if (permit_chmod == 1) {
+			ret = chmod(name, a->perm & 0777);
+			if (ret == -1)
+				status = errno_to_portable(errno);
+			else
+				if ( permit_logging == 1 )
+				logit("chmod'ed %s", name);
+		} else {
+			status = SSH2_FX_PERMISSION_DENIED;
+			if ( permit_logging == 1 )
+			logit("chmod %s: operation prohibited by sftp-server configuration.", name);
+		}
 	}
 	if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
 		char buf[64];
 		time_t t = a->mtime;
 
+if ( permit_logging == 1 ) 
+logit("process_setstat: utimes");
 		strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
 		    localtime(&t));
 		logit("set \"%s\" modtime %s", name, buf);
@@ -737,11 +770,18 @@ process_setstat(void)
 			status = errno_to_portable(errno);
 	}
 	if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
-		logit("set \"%s\" owner %lu group %lu", name,
-		    (u_long)a->uid, (u_long)a->gid);
-		ret = chown(name, a->uid, a->gid);
-		if (ret == -1)
-			status = errno_to_portable(errno);
+		if (permit_chown == 1) {
+			ret = chown(name, a->uid, a->gid);
+			if (ret == -1)
+				status = errno_to_portable(errno);
+			else
+				if ( permit_logging == 1 )
+				logit("chown'ed %s.", name);
+		} else {
+			status = SSH2_FX_PERMISSION_DENIED;
+			if ( permit_logging == 1 )
+			logit("chown %s: operation prohibited by sftp-server configuration.", name);
+		}
 	}
 	send_status(id, status);
 	xfree(name);
@@ -755,8 +795,13 @@ process_fsetstat(void)
 	int handle, fd, ret;
 	int status = SSH2_FX_OK;
 
+if ( permit_logging == 1 )
+logit("process_fsetstat");
+
 	id = get_int();
 	handle = get_handle();
+if ( permit_logging == 1 )
+logit("process_fsetstat: ftruncate");
 	a = get_attrib();
 	debug("request %u: fsetstat handle %d", id, handle);
 	fd = handle_to_fd(handle);
@@ -766,6 +811,8 @@ process_fsetstat(void)
 		char *name = handle_to_name(handle);
 
 		if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
+			if ( permit_logging == 1 )
+			logit("process_setstat: truncate");
 			logit("set \"%s\" size %llu",
 			    name, (unsigned long long)a->size);
 			ret = ftruncate(fd, a->size);
@@ -773,7 +820,9 @@ process_fsetstat(void)
 				status = errno_to_portable(errno);
 		}
 		if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
+if ( permit_logging == 1 ) 
 			logit("set \"%s\" mode %04o", name, a->perm);
+			if (permit_chmod == 1) {
 #ifdef HAVE_FCHMOD
 			ret = fchmod(fd, a->perm & 0777);
 #else
@@ -781,11 +830,21 @@ process_fsetstat(void)
 #endif
 			if (ret == -1)
 				status = errno_to_portable(errno);
+			else
+				if ( permit_logging == 1 )
+				logit("chmod: succeeded.");
+		   } else { // permit_chmod
+                        status = SSH2_FX_PERMISSION_DENIED;
+			if ( permit_logging == 1 )
+			logit("chmod: operation prohibited by sftp-server configuration.");
+		   } // permit_chmod
 		}
 		if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
 			char buf[64];
 			time_t t = a->mtime;
 
+if ( permit_logging == 1 )
+logit("process_fsetstat: utimes");
 			strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
 			    localtime(&t));
 			logit("set \"%s\" modtime %s", name, buf);
@@ -800,6 +859,7 @@ process_fsetstat(void)
 		if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
 			logit("set \"%s\" owner %lu group %lu", name,
 			    (u_long)a->uid, (u_long)a->gid);
+			if (permit_chown == 1) {
 #ifdef HAVE_FCHOWN
 			ret = fchown(fd, a->uid, a->gid);
 #else
@@ -807,6 +867,14 @@ process_fsetstat(void)
 #endif
 			if (ret == -1)
 				status = errno_to_portable(errno);
+			else
+				if ( permit_logging == 1 )
+				logit("chown: succeeded");
+		   } else { // permit_chown
+			status = SSH2_FX_PERMISSION_DENIED;
+			if ( permit_logging == 1 )
+			logit("chown: operation prohibited by sftp-server configuration.");
+		   } // permit_chown
 		}
 	}
 	send_status(id, status);
@@ -929,6 +997,14 @@ process_mkdir(void)
 	a = get_attrib();
 	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
 	    a->perm & 0777 : 0777;
+
+        if (setumask != 0) {
+		if ( permit_logging == 1 )
+                logit("setting directory creation mode to 0777 and umask to %o.", setumask);
+                mode = 0777;
+                umask(setumask);
+        }
+
 	debug3("request %u: mkdir", id);
 	logit("mkdir name \"%s\" mode 0%o", name, mode);
 	ret = mkdir(name, mode);
@@ -977,6 +1053,8 @@ process_realpath(void)
 		s.name = s.long_name = resolvedname;
 		send_names(id, 1, &s);
 	}
+	if ( permit_logging == 1 )
+	logit("realpath %s", path);
 	xfree(path);
 }
 
@@ -1059,6 +1137,8 @@ process_readlink(void)
 		s.name = s.long_name = buf;
 		send_names(id, 1, &s);
 	}
+	if ( permit_logging == 1 )
+	logit("readlink %s", path);
 	xfree(path);
 }
 
@@ -1246,6 +1326,8 @@ sftp_server_main(int argc, char **argv, 
 {
 	fd_set *rset, *wset;
 	int in, out, max, ch, skipargs = 0, log_stderr = 0;
+	unsigned int val = 0;
+	char *umask_env;
 	ssize_t len, olen, set_size;
 	SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
 	char *cp, buf[4*4096];
@@ -1254,7 +1336,16 @@ sftp_server_main(int argc, char **argv, 
 	extern char *__progname;
 
 	__progname = ssh_get_progname(argv[0]);
-	log_init(__progname, log_level, log_facility, log_stderr);
+	/* sftplogging */
+
+	if ( (getenv("LOG_SFTP") != NULL) && (atoi(getenv("LOG_SFTP")) == 1) )
+	{
+		permit_logging = 1;
+		log_init("sftp-server", (getenv("SFTP_LOG_LEVEL") != NULL) ? atoi(getenv("SFTP_LOG_LEVEL")) : SYSLOG_LEVEL_DEBUG1,
+			(getenv("SFTP_LOG_FACILITY") != NULL) ? atoi(getenv("SFTP_LOG_FACILITY")) : SYSLOG_FACILITY_AUTH, 0);
+	};
+
+
 
 	while (!skipargs && (ch = getopt(argc, argv, "C:f:l:che")) != -1) {
 		switch (ch) {
@@ -1284,7 +1375,6 @@ sftp_server_main(int argc, char **argv, 
 		}
 	}
 
-	log_init(__progname, log_level, log_facility, log_stderr);
 
 	if ((cp = getenv("SSH_CONNECTION")) != NULL) {
 		client_addr = xstrdup(cp);
@@ -1302,6 +1392,41 @@ sftp_server_main(int argc, char **argv, 
 	logit("session opened for local user %s from [%s]",
 	    pw->pw_name, client_addr);
 
+	if ( permit_logging == 1 )
+	logit("Starting sftp-server logging for user %s.", getenv("USER"));
+
+	/* Umask control */
+
+	if ( (umask_env = getenv("SFTP_UMASK")) != NULL )
+	{
+		while (*umask_env && *umask_env >= '0' && *umask_env <= '9')
+			val = val * 8 + *umask_env++ - '0';
+
+		if (*umask_env || val > 0777 || val == 0) {
+			if ( permit_logging == 1 )
+			logit("bad value %o for SFTP_UMASK, turning umask control off.", val);
+			setumask = 0;
+		} else {
+			if ( permit_logging == 1 )
+			logit("umask control is on.");
+			setumask = val;
+		};
+	} else setumask = 0;
+
+
+	/* Sensitive client commands */
+	
+        if ( (getenv("SFTP_PERMIT_CHMOD") != NULL) && (atoi(getenv("SFTP_PERMIT_CHMOD")) != 1) ) {
+		permit_chmod = 0;
+		if ( permit_logging == 1 )
+                logit("client is not permitted to chmod.");
+	};
+        if ( (getenv("SFTP_PERMIT_CHOWN") != NULL) && (atoi(getenv("SFTP_PERMIT_CHOWN")) != 1) ) {
+		permit_chown = 0;
+		if ( permit_logging == 1 )
+                logit("client is not permitted to chown.");
+	};
+	
 	in = dup(STDIN_FILENO);
 	out = dup(STDOUT_FILENO);
 
@@ -1352,6 +1477,8 @@ sftp_server_main(int argc, char **argv, 
 			len = read(in, buf, sizeof buf);
 			if (len == 0) {
 				debug("read eof");
+				if ( permit_logging == 1 )
+				logit("sftp-server finished.");
 				sftp_server_cleanup_exit(0);
 			} else if (len < 0) {
 				error("read: %s", strerror(errno));
diff -Naurp openssh-4.9p1/sshd.c openssh-4.9p1.oden/sshd.c
--- openssh-4.9p1/sshd.c	2008-03-11 12:58:25.000000000 +0100
+++ openssh-4.9p1.oden/sshd.c	2008-04-01 13:18:51.000000000 +0200
@@ -421,7 +421,7 @@ sshd_exchange_identification(int sock_in
 		major = PROTOCOL_MAJOR_1;
 		minor = PROTOCOL_MINOR_1;
 	}
-	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
+	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_RELEASE);
 	server_version_string = xstrdup(buf);
 
 	/* Send our protocol version identification. */
diff -Naurp openssh-4.9p1/sshd_config openssh-4.9p1.oden/sshd_config
--- openssh-4.9p1/sshd_config	2008-02-10 12:40:12.000000000 +0100
+++ openssh-4.9p1.oden/sshd_config	2008-04-01 13:18:51.000000000 +0200
@@ -110,6 +110,17 @@ Protocol 2
 # override default of no subsystems
 Subsystem	sftp	/usr/libexec/sftp-server
 
+# sftp-server logging
+#LogSftp no
+#SftpLogFacility AUTH
+#SftpLogLevel INFO
+
+# sftp-server umask control
+#SftpUmask
+
+#SftpPermitChmod yes
+#SftpPermitChown yes
+
 # Example of overriding settings on a per-user basis
 #Match User anoncvs
 #	X11Forwarding no
diff -Naurp openssh-4.9p1/sshd_config.5 openssh-4.9p1.oden/sshd_config.5
--- openssh-4.9p1/sshd_config.5	2008-03-27 01:02:02.000000000 +0100
+++ openssh-4.9p1.oden/sshd_config.5	2008-04-01 13:18:51.000000000 +0200
@@ -530,6 +530,10 @@ The default is INFO.
 DEBUG and DEBUG1 are equivalent.
 DEBUG2 and DEBUG3 each specify higher levels of debugging output.
 Logging with a DEBUG level violates the privacy of users and is not recommended.
+.It Cm LogSftp
+Specifies whether to perform logging of
+.Nm sftp-server
+subsystem transactions. Must be "yes" or "no." The default value is "no."
 .It Cm MACs
 Specifies the available MAC (message authentication code) algorithms.
 The MAC algorithm is used in protocol version 2
@@ -773,6 +777,37 @@ This option applies to protocol version 
 .It Cm ServerKeyBits
 Defines the number of bits in the ephemeral protocol version 1 server key.
 The minimum value is 512, and the default is 768.
+.It Cm SftpLogFacility
+Gives the facility code that is used when logging
+.Nm sftp-server .
+transactions. The possible values are: DAEMON, USER, AUTH, LOCAL0,
+LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
+The default is AUTH.
+.It Cm SftpLogLevel
+Gives the verbosity level that is used when logging messages from
+.Nm sftp-server .
+The possible values are:
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+The default is INFO.  DEBUG and DEBUG1 are equivalent.  DEBUG2
+and DEBUG3 each specify higher levels of debugging output.
+Logging with a DEBUG level violates the privacy of users
+and is not recommended.
+.It Cm SftpPermitChmod
+Specifies whether the sftp-server allows the sftp client to execute chmod 
+commands on the server. The default is yes.
+.It Cm SftpPermitChown
+Specifies whether the sftp-server allows the sftp client to execute chown
+or chgrp commands on the server. Turning this value on means that the client
+is allowed to execute both chown and chgrp commands. Turning it off means that
+the client is prohibited from executing either chown or chgrp.
+ The default is yes.
+.It Cm SftpUmask
+Specifies an optional umask for 
+.Nm sftp-server
+subsystem transactions. If a umask is given, this umask will override all system, 
+environment or sftp client permission modes. If
+no umask or an invalid umask is given, file creation mode defaults to the permission
+mode specified by the sftp client. The default is for no umask.
 .It Cm StrictModes
 Specifies whether
 .Xr sshd 8
diff -Naurp openssh-4.9p1/version.h openssh-4.9p1.oden/version.h
--- openssh-4.9p1/version.h	2008-03-27 01:18:13.000000000 +0100
+++ openssh-4.9p1.oden/version.h	2008-04-01 13:18:51.000000000 +0200
@@ -2,5 +2,5 @@
 
 #define SSH_VERSION	"OpenSSH_4.9"
 
-#define SSH_PORTABLE	"p1"
+#define SSH_PORTABLE	"p1+sftplogging-v1.5"
 #define SSH_RELEASE	SSH_VERSION SSH_PORTABLE