Lines 79-85
Link Here
|
79 |
#include <netdb.h> |
79 |
#include <netdb.h> |
80 |
#include <pwd.h> |
80 |
#include <pwd.h> |
81 |
#include <grp.h> |
81 |
#include <grp.h> |
82 |
#include <opie.h> |
|
|
83 |
#include <signal.h> |
82 |
#include <signal.h> |
84 |
#include <stdint.h> |
83 |
#include <stdint.h> |
85 |
#include <stdio.h> |
84 |
#include <stdio.h> |
Lines 97-102
Link Here
|
97 |
#include <security/pam_appl.h> |
96 |
#include <security/pam_appl.h> |
98 |
#endif |
97 |
#endif |
99 |
|
98 |
|
|
|
99 |
#ifdef USE_OPIE |
100 |
#include <opie.h> |
101 |
#endif |
102 |
|
100 |
#include "pathnames.h" |
103 |
#include "pathnames.h" |
101 |
#include "extern.h" |
104 |
#include "extern.h" |
102 |
|
105 |
|
Lines 105-110
Link Here
|
105 |
static char version[] = "Version 6.00LS"; |
108 |
static char version[] = "Version 6.00LS"; |
106 |
#undef main |
109 |
#undef main |
107 |
|
110 |
|
|
|
111 |
extern off_t restart_point; |
112 |
extern char cbuf[]; |
113 |
|
108 |
union sockunion ctrl_addr; |
114 |
union sockunion ctrl_addr; |
109 |
union sockunion data_source; |
115 |
union sockunion data_source; |
110 |
union sockunion data_dest; |
116 |
union sockunion data_dest; |
Lines 181-188
Link Here
|
181 |
pam_handle_t *pamh = NULL; |
187 |
pam_handle_t *pamh = NULL; |
182 |
#endif |
188 |
#endif |
183 |
|
189 |
|
|
|
190 |
#ifdef USE_OPIE |
184 |
static struct opie opiedata; |
191 |
static struct opie opiedata; |
185 |
static char opieprompt[OPIE_CHALLENGE_MAX+1]; |
192 |
static char opieprompt[OPIE_CHALLENGE_MAX+1]; |
|
|
193 |
#endif |
194 |
|
186 |
static int pwok; |
195 |
static int pwok; |
187 |
|
196 |
|
188 |
char *pid_file = NULL; /* means default location to pidfile(3) */ |
197 |
char *pid_file = NULL; /* means default location to pidfile(3) */ |
Lines 245-251
Link Here
|
245 |
static void maskurg(int); |
254 |
static void maskurg(int); |
246 |
static void flagxfer(int); |
255 |
static void flagxfer(int); |
247 |
static int myoob(void); |
256 |
static int myoob(void); |
248 |
static int checkuser(char *, char *, int, char **); |
257 |
static int checkuser(char *, char *, int, char **, int *); |
249 |
static FILE *dataconn(char *, off_t, char *); |
258 |
static FILE *dataconn(char *, off_t, char *); |
250 |
static void dolog(struct sockaddr *); |
259 |
static void dolog(struct sockaddr *); |
251 |
static void end_login(void); |
260 |
static void end_login(void); |
Lines 998-1003
Link Here
|
998 |
void |
1007 |
void |
999 |
user(char *name) |
1008 |
user(char *name) |
1000 |
{ |
1009 |
{ |
|
|
1010 |
int ecode; |
1001 |
char *cp, *shell; |
1011 |
char *cp, *shell; |
1002 |
|
1012 |
|
1003 |
if (logged_in) { |
1013 |
if (logged_in) { |
Lines 1018-1026
Link Here
|
1018 |
pw = sgetpwnam("ftp"); |
1028 |
pw = sgetpwnam("ftp"); |
1019 |
#endif |
1029 |
#endif |
1020 |
if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { |
1030 |
if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { |
1021 |
if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL) || |
1031 |
if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL, &ecode) || |
1022 |
checkuser(_PATH_FTPUSERS, "anonymous", 0, NULL)) |
1032 |
(ecode != 0 && ecode != ENOENT)) |
1023 |
reply(530, "User %s access denied.", name); |
1033 |
reply(530, "User %s access denied.", name); |
|
|
1034 |
else if (checkuser(_PATH_FTPUSERS, "anonymous", 0, NULL, &ecode) || |
1035 |
(ecode != 0 && ecode != ENOENT)) |
1036 |
reply(530, "User %s access denied.", name); |
1024 |
else if (pw != NULL) { |
1037 |
else if (pw != NULL) { |
1025 |
guest = 1; |
1038 |
guest = 1; |
1026 |
askpasswd = 1; |
1039 |
askpasswd = 1; |
Lines 1047-1053
Link Here
|
1047 |
break; |
1060 |
break; |
1048 |
endusershell(); |
1061 |
endusershell(); |
1049 |
|
1062 |
|
1050 |
if (cp == NULL || checkuser(_PATH_FTPUSERS, name, 1, NULL)) { |
1063 |
if (cp == NULL || |
|
|
1064 |
(checkuser(_PATH_FTPUSERS, name, 1, NULL, &ecode) || |
1065 |
(ecode != 0 && ecode != ENOENT))) { |
1051 |
reply(530, "User %s access denied.", name); |
1066 |
reply(530, "User %s access denied.", name); |
1052 |
if (logging) |
1067 |
if (logging) |
1053 |
syslog(LOG_NOTICE, |
1068 |
syslog(LOG_NOTICE, |
Lines 1064-1076
Link Here
|
1064 |
#ifdef USE_PAM |
1079 |
#ifdef USE_PAM |
1065 |
/* XXX Kluge! The conversation mechanism needs to be fixed. */ |
1080 |
/* XXX Kluge! The conversation mechanism needs to be fixed. */ |
1066 |
#endif |
1081 |
#endif |
|
|
1082 |
|
1083 |
#ifdef USE_OPIE |
1067 |
if (opiechallenge(&opiedata, name, opieprompt) == 0) { |
1084 |
if (opiechallenge(&opiedata, name, opieprompt) == 0) { |
1068 |
pwok = (pw != NULL) && |
1085 |
pwok = (pw != NULL) && |
1069 |
opieaccessfile(remotehost) && |
1086 |
opieaccessfile(remotehost) && |
1070 |
opiealways(pw->pw_dir); |
1087 |
opiealways(pw->pw_dir); |
1071 |
reply(331, "Response to %s %s for %s.", |
1088 |
reply(331, "Response to %s %s for %s.", |
1072 |
opieprompt, pwok ? "requested" : "required", name); |
1089 |
opieprompt, pwok ? "requested" : "required", name); |
1073 |
} else { |
1090 |
} |
|
|
1091 |
else |
1092 |
#endif |
1093 |
{ |
1074 |
pwok = 1; |
1094 |
pwok = 1; |
1075 |
reply(331, "Password required for %s.", name); |
1095 |
reply(331, "Password required for %s.", name); |
1076 |
} |
1096 |
} |
Lines 1089-1101
Link Here
|
1089 |
* of the matching line in "residue" if not NULL. |
1109 |
* of the matching line in "residue" if not NULL. |
1090 |
*/ |
1110 |
*/ |
1091 |
static int |
1111 |
static int |
1092 |
checkuser(char *fname, char *name, int pwset, char **residue) |
1112 |
checkuser(char *fname, char *name, int pwset, char **residue, int *ecode) |
1093 |
{ |
1113 |
{ |
1094 |
FILE *fd; |
1114 |
FILE *fd; |
1095 |
int found = 0; |
1115 |
int found = 0; |
1096 |
size_t len; |
1116 |
size_t len; |
1097 |
char *line, *mp, *p; |
1117 |
char *line, *mp, *p; |
1098 |
|
1118 |
|
|
|
1119 |
if (ecode != NULL) |
1120 |
*ecode = 0; |
1099 |
if ((fd = fopen(fname, "r")) != NULL) { |
1121 |
if ((fd = fopen(fname, "r")) != NULL) { |
1100 |
while (!found && (line = fgetln(fd, &len)) != NULL) { |
1122 |
while (!found && (line = fgetln(fd, &len)) != NULL) { |
1101 |
/* skip comments */ |
1123 |
/* skip comments */ |
Lines 1164-1170
Link Here
|
1164 |
free(mp); |
1186 |
free(mp); |
1165 |
} |
1187 |
} |
1166 |
(void) fclose(fd); |
1188 |
(void) fclose(fd); |
1167 |
} |
1189 |
} else if (ecode != NULL) |
|
|
1190 |
*ecode = errno; |
1168 |
return (found); |
1191 |
return (found); |
1169 |
} |
1192 |
} |
1170 |
|
1193 |
|
Lines 1361-1367
Link Here
|
1361 |
void |
1384 |
void |
1362 |
pass(char *passwd) |
1385 |
pass(char *passwd) |
1363 |
{ |
1386 |
{ |
1364 |
int rval; |
1387 |
int rval, ecode; |
1365 |
FILE *fd; |
1388 |
FILE *fd; |
1366 |
#ifdef LOGIN_CAP |
1389 |
#ifdef LOGIN_CAP |
1367 |
login_cap_t *lc = NULL; |
1390 |
login_cap_t *lc = NULL; |
Lines 1385-1397
Link Here
|
1385 |
#ifdef USE_PAM |
1408 |
#ifdef USE_PAM |
1386 |
rval = auth_pam(&pw, passwd); |
1409 |
rval = auth_pam(&pw, passwd); |
1387 |
if (rval >= 0) { |
1410 |
if (rval >= 0) { |
|
|
1411 |
#ifdef USE_OPIE |
1388 |
opieunlock(); |
1412 |
opieunlock(); |
|
|
1413 |
#endif |
1389 |
goto skip; |
1414 |
goto skip; |
1390 |
} |
1415 |
} |
1391 |
#endif |
1416 |
#endif |
|
|
1417 |
#ifdef USE_OPIE |
1392 |
if (opieverify(&opiedata, passwd) == 0) |
1418 |
if (opieverify(&opiedata, passwd) == 0) |
1393 |
xpasswd = pw->pw_passwd; |
1419 |
xpasswd = pw->pw_passwd; |
1394 |
else if (pwok) { |
1420 |
else |
|
|
1421 |
#endif |
1422 |
if (pwok) { |
1395 |
xpasswd = crypt(passwd, pw->pw_passwd); |
1423 |
xpasswd = crypt(passwd, pw->pw_passwd); |
1396 |
if (passwd[0] == '\0' && pw->pw_passwd[0] != '\0') |
1424 |
if (passwd[0] == '\0' && pw->pw_passwd[0] != '\0') |
1397 |
xpasswd = ":"; |
1425 |
xpasswd = ":"; |
Lines 1492-1502
Link Here
|
1492 |
stats = 0; |
1520 |
stats = 0; |
1493 |
|
1521 |
|
1494 |
dochroot = |
1522 |
dochroot = |
1495 |
checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue) |
1523 |
checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue, &ecode) |
1496 |
#ifdef LOGIN_CAP /* Allow login.conf configuration as well */ |
1524 |
#ifdef LOGIN_CAP /* Allow login.conf configuration as well */ |
1497 |
|| login_getcapbool(lc, "ftp-chroot", 0) |
1525 |
|| login_getcapbool(lc, "ftp-chroot", 0) |
1498 |
#endif |
1526 |
#endif |
1499 |
; |
1527 |
; |
|
|
1528 |
/* |
1529 |
* It is possible that checkuser() failed to open the chroot file. |
1530 |
* If this is the case, report that logins are un-available, since we |
1531 |
* have no way of checking whether or not the user should be chrooted. |
1532 |
* We ignore ENOENT since it is not required that this file be present. |
1533 |
*/ |
1534 |
if (ecode != 0 && ecode != ENOENT) { |
1535 |
reply(530, "Login not available right now."); |
1536 |
return; |
1537 |
} |
1500 |
chrootdir = NULL; |
1538 |
chrootdir = NULL; |
1501 |
/* |
1539 |
/* |
1502 |
* For a chrooted local user, |
1540 |
* For a chrooted local user, |
Lines 1543-1549
Link Here
|
1543 |
reply(550, "Can't change root."); |
1581 |
reply(550, "Can't change root."); |
1544 |
goto bad; |
1582 |
goto bad; |
1545 |
} |
1583 |
} |
1546 |
__FreeBSD_libc_enter_restricted_mode(); |
|
|
1547 |
} else /* real user w/o chroot */ |
1584 |
} else /* real user w/o chroot */ |
1548 |
homedir = pw->pw_dir; |
1585 |
homedir = pw->pw_dir; |
1549 |
/* |
1586 |
/* |
Lines 1874-1885
Link Here
|
1874 |
#ifdef TCP_NOPUSH |
1911 |
#ifdef TCP_NOPUSH |
1875 |
/* |
1912 |
/* |
1876 |
* Turn off push flag to keep sender TCP from sending short packets |
1913 |
* Turn off push flag to keep sender TCP from sending short packets |
1877 |
* at the boundaries of each write(). |
1914 |
* at the boundaries of each write(). Should probably do a SO_SNDBUF |
|
|
1915 |
* to set the send buffer size as well, but that may not be desirable |
1916 |
* in heavy-load situations. |
1878 |
*/ |
1917 |
*/ |
1879 |
on = 1; |
1918 |
on = 1; |
1880 |
if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof on) < 0) |
1919 |
if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof on) < 0) |
1881 |
syslog(LOG_WARNING, "data setsockopt (TCP_NOPUSH): %m"); |
1920 |
syslog(LOG_WARNING, "data setsockopt (TCP_NOPUSH): %m"); |
1882 |
#endif |
1921 |
#endif |
|
|
1922 |
#ifdef SO_SNDBUF |
1923 |
on = 65536; |
1924 |
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &on, sizeof on) < 0) |
1925 |
syslog(LOG_WARNING, "data setsockopt (SO_SNDBUF): %m"); |
1926 |
#endif |
1927 |
|
1883 |
return (fdopen(s, mode)); |
1928 |
return (fdopen(s, mode)); |
1884 |
bad: |
1929 |
bad: |
1885 |
/* Return the real value of errno (close may change it) */ |
1930 |
/* Return the real value of errno (close may change it) */ |
Lines 2331-2336
Link Here
|
2331 |
code = lstat(filename, &st) == 0 && S_ISDIR(st.st_mode) ? 212 : 213; |
2376 |
code = lstat(filename, &st) == 0 && S_ISDIR(st.st_mode) ? 212 : 213; |
2332 |
(void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename); |
2377 |
(void)snprintf(line, sizeof(line), _PATH_LS " -lgA %s", filename); |
2333 |
fin = ftpd_popen(line, "r"); |
2378 |
fin = ftpd_popen(line, "r"); |
|
|
2379 |
if (fin == NULL) { |
2380 |
perror_reply(551, filename); |
2381 |
return; |
2382 |
} |
2334 |
lreply(code, "Status of %s:", filename); |
2383 |
lreply(code, "Status of %s:", filename); |
2335 |
atstart = 1; |
2384 |
atstart = 1; |
2336 |
while ((c = getc(fin)) != EOF) { |
2385 |
while ((c = getc(fin)) != EOF) { |
Lines 3467-3469
Link Here
|
3467 |
} |
3516 |
} |
3468 |
return(socks); |
3517 |
return(socks); |
3469 |
} |
3518 |
} |
|
|
3519 |
|