312 lines
7.6 KiB
Diff
312 lines
7.6 KiB
Diff
diff -Naur inetutils-1.9.2-orig/ftpd/auth.c inetutils-1.9.2/ftpd/auth.c
|
|
--- inetutils-1.9.2-orig/ftpd/auth.c 2013-09-26 12:36:38.000000000 +0300
|
|
+++ inetutils-1.9.2/ftpd/auth.c 2014-12-12 11:55:12.478800000 +0300
|
|
@@ -19,6 +19,17 @@
|
|
|
|
#include <config.h>
|
|
|
|
+#ifdef __CYGWIN__
|
|
+# undef ERROR
|
|
+# include <windows.h>
|
|
+# include <pwd.h>
|
|
+# include <sys/cygwin.h>
|
|
+# include <io.h>
|
|
+# define is_winnt (GetVersion() < 0x80000000)
|
|
+#else
|
|
+# define is_winnt (0)
|
|
+#endif
|
|
+
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
@@ -44,6 +55,9 @@
|
|
shell as returned by getusershell(). Disallow anyone mentioned in the file
|
|
PATH_FTPUSERS to allow people such as root and uucp to be avoided. */
|
|
|
|
+static int
|
|
+do_cygwin_auth (const char* passwd, struct credentials *pcred);
|
|
+
|
|
int
|
|
auth_user (const char *name, struct credentials *pcred)
|
|
{
|
|
@@ -84,6 +98,12 @@
|
|
if (pcred->message == NULL)
|
|
return -1;
|
|
|
|
+#ifdef __CYGWIN__
|
|
+ /* when running under WinNT, password is always required. */
|
|
+ if (!is_winnt)
|
|
+ {
|
|
+#endif /* __CYGWIN__ */
|
|
+
|
|
/* Check for anonymous log in.
|
|
*
|
|
* This code simulates part of `pam_ftp.so'
|
|
@@ -113,6 +133,9 @@
|
|
}
|
|
return err;
|
|
}
|
|
+#ifdef __CYGWIN__
|
|
+ }
|
|
+#endif /* __CYGWIN__ */
|
|
|
|
if (sgetcred (name, pcred) == 0)
|
|
{
|
|
@@ -184,18 +207,49 @@
|
|
case AUTH_TYPE_PASSWD:
|
|
default:
|
|
{
|
|
+#ifdef __CYGWIN__
|
|
+ if (!is_winnt)
|
|
+ {
|
|
+#endif /* __CYGWIN__ */
|
|
char *xpasswd;
|
|
char *salt = pcred->passwd;
|
|
/* Try to authenticate the user. */
|
|
if (pcred->passwd == NULL || *pcred->passwd == '\0')
|
|
return 1; /* Failed. */
|
|
- xpasswd = crypt (passwd, salt);
|
|
+ xpasswd = (char*) crypt (passwd, salt);
|
|
return (!xpasswd || strcmp (xpasswd, pcred->passwd) != 0);
|
|
+#ifdef __CYGWIN__
|
|
+ } else {
|
|
+ return do_cygwin_auth (passwd, pcred);
|
|
+ }
|
|
+#endif /* __CYGWIN__ */
|
|
}
|
|
} /* switch (auth_type) */
|
|
return -1;
|
|
}
|
|
|
|
+#ifdef __CYGWIN__
|
|
+static int
|
|
+do_cygwin_auth (const char* passwd, struct credentials *pcred)
|
|
+{
|
|
+ struct passwd *p;
|
|
+ if ((pcred == NULL) || (pcred->name == NULL) || (pcred->name[0] == '\0'))
|
|
+ return 1;
|
|
+
|
|
+ /* can't "recreate" p from contents of pcred, because
|
|
+ struct passwd might contain extension elements
|
|
+ unknown to us
|
|
+ */
|
|
+ p = getpwnam (pcred->name);
|
|
+ if (p == NULL)
|
|
+ return 1;
|
|
+
|
|
+ HANDLE hToken = (HANDLE) cygwin_logon_user (p, passwd);
|
|
+ cygwin_set_impersonation_token (hToken);
|
|
+ return (hToken == INVALID_HANDLE_VALUE); // non-zero on error
|
|
+}
|
|
+#endif /* __CYGWIN__ */
|
|
+
|
|
int
|
|
sgetcred (const char *name, struct credentials *pcred)
|
|
{
|
|
diff -Naur inetutils-1.9.2-orig/ftpd/ftpcmd.y inetutils-1.9.2/ftpd/ftpcmd.y
|
|
--- inetutils-1.9.2-orig/ftpd/ftpcmd.y 2013-12-23 14:57:54.000000000 +0300
|
|
+++ inetutils-1.9.2/ftpd/ftpcmd.y 2014-12-12 11:55:12.478800000 +0300
|
|
@@ -592,7 +592,7 @@
|
|
# endif /* BSD */
|
|
#endif /* !HAVE_UNAME */
|
|
|
|
-#if defined unix || defined __unix || defined __unix__
|
|
+#if defined unix || defined __unix || defined __unix__ || defined __CYGWIN__
|
|
sys_type = "UNIX";
|
|
#else
|
|
sys_type = "UNKNOWN";
|
|
diff -Naur inetutils-1.9.2-orig/ftpd/ftpd.c inetutils-1.9.2/ftpd/ftpd.c
|
|
--- inetutils-1.9.2-orig/ftpd/ftpd.c 2013-12-23 14:57:54.000000000 +0300
|
|
+++ inetutils-1.9.2/ftpd/ftpd.c 2014-12-12 11:55:12.478800000 +0300
|
|
@@ -113,6 +113,10 @@
|
|
# define LOG_FTP LOG_DAEMON /* Use generic facility. */
|
|
#endif
|
|
|
|
+#ifndef LARGE_TRANSFER_BLOCKSIZE
|
|
+# define LARGE_TRANSFER_BLOCKSIZE 4096
|
|
+#endif
|
|
+
|
|
#ifndef MAP_FAILED
|
|
# define MAP_FAILED (void*)-1
|
|
#endif
|
|
@@ -445,11 +449,21 @@
|
|
NULL
|
|
};
|
|
|
|
+#if defined(WITH_WRAP) && defined(__CYGWIN__)
|
|
+extern int allow_severity; /* set value in main() */
|
|
+extern int deny_severity; /* set value in main() */
|
|
+#endif
|
|
+
|
|
int
|
|
main (int argc, char *argv[], char **envp)
|
|
{
|
|
int index;
|
|
|
|
+#if defined(WITH_WRAP) && defined(__CYGWIN__)
|
|
+ allow_severity = LOG_INFO;
|
|
+ deny_severity = LOG_NOTICE;
|
|
+#endif
|
|
+
|
|
set_program_name (argv[0]);
|
|
|
|
#ifdef HAVE_TZSET
|
|
@@ -560,7 +574,7 @@
|
|
}
|
|
#endif
|
|
|
|
-#ifdef F_SETOWN
|
|
+#if defined(F_SETOWN) && !defined(__CYGWIN__)
|
|
if (fcntl (STDIN_FILENO, F_SETOWN, getpid ()) == -1)
|
|
syslog (LOG_ERR, "fcntl F_SETOWN: %m");
|
|
#endif
|
|
@@ -684,19 +698,29 @@
|
|
/* We MUST do a chdir () after the chroot. Otherwise
|
|
the old current directory will be accessible as "."
|
|
outside the new root! */
|
|
- if (chroot (pcred->rootdir) < 0 || chdir (pcred->homedir) < 0)
|
|
+ if (chroot (pcred->rootdir) < 0)
|
|
{
|
|
reply (550, "Can't set guest privileges.");
|
|
goto bad;
|
|
}
|
|
+ if (chdir (pcred->homedir) < 0)
|
|
+ {
|
|
+ reply(550, "Can't access home directory.");
|
|
+ goto bad;
|
|
+ }
|
|
}
|
|
else if (pcred->dochroot)
|
|
{
|
|
- if (chroot (pcred->rootdir) < 0 || chdir (pcred->homedir) < 0)
|
|
+ if (chroot (pcred->rootdir) < 0)
|
|
{
|
|
reply (550, "Can't change root.");
|
|
goto bad;
|
|
}
|
|
+ if (chdir (pcred->homedir) < 0)
|
|
+ {
|
|
+ reply(550, "Can't access home directory.");
|
|
+ goto bad;
|
|
+ }
|
|
}
|
|
|
|
if (seteuid ((uid_t) pcred->uid) < 0)
|
|
@@ -862,7 +886,7 @@
|
|
char *remotehost = pcred->remotehost;
|
|
int atype = pcred->auth_type;
|
|
|
|
- seteuid ((uid_t) 0);
|
|
+ seteuid (getuid ());
|
|
if (pcred->logged_in)
|
|
{
|
|
logwtmp_keep_open (ttyline, "", "");
|
|
@@ -972,7 +996,13 @@
|
|
|
|
if (cmd == 0)
|
|
{
|
|
+#ifdef __CYGWIN__
|
|
+ if (type != TYPE_A)
|
|
+ fin = fopen (name, "rb"), closefunc = fclose;
|
|
+ else
|
|
+#else
|
|
fin = fopen (name, "r"), closefunc = fclose;
|
|
+#endif /* __CYGWIN__ */
|
|
st.st_size = 0;
|
|
}
|
|
else
|
|
@@ -1059,6 +1089,13 @@
|
|
FILE *fout, *din;
|
|
struct stat st;
|
|
int (*closefunc) (FILE *);
|
|
+ char nmode[8];
|
|
+
|
|
+ strcpy (nmode, mode);
|
|
+#ifdef __CYGWIN__
|
|
+ if (type != TYPE_A)
|
|
+ strcat (nmode, "b");
|
|
+#endif
|
|
|
|
if (unique && stat (name, &st) == 0)
|
|
{
|
|
@@ -1074,8 +1111,16 @@
|
|
}
|
|
|
|
if (restart_point)
|
|
- mode = "r+";
|
|
- fout = fopen (name, mode);
|
|
+ {
|
|
+#ifdef __CYGWIN__
|
|
+ if (type != TYPE_A)
|
|
+ mode = "rb+";
|
|
+ else
|
|
+#endif
|
|
+ mode = "r+";
|
|
+ strcpy (nmode, mode);
|
|
+ }
|
|
+ fout = fopen (name, nmode);
|
|
closefunc = fclose;
|
|
if (fout == NULL || fstat (fileno (fout), &st) < 0)
|
|
{
|
|
@@ -1151,7 +1196,7 @@
|
|
|
|
if (data >= 0)
|
|
return fdopen (data, mode);
|
|
- seteuid ((uid_t) 0);
|
|
+ seteuid (getuid ());
|
|
s = socket (ctrl_addr.ss_family, SOCK_STREAM, 0);
|
|
if (s < 0)
|
|
goto bad;
|
|
@@ -1414,7 +1459,14 @@
|
|
len = filesize;
|
|
do
|
|
{
|
|
+#ifdef __CYGWIN__
|
|
+ cnt = write (netfd, bp,
|
|
+ (len < LARGE_TRANSFER_BLOCKSIZE ?
|
|
+ len : LARGE_TRANSFER_BLOCKSIZE));
|
|
+#else
|
|
cnt = write (netfd, bp, len);
|
|
+#endif /* __CYGWIN__ */
|
|
+
|
|
len -= cnt;
|
|
bp += cnt;
|
|
if (cnt > 0)
|
|
@@ -1439,6 +1491,9 @@
|
|
syslog (LOG_DEBUG, "Starting at position %jd.", curpos);
|
|
}
|
|
|
|
+ if (blksize <= 0)
|
|
+ blksize = LARGE_TRANSFER_BLOCKSIZE;
|
|
+
|
|
buf = malloc ((u_int) blksize);
|
|
if (buf == NULL)
|
|
{
|
|
@@ -1978,7 +2033,7 @@
|
|
else /* !AF_INET6 */
|
|
((struct sockaddr_in *) &pasv_addr)->sin_port = 0;
|
|
|
|
- seteuid ((uid_t) 0);
|
|
+ seteuid (getuid ());
|
|
if (bind (pdata, (struct sockaddr *) &pasv_addr, pasv_addrlen) < 0)
|
|
{
|
|
if (seteuid ((uid_t) cred.uid))
|
|
diff -Naur inetutils-1.9.2-orig/ftpd/server_mode.c inetutils-1.9.2/ftpd/server_mode.c
|
|
--- inetutils-1.9.2-orig/ftpd/server_mode.c 2013-09-26 12:36:38.000000000 +0300
|
|
+++ inetutils-1.9.2/ftpd/server_mode.c 2014-12-12 11:55:12.478800000 +0300
|
|
@@ -58,8 +58,14 @@
|
|
extern int hosts_ctl (char *, char *, char *, char *);
|
|
# endif
|
|
|
|
+#ifdef __CYGWIN__
|
|
+/* provided by library (e.g. extern, here) on cygwin */
|
|
+extern int allow_severity; /* set value in main() */
|
|
+extern int deny_severity; /* set value in main() */
|
|
+#else
|
|
int allow_severity = LOG_INFO;
|
|
int deny_severity = LOG_NOTICE;
|
|
+#endif
|
|
|
|
static int
|
|
check_host (struct sockaddr *sa, socklen_t len)
|