diff options
author | Darren Tucker <dtucker@zip.com.au> | 2005-02-15 21:45:57 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2005-02-15 21:45:57 +1100 |
commit | 691d5235ca9485877e8345269b1be4b2cf1be322 (patch) | |
tree | 7adbbdbb837a6d3d4953a6ea339ad9d9e6d289ce | |
parent | f04c3616756831fe987fe3e474c8c234c298e4cb (diff) |
- (dtucker) [README.platform auth.c configure.ac loginrec.c
openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6
on AIX where possible (see README.platform for details) and work around
a misfeature of AIX's getnameinfo. ok djm@
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | README.platform | 11 | ||||
-rw-r--r-- | auth.c | 2 | ||||
-rw-r--r-- | configure.ac | 62 | ||||
-rw-r--r-- | loginrec.c | 6 | ||||
-rw-r--r-- | openbsd-compat/port-aix.c | 45 | ||||
-rw-r--r-- | openbsd-compat/port-aix.h | 22 |
7 files changed, 136 insertions, 18 deletions
@@ -1,5 +1,9 @@ | |||
1 | 20050215 | 1 | 20050215 |
2 | - (dtucker) [config.sh.in] Collect oslevel -r too. | 2 | - (dtucker) [config.sh.in] Collect oslevel -r too. |
3 | - (dtucker) [README.platform auth.c configure.ac loginrec.c | ||
4 | openbsd-compat/port-aix.c openbsd-compat/port-aix.h] Bug #835: enable IPv6 | ||
5 | on AIX where possible (see README.platform for details) and work around | ||
6 | a misfeature of AIX's getnameinfo. ok djm@ | ||
3 | 7 | ||
4 | 20050211 | 8 | 20050211 |
5 | - (dtucker) [configure.ac] Tidy up configure --help output. | 9 | - (dtucker) [configure.ac] Tidy up configure --help output. |
@@ -2126,4 +2130,4 @@ | |||
2126 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2130 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2127 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2131 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2128 | 2132 | ||
2129 | $Id: ChangeLog,v 1.3651 2005/02/15 10:26:32 dtucker Exp $ | 2133 | $Id: ChangeLog,v 1.3652 2005/02/15 10:45:57 dtucker Exp $ |
diff --git a/README.platform b/README.platform index 880b83c63..136304a8e 100644 --- a/README.platform +++ b/README.platform | |||
@@ -13,6 +13,15 @@ Accounts in this state must have their passwords reset manually by the | |||
13 | administrator. As a precaution, it is recommended that the administrative | 13 | administrator. As a precaution, it is recommended that the administrative |
14 | passwords be reset before upgrading from OpenSSH <3.8. | 14 | passwords be reset before upgrading from OpenSSH <3.8. |
15 | 15 | ||
16 | As of OpenSSH 4.0, configure will attempt to detect if your version | ||
17 | and maintenance level of AIX has a working getaddrinfo, and will use it | ||
18 | if found. This will enable IPv6 support. If for some reason configure | ||
19 | gets it wrong, or if you want to build binaries to work on earlier MLs | ||
20 | than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS | ||
21 | to force the previous IPv4-only behaviour. | ||
22 | |||
23 | IPv6 known to work: 5.2ML2 5.2ML5 | ||
24 | IPv6 known broken: 4.3.3ML11 5.1ML4 | ||
16 | 25 | ||
17 | Cygwin | 26 | Cygwin |
18 | ------ | 27 | ------ |
@@ -27,4 +36,4 @@ Currently, sshd does not support BSM auditting. This can show up as errors | |||
27 | when editting cron entries via crontab. See. | 36 | when editting cron entries via crontab. See. |
28 | http://bugzilla.mindrot.org/show_bug.cgi?id=125 | 37 | http://bugzilla.mindrot.org/show_bug.cgi?id=125 |
29 | 38 | ||
30 | $Id: README.platform,v 1.2 2004/04/23 08:57:13 dtucker Exp $ | 39 | $Id: README.platform,v 1.3 2005/02/15 10:45:57 dtucker Exp $ |
@@ -209,7 +209,7 @@ allowed_user(struct passwd * pw) | |||
209 | } | 209 | } |
210 | 210 | ||
211 | #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER | 211 | #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER |
212 | if (!sys_auth_allowed_user(pw)) | 212 | if (!sys_auth_allowed_user(pw, &loginmsg)) |
213 | return 0; | 213 | return 0; |
214 | #endif | 214 | #endif |
215 | 215 | ||
diff --git a/configure.ac b/configure.ac index 2df8a5e87..b27f0cf70 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: configure.ac,v 1.241 2005/02/11 05:11:49 dtucker Exp $ | 1 | # $Id: configure.ac,v 1.242 2005/02/15 10:45:57 dtucker Exp $ |
2 | # | 2 | # |
3 | # Copyright (c) 1999-2004 Damien Miller | 3 | # Copyright (c) 1999-2004 Damien Miller |
4 | # | 4 | # |
@@ -135,7 +135,7 @@ case "$host" in | |||
135 | [#include <usersec.h>] | 135 | [#include <usersec.h>] |
136 | ) | 136 | ) |
137 | AC_CHECK_FUNCS(setauthdb) | 137 | AC_CHECK_FUNCS(setauthdb) |
138 | AC_DEFINE(BROKEN_GETADDRINFO) | 138 | check_for_aix_broken_getaddrinfo=1 |
139 | AC_DEFINE(BROKEN_REALPATH) | 139 | AC_DEFINE(BROKEN_REALPATH) |
140 | AC_DEFINE(SETEUID_BREAKS_SETUID) | 140 | AC_DEFINE(SETEUID_BREAKS_SETUID) |
141 | AC_DEFINE(BROKEN_SETREUID) | 141 | AC_DEFINE(BROKEN_SETREUID) |
@@ -1146,6 +1146,64 @@ main(void) | |||
1146 | ) | 1146 | ) |
1147 | fi | 1147 | fi |
1148 | 1148 | ||
1149 | if test "x$ac_cv_func_getaddrinfo" = "xyes" -a "x$check_for_aix_broken_getaddrinfo" = "x1"; then | ||
1150 | AC_MSG_CHECKING(if getaddrinfo seems to work) | ||
1151 | AC_TRY_RUN( | ||
1152 | [ | ||
1153 | #include <stdio.h> | ||
1154 | #include <sys/socket.h> | ||
1155 | #include <netdb.h> | ||
1156 | #include <errno.h> | ||
1157 | #include <netinet/in.h> | ||
1158 | |||
1159 | #define TEST_PORT "2222" | ||
1160 | |||
1161 | int | ||
1162 | main(void) | ||
1163 | { | ||
1164 | int err, sock; | ||
1165 | struct addrinfo *gai_ai, *ai, hints; | ||
1166 | char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL; | ||
1167 | |||
1168 | memset(&hints, 0, sizeof(hints)); | ||
1169 | hints.ai_family = PF_UNSPEC; | ||
1170 | hints.ai_socktype = SOCK_STREAM; | ||
1171 | hints.ai_flags = AI_PASSIVE; | ||
1172 | |||
1173 | err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai); | ||
1174 | if (err != 0) { | ||
1175 | fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err)); | ||
1176 | exit(1); | ||
1177 | } | ||
1178 | |||
1179 | for (ai = gai_ai; ai != NULL; ai = ai->ai_next) { | ||
1180 | if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) | ||
1181 | continue; | ||
1182 | |||
1183 | err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, | ||
1184 | sizeof(ntop), strport, sizeof(strport), | ||
1185 | NI_NUMERICHOST|NI_NUMERICSERV); | ||
1186 | |||
1187 | if (ai->ai_family == AF_INET && err != 0) { | ||
1188 | perror("getnameinfo"); | ||
1189 | exit(2); | ||
1190 | } | ||
1191 | } | ||
1192 | exit(0); | ||
1193 | } | ||
1194 | ], | ||
1195 | [ | ||
1196 | AC_MSG_RESULT(yes) | ||
1197 | AC_DEFINE(AIX_GETNAMEINFO_HACK, [], | ||
1198 | [Define if you have a getaddrinfo that fails for the all-zeros IPv6 address]) | ||
1199 | ], | ||
1200 | [ | ||
1201 | AC_MSG_RESULT(no) | ||
1202 | AC_DEFINE(BROKEN_GETADDRINFO) | ||
1203 | ] | ||
1204 | ) | ||
1205 | fi | ||
1206 | |||
1149 | if test "x$check_for_conflicting_getspnam" = "x1"; then | 1207 | if test "x$check_for_conflicting_getspnam" = "x1"; then |
1150 | AC_MSG_CHECKING(for conflicting getspnam in shadow.h) | 1208 | AC_MSG_CHECKING(for conflicting getspnam in shadow.h) |
1151 | AC_COMPILE_IFELSE( | 1209 | AC_COMPILE_IFELSE( |
diff --git a/loginrec.c b/loginrec.c index c033582ad..8f5061cdc 100644 --- a/loginrec.c +++ b/loginrec.c | |||
@@ -164,7 +164,7 @@ | |||
164 | # include <libutil.h> | 164 | # include <libutil.h> |
165 | #endif | 165 | #endif |
166 | 166 | ||
167 | RCSID("$Id: loginrec.c,v 1.65 2005/02/08 10:52:48 dtucker Exp $"); | 167 | RCSID("$Id: loginrec.c,v 1.66 2005/02/15 10:45:57 dtucker Exp $"); |
168 | 168 | ||
169 | /** | 169 | /** |
170 | ** prototypes for helper functions in this file | 170 | ** prototypes for helper functions in this file |
@@ -192,6 +192,8 @@ int lastlog_get_entry(struct logininfo *li); | |||
192 | int wtmp_get_entry(struct logininfo *li); | 192 | int wtmp_get_entry(struct logininfo *li); |
193 | int wtmpx_get_entry(struct logininfo *li); | 193 | int wtmpx_get_entry(struct logininfo *li); |
194 | 194 | ||
195 | extern Buffer loginmsg; | ||
196 | |||
195 | /* pick the shortest string */ | 197 | /* pick the shortest string */ |
196 | #define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) | 198 | #define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) |
197 | 199 | ||
@@ -441,7 +443,7 @@ login_write(struct logininfo *li) | |||
441 | #endif | 443 | #endif |
442 | #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN | 444 | #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN |
443 | if (li->type == LTYPE_LOGIN && | 445 | if (li->type == LTYPE_LOGIN && |
444 | !sys_auth_record_login(li->username,li->hostname,li->line)) | 446 | !sys_auth_record_login(li->username,li->hostname,li->line, &loginmsg)) |
445 | logit("Writing login record failed for %s", li->username); | 447 | logit("Writing login record failed for %s", li->username); |
446 | #endif | 448 | #endif |
447 | #ifdef SSH_AUDIT_EVENTS | 449 | #ifdef SSH_AUDIT_EVENTS |
diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index b16988543..8ab862f98 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c | |||
@@ -34,14 +34,13 @@ | |||
34 | #ifdef _AIX | 34 | #ifdef _AIX |
35 | 35 | ||
36 | #include <uinfo.h> | 36 | #include <uinfo.h> |
37 | #include <sys/socket.h> | ||
37 | #include "port-aix.h" | 38 | #include "port-aix.h" |
38 | 39 | ||
39 | /* These should be in the system headers but are not. */ | 40 | /* These should be in the system headers but are not. */ |
40 | int usrinfo(int, char *, int); | 41 | int usrinfo(int, char *, int); |
41 | int setauthdb(const char *, char *); | 42 | int setauthdb(const char *, char *); |
42 | 43 | ||
43 | extern Buffer loginmsg; | ||
44 | |||
45 | # ifdef HAVE_SETAUTHDB | 44 | # ifdef HAVE_SETAUTHDB |
46 | static char old_registry[REGISTRY_SIZE] = ""; | 45 | static char old_registry[REGISTRY_SIZE] = ""; |
47 | # endif | 46 | # endif |
@@ -156,7 +155,7 @@ aix_valid_authentications(const char *user) | |||
156 | * returns 0. | 155 | * returns 0. |
157 | */ | 156 | */ |
158 | int | 157 | int |
159 | sys_auth_passwd(Authctxt *ctxt, const char *password) | 158 | sys_auth_passwd(Authctxt *ctxt, const char *password, Buffer *loginmsg) |
160 | { | 159 | { |
161 | char *authmsg = NULL, *msg, *name = ctxt->pw->pw_name; | 160 | char *authmsg = NULL, *msg, *name = ctxt->pw->pw_name; |
162 | int authsuccess = 0, expired, reenter, result; | 161 | int authsuccess = 0, expired, reenter, result; |
@@ -186,7 +185,7 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) | |||
186 | */ | 185 | */ |
187 | expired = passwdexpired(name, &msg); | 186 | expired = passwdexpired(name, &msg); |
188 | if (msg && *msg) { | 187 | if (msg && *msg) { |
189 | buffer_append(&loginmsg, msg, strlen(msg)); | 188 | buffer_append(loginmsg, msg, strlen(msg)); |
190 | aix_remove_embedded_newlines(msg); | 189 | aix_remove_embedded_newlines(msg); |
191 | } | 190 | } |
192 | debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); | 191 | debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); |
@@ -219,7 +218,7 @@ sys_auth_passwd(Authctxt *ctxt, const char *password) | |||
219 | * Returns 1 if login is allowed, 0 if not allowed. | 218 | * Returns 1 if login is allowed, 0 if not allowed. |
220 | */ | 219 | */ |
221 | int | 220 | int |
222 | sys_auth_allowed_user(struct passwd *pw) | 221 | sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) |
223 | { | 222 | { |
224 | char *msg = NULL; | 223 | char *msg = NULL; |
225 | int result, permitted = 0; | 224 | int result, permitted = 0; |
@@ -246,7 +245,7 @@ sys_auth_allowed_user(struct passwd *pw) | |||
246 | if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) | 245 | if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) |
247 | permitted = 1; | 246 | permitted = 1; |
248 | else if (msg != NULL) | 247 | else if (msg != NULL) |
249 | buffer_append(&loginmsg, msg, strlen(msg)); | 248 | buffer_append(loginmsg, msg, strlen(msg)); |
250 | if (msg == NULL) | 249 | if (msg == NULL) |
251 | msg = xstrdup("(none)"); | 250 | msg = xstrdup("(none)"); |
252 | aix_remove_embedded_newlines(msg); | 251 | aix_remove_embedded_newlines(msg); |
@@ -259,7 +258,8 @@ sys_auth_allowed_user(struct passwd *pw) | |||
259 | } | 258 | } |
260 | 259 | ||
261 | int | 260 | int |
262 | sys_auth_record_login(const char *user, const char *host, const char *ttynm) | 261 | sys_auth_record_login(const char *user, const char *host, const char *ttynm, |
262 | Buffer *loginmsg) | ||
263 | { | 263 | { |
264 | char *msg; | 264 | char *msg; |
265 | int success = 0; | 265 | int success = 0; |
@@ -269,7 +269,7 @@ sys_auth_record_login(const char *user, const char *host, const char *ttynm) | |||
269 | success = 1; | 269 | success = 1; |
270 | if (msg != NULL) { | 270 | if (msg != NULL) { |
271 | debug("AIX/loginsuccess: msg %s", msg); | 271 | debug("AIX/loginsuccess: msg %s", msg); |
272 | buffer_append(&loginmsg, msg, strlen(msg)); | 272 | buffer_append(loginmsg, msg, strlen(msg)); |
273 | xfree(msg); | 273 | xfree(msg); |
274 | } | 274 | } |
275 | } | 275 | } |
@@ -349,4 +349,33 @@ aix_restoreauthdb(void) | |||
349 | 349 | ||
350 | # endif /* WITH_AIXAUTHENTICATE */ | 350 | # endif /* WITH_AIXAUTHENTICATE */ |
351 | 351 | ||
352 | # if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) | ||
353 | # undef getnameinfo | ||
354 | /* | ||
355 | * For some reason, AIX's getnameinfo will refuse to resolve the all-zeros | ||
356 | * IPv6 address into its textual representation ("::"), so we wrap it | ||
357 | * with a function that will. | ||
358 | */ | ||
359 | int | ||
360 | sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, | ||
361 | size_t hostlen, char *serv, size_t servlen, int flags) | ||
362 | { | ||
363 | struct sockaddr_in6 *sa6; | ||
364 | u_int32_t *a6; | ||
365 | |||
366 | if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) && | ||
367 | sa->sa_family == AF_INET6) { | ||
368 | sa6 = (struct sockaddr_in6 *)sa; | ||
369 | a6 = sa6->sin6_addr.u6_addr.u6_addr32; | ||
370 | |||
371 | if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { | ||
372 | strlcpy(host, "::", hostlen); | ||
373 | snprintf(serv, servlen, "%d", sa6->sin6_port); | ||
374 | return 0; | ||
375 | } | ||
376 | } | ||
377 | return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); | ||
378 | } | ||
379 | # endif /* AIX_GETNAMEINFO_HACK */ | ||
380 | |||
352 | #endif /* _AIX */ | 381 | #endif /* _AIX */ |
diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index 751139004..cc7c43cda 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Id: port-aix.h,v 1.22 2005/02/02 06:10:11 dtucker Exp $ */ | 1 | /* $Id: port-aix.h,v 1.23 2005/02/15 10:45:58 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * | 4 | * |
@@ -27,6 +27,10 @@ | |||
27 | 27 | ||
28 | #ifdef _AIX | 28 | #ifdef _AIX |
29 | 29 | ||
30 | #ifdef HAVE_SYS_SOCKET_H | ||
31 | # include <sys/socket.h> | ||
32 | #endif | ||
33 | |||
30 | #ifdef WITH_AIXAUTHENTICATE | 34 | #ifdef WITH_AIXAUTHENTICATE |
31 | # include <login.h> | 35 | # include <login.h> |
32 | # include <userpw.h> | 36 | # include <userpw.h> |
@@ -36,6 +40,8 @@ | |||
36 | # include <usersec.h> | 40 | # include <usersec.h> |
37 | #endif | 41 | #endif |
38 | 42 | ||
43 | #include "buffer.h" | ||
44 | |||
39 | /* Some versions define r_type in the above headers, which causes a conflict */ | 45 | /* Some versions define r_type in the above headers, which causes a conflict */ |
40 | #ifdef r_type | 46 | #ifdef r_type |
41 | # undef r_type | 47 | # undef r_type |
@@ -64,13 +70,23 @@ void aix_usrinfo(struct passwd *); | |||
64 | #ifdef WITH_AIXAUTHENTICATE | 70 | #ifdef WITH_AIXAUTHENTICATE |
65 | # define CUSTOM_SYS_AUTH_PASSWD 1 | 71 | # define CUSTOM_SYS_AUTH_PASSWD 1 |
66 | # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 | 72 | # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 |
67 | int sys_auth_allowed_user(struct passwd *); | 73 | int sys_auth_allowed_user(struct passwd *, Buffer *); |
68 | # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 | 74 | # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 |
69 | int sys_auth_record_login(const char *, const char *, const char *); | 75 | int sys_auth_record_login(const char *, const char *, const char *, Buffer *); |
70 | # define CUSTOM_FAILED_LOGIN 1 | 76 | # define CUSTOM_FAILED_LOGIN 1 |
71 | #endif | 77 | #endif |
72 | 78 | ||
73 | void aix_setauthdb(const char *); | 79 | void aix_setauthdb(const char *); |
74 | void aix_restoreauthdb(void); | 80 | void aix_restoreauthdb(void); |
75 | void aix_remove_embedded_newlines(char *); | 81 | void aix_remove_embedded_newlines(char *); |
82 | |||
83 | #if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_GETADDRINFO) | ||
84 | # ifdef getnameinfo | ||
85 | # undef getnameinfo | ||
86 | # endif | ||
87 | int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t, | ||
88 | char *, size_t, int); | ||
89 | # define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) | ||
90 | #endif | ||
91 | |||
76 | #endif /* _AIX */ | 92 | #endif /* _AIX */ |