1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
Add -C user@host support instead of just -C user and add support for
IPv6 in ftpusers.
FreeBSD does not have _PASSWORD_CHGNOW defined, so use direct constant
instead.
We are sure, that we have good LOGIN_NAME_MAX from tnftpd.h, so use it
instead of unnecessarily conservative _POSIX_LOGIN_NAME_MAX.
--- src/ftpd.c.orig 2008-06-08 20:52:33.000000000 -0400
+++ src/ftpd.c 2008-06-08 20:52:33.000000000 -0400
@@ -368,6 +368,24 @@
break;
case 'C':
+ if ((p = strchr(optarg, '@')) != NULL) {
+ *p++ = '\0';
+ strlcpy(remotehost, p, MAXHOSTNAMELEN + 1);
+ if (inet_pton(AF_INET, p,
+ &his_addr.su_addr) == 1) {
+ his_addr.su_family = AF_INET;
+ his_addr.su_len =
+ sizeof(his_addr.si_su.su_sin);
+#ifdef INET6
+ } else if (inet_pton(AF_INET6, p,
+ &his_addr.su_6addr) == 1) {
+ his_addr.su_family = AF_INET6;
+ his_addr.su_len =
+ sizeof(his_addr.si_su.su_sin6);
+#endif
+ } else
+ his_addr.su_family = AF_UNSPEC;
+ }
pw = sgetpwnam(optarg);
exit(checkaccess(optarg) ? 0 : 1);
/* NOTREACHED */
@@ -497,12 +515,12 @@
exit(1);
} else if (l <= 0) {
syslog(LOG_WARNING, "using conservative LOGIN_NAME_MAX value");
- curname_len = _POSIX_LOGIN_NAME_MAX;
+ curname_len = LOGIN_NAME_MAX;
} else
curname_len = (size_t)l;
#else
/* using conservative LOGIN_NAME_MAX value */
- curname_len = _POSIX_LOGIN_NAME_MAX;
+ curname_len = LOGIN_NAME_MAX;
#endif
curname = malloc(curname_len);
if (curname == NULL) {
@@ -1179,18 +1197,38 @@
/* have a host specifier */
if ((p = strchr(word, '@')) != NULL) {
- unsigned long net, mask, addr;
- int bits;
+ char net[16], mask[16], *addr;
+ int addrlen, bits, bytes, a;
*p++ = '\0';
/* check against network or CIDR */
- if (isdigit((unsigned char)*p) &&
- (bits = inet_net_pton(AF_INET, p,
- &net, sizeof(net))) != -1) {
- net = ntohl(net);
- mask = 0xffffffffU << (32 - bits);
- addr = ntohl(his_addr.su_addr.s_addr);
- if ((addr & mask) != net)
+ memset(net, 0x00, sizeof(net));
+ if ((bits = inet_net_pton(his_addr.su_family, p, net,
+ sizeof(net))) != -1) {
+#ifdef INET6
+ if (his_addr.su_family == AF_INET) {
+#endif
+ addrlen = 4;
+ addr = (char *)&his_addr.su_addr;
+#ifdef INET6
+ } else {
+ addrlen = 16;
+ addr = (char *)&his_addr.su_6addr;
+ }
+#endif
+ bytes = bits / 8;
+ bits = bits % 8;
+ if (bytes > 0)
+ memset(mask, 0xFF, bytes);
+ if (bytes < addrlen)
+ mask[bytes] = 0xFF << (8 - bits);
+ if (bytes + 1 < addrlen)
+ memset(mask + bytes + 1, 0x00,
+ addrlen - bytes - 1);
+ for (a = 0; a < addrlen; a++)
+ if ((addr[a] & mask[a]) != net[a])
+ break;
+ if (a < addrlen)
continue;
/* check against hostname glob */
@@ -3776,7 +3814,7 @@
expire = pwent->pw_expire;
#endif
#if defined(HAVE_STRUCT_PASSWD_PW_CHANGE)
- change = (pwent->pw_change == _PASSWORD_CHGNOW)? now : pwent->pw_change;
+ change = (pwent->pw_change == -1)? now : pwent->pw_change;
#endif
#endif
|