Ben Lindstrom | 51b2488 | 2002-07-04 03:08:40 +0000 | [diff] [blame] | 1 | /* |
Ben Lindstrom | 024f08f | 2002-07-07 02:17:36 +0000 | [diff] [blame] | 2 | * |
| 3 | * Copyright (c) 2001 Gert Doering. All rights reserved. |
Darren Tucker | 782727a | 2005-05-29 10:28:48 +1000 | [diff] [blame] | 4 | * Copyright (c) 2003,2004,2005 Darren Tucker. All rights reserved. |
Ben Lindstrom | 024f08f | 2002-07-07 02:17:36 +0000 | [diff] [blame] | 5 | * |
Ben Lindstrom | 51b2488 | 2002-07-04 03:08:40 +0000 | [diff] [blame] | 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions |
| 8 | * are met: |
| 9 | * 1. Redistributions of source code must retain the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer. |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer in the |
| 13 | * documentation and/or other materials provided with the distribution. |
| 14 | * |
| 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 | * |
| 26 | */ |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 27 | #include "includes.h" |
Damien Miller | d783435 | 2006-08-05 12:39:39 +1000 | [diff] [blame] | 28 | |
| 29 | #include "xmalloc.h" |
| 30 | #include "buffer.h" |
| 31 | #include "key.h" |
| 32 | #include "hostfile.h" |
Darren Tucker | cfea206 | 2004-02-10 15:27:34 +1100 | [diff] [blame] | 33 | #include "auth.h" |
Darren Tucker | 97363a8 | 2003-05-02 23:42:25 +1000 | [diff] [blame] | 34 | #include "ssh.h" |
| 35 | #include "log.h" |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 36 | |
| 37 | #ifdef _AIX |
| 38 | |
Darren Tucker | 2eaea99 | 2006-07-12 23:41:33 +1000 | [diff] [blame] | 39 | #include <errno.h> |
Damien Miller | be43ebf | 2006-07-24 13:51:51 +1000 | [diff] [blame] | 40 | #if defined(HAVE_NETDB_H) |
| 41 | # include <netdb.h> |
| 42 | #endif |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 43 | #include <uinfo.h> |
Damien Miller | ded319c | 2006-09-01 15:38:36 +1000 | [diff] [blame] | 44 | #include <stdarg.h> |
Damien Miller | 62da44f | 2006-07-24 15:08:35 +1000 | [diff] [blame] | 45 | #include <string.h> |
| 46 | #include <unistd.h> |
Darren Tucker | 691d523 | 2005-02-15 21:45:57 +1100 | [diff] [blame] | 47 | #include <sys/socket.h> |
Darren Tucker | c70ce7b | 2006-09-18 23:54:32 +1000 | [diff] [blame] | 48 | |
| 49 | #ifdef WITH_AIXAUTHENTICATE |
| 50 | # include <login.h> |
| 51 | # include <userpw.h> |
| 52 | # if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG) |
| 53 | # include <sys/audit.h> |
| 54 | # endif |
| 55 | # include <usersec.h> |
| 56 | #endif |
| 57 | |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 58 | #include "port-aix.h" |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 59 | |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 60 | # ifdef HAVE_SETAUTHDB |
| 61 | static char old_registry[REGISTRY_SIZE] = ""; |
| 62 | # endif |
| 63 | |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 64 | /* |
Darren Tucker | 6b2fe31 | 2005-05-29 10:32:47 +1000 | [diff] [blame] | 65 | * AIX has a "usrinfo" area where logname and other stuff is stored - |
Ben Lindstrom | 51b2488 | 2002-07-04 03:08:40 +0000 | [diff] [blame] | 66 | * a few applications actually use this and die if it's not set |
| 67 | * |
| 68 | * NOTE: TTY= should be set, but since no one uses it and it's hard to |
| 69 | * acquire due to privsep code. We will just drop support. |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 70 | */ |
| 71 | void |
Ben Lindstrom | 51b2488 | 2002-07-04 03:08:40 +0000 | [diff] [blame] | 72 | aix_usrinfo(struct passwd *pw) |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 73 | { |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 74 | u_int i; |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 75 | size_t len; |
Ben Lindstrom | 51b2488 | 2002-07-04 03:08:40 +0000 | [diff] [blame] | 76 | char *cp; |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 77 | |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 78 | len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); |
| 79 | cp = xmalloc(len); |
| 80 | |
Darren Tucker | 6b2fe31 | 2005-05-29 10:32:47 +1000 | [diff] [blame] | 81 | i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', |
Damien Miller | 3867bf3 | 2003-05-19 09:33:15 +1000 | [diff] [blame] | 82 | pw->pw_name, '\0'); |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 83 | if (usrinfo(SETUINFO, cp, i) == -1) |
| 84 | fatal("Couldn't set usrinfo: %s", strerror(errno)); |
| 85 | debug3("AIX/UsrInfo: set len %d", i); |
Damien Miller | 3174125 | 2003-05-19 00:13:38 +1000 | [diff] [blame] | 86 | |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 87 | xfree(cp); |
| 88 | } |
| 89 | |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 90 | # ifdef WITH_AIXAUTHENTICATE |
Darren Tucker | b9aa0a0 | 2003-07-08 22:59:59 +1000 | [diff] [blame] | 91 | /* |
| 92 | * Remove embedded newlines in string (if any). |
| 93 | * Used before logging messages returned by AIX authentication functions |
| 94 | * so the message is logged on one line. |
| 95 | */ |
| 96 | void |
| 97 | aix_remove_embedded_newlines(char *p) |
| 98 | { |
| 99 | if (p == NULL) |
| 100 | return; |
| 101 | |
| 102 | for (; *p; p++) { |
| 103 | if (*p == '\n') |
| 104 | *p = ' '; |
| 105 | } |
| 106 | /* Remove trailing whitespace */ |
| 107 | if (*--p == ' ') |
| 108 | *p = '\0'; |
| 109 | } |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 110 | |
| 111 | /* |
Darren Tucker | 5a88d00 | 2004-08-29 21:43:33 +1000 | [diff] [blame] | 112 | * Test specifically for the case where SYSTEM == NONE and AUTH1 contains |
| 113 | * anything other than NONE or SYSTEM, which indicates that the admin has |
| 114 | * configured the account for purely AUTH1-type authentication. |
| 115 | * |
| 116 | * Since authenticate() doesn't check AUTH1, and sshd can't sanely support |
| 117 | * AUTH1 itself, in such a case authenticate() will allow access without |
| 118 | * authentation, which is almost certainly not what the admin intends. |
| 119 | * |
| 120 | * (The native tools, eg login, will process the AUTH1 list in addition to |
| 121 | * the SYSTEM list by using ckuserID(), however ckuserID() and AUTH1 methods |
| 122 | * have been deprecated since AIX 4.2.x and would be very difficult for sshd |
| 123 | * to support. |
| 124 | * |
| 125 | * Returns 0 if an unsupportable combination is found, 1 otherwise. |
| 126 | */ |
| 127 | static int |
| 128 | aix_valid_authentications(const char *user) |
| 129 | { |
| 130 | char *auth1, *sys, *p; |
| 131 | int valid = 1; |
| 132 | |
| 133 | if (getuserattr((char *)user, S_AUTHSYSTEM, &sys, SEC_CHAR) != 0) { |
| 134 | logit("Can't retrieve attribute SYSTEM for %s: %.100s", |
| 135 | user, strerror(errno)); |
| 136 | return 0; |
| 137 | } |
| 138 | |
| 139 | debug3("AIX SYSTEM attribute %s", sys); |
| 140 | if (strcmp(sys, "NONE") != 0) |
| 141 | return 1; /* not "NONE", so is OK */ |
| 142 | |
| 143 | if (getuserattr((char *)user, S_AUTH1, &auth1, SEC_LIST) != 0) { |
| 144 | logit("Can't retrieve attribute auth1 for %s: %.100s", |
| 145 | user, strerror(errno)); |
| 146 | return 0; |
| 147 | } |
| 148 | |
| 149 | p = auth1; |
| 150 | /* A SEC_LIST is concatenated strings, ending with two NULs. */ |
| 151 | while (p[0] != '\0' && p[1] != '\0') { |
| 152 | debug3("AIX auth1 attribute list member %s", p); |
| 153 | if (strcmp(p, "NONE") != 0 && strcmp(p, "SYSTEM")) { |
| 154 | logit("Account %s has unsupported auth1 value '%s'", |
| 155 | user, p); |
| 156 | valid = 0; |
| 157 | } |
| 158 | p += strlen(p) + 1; |
| 159 | } |
| 160 | |
| 161 | return (valid); |
| 162 | } |
| 163 | |
| 164 | /* |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 165 | * Do authentication via AIX's authenticate routine. We loop until the |
| 166 | * reenter parameter is 0, but normally authenticate is called only once. |
| 167 | * |
| 168 | * Note: this function returns 1 on success, whereas AIX's authenticate() |
| 169 | * returns 0. |
| 170 | */ |
| 171 | int |
Darren Tucker | f3bb434 | 2005-03-31 21:39:25 +1000 | [diff] [blame] | 172 | sys_auth_passwd(Authctxt *ctxt, const char *password) |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 173 | { |
Darren Tucker | 782727a | 2005-05-29 10:28:48 +1000 | [diff] [blame] | 174 | char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name; |
Darren Tucker | e3dba82 | 2004-02-10 12:50:19 +1100 | [diff] [blame] | 175 | int authsuccess = 0, expired, reenter, result; |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 176 | |
| 177 | do { |
| 178 | result = authenticate((char *)name, (char *)password, &reenter, |
| 179 | &authmsg); |
| 180 | aix_remove_embedded_newlines(authmsg); |
Darren Tucker | f9fea65 | 2005-05-29 10:54:27 +1000 | [diff] [blame] | 181 | debug3("AIX/authenticate result %d, authmsg %.100s", result, |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 182 | authmsg); |
| 183 | } while (reenter); |
| 184 | |
Darren Tucker | 5a88d00 | 2004-08-29 21:43:33 +1000 | [diff] [blame] | 185 | if (!aix_valid_authentications(name)) |
| 186 | result = -1; |
| 187 | |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 188 | if (result == 0) { |
| 189 | authsuccess = 1; |
| 190 | |
Darren Tucker | 6b2fe31 | 2005-05-29 10:32:47 +1000 | [diff] [blame] | 191 | /* |
Darren Tucker | e3dba82 | 2004-02-10 12:50:19 +1100 | [diff] [blame] | 192 | * Record successful login. We don't have a pty yet, so just |
| 193 | * label the line as "ssh" |
| 194 | */ |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 195 | aix_setauthdb(name); |
Darren Tucker | e3dba82 | 2004-02-10 12:50:19 +1100 | [diff] [blame] | 196 | |
| 197 | /* |
| 198 | * Check if the user's password is expired. |
| 199 | */ |
Darren Tucker | a7ea546 | 2004-06-16 12:01:15 +1000 | [diff] [blame] | 200 | expired = passwdexpired(name, &msg); |
| 201 | if (msg && *msg) { |
Darren Tucker | f3bb434 | 2005-03-31 21:39:25 +1000 | [diff] [blame] | 202 | buffer_append(ctxt->loginmsg, msg, strlen(msg)); |
Darren Tucker | a7ea546 | 2004-06-16 12:01:15 +1000 | [diff] [blame] | 203 | aix_remove_embedded_newlines(msg); |
| 204 | } |
| 205 | debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); |
Darren Tucker | e3dba82 | 2004-02-10 12:50:19 +1100 | [diff] [blame] | 206 | |
| 207 | switch (expired) { |
| 208 | case 0: /* password not expired */ |
| 209 | break; |
| 210 | case 1: /* expired, password change required */ |
| 211 | ctxt->force_pwchange = 1; |
Darren Tucker | e3dba82 | 2004-02-10 12:50:19 +1100 | [diff] [blame] | 212 | break; |
| 213 | default: /* user can't change(2) or other error (-1) */ |
| 214 | logit("Password can't be changed for user %s: %.100s", |
| 215 | name, msg); |
| 216 | if (msg) |
| 217 | xfree(msg); |
| 218 | authsuccess = 0; |
| 219 | } |
| 220 | |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 221 | aix_restoreauthdb(); |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 222 | } |
| 223 | |
| 224 | if (authmsg != NULL) |
| 225 | xfree(authmsg); |
| 226 | |
| 227 | return authsuccess; |
| 228 | } |
Darren Tucker | 0a9d43d | 2004-06-23 13:45:24 +1000 | [diff] [blame] | 229 | |
| 230 | /* |
| 231 | * Check if specified account is permitted to log in. |
| 232 | * Returns 1 if login is allowed, 0 if not allowed. |
| 233 | */ |
| 234 | int |
Darren Tucker | 691d523 | 2005-02-15 21:45:57 +1100 | [diff] [blame] | 235 | sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) |
Darren Tucker | 0a9d43d | 2004-06-23 13:45:24 +1000 | [diff] [blame] | 236 | { |
| 237 | char *msg = NULL; |
| 238 | int result, permitted = 0; |
| 239 | struct stat st; |
| 240 | |
| 241 | /* |
| 242 | * Don't perform checks for root account (PermitRootLogin controls |
Darren Tucker | 863cfa0 | 2007-08-09 14:29:47 +1000 | [diff] [blame^] | 243 | * logins via ssh) or if running as non-root user (since |
Darren Tucker | 0a9d43d | 2004-06-23 13:45:24 +1000 | [diff] [blame] | 244 | * loginrestrictions will always fail due to insufficient privilege). |
| 245 | */ |
| 246 | if (pw->pw_uid == 0 || geteuid() != 0) { |
Darren Tucker | 5288cb2 | 2004-06-28 18:11:19 +1000 | [diff] [blame] | 247 | debug3("%s: not checking", __func__); |
Darren Tucker | 0a9d43d | 2004-06-23 13:45:24 +1000 | [diff] [blame] | 248 | return 1; |
| 249 | } |
| 250 | |
| 251 | result = loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg); |
| 252 | if (result == 0) |
| 253 | permitted = 1; |
| 254 | /* |
| 255 | * If restricted because /etc/nologin exists, the login will be denied |
| 256 | * in session.c after the nologin message is sent, so allow for now |
| 257 | * and do not append the returned message. |
| 258 | */ |
| 259 | if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) |
| 260 | permitted = 1; |
| 261 | else if (msg != NULL) |
Darren Tucker | 691d523 | 2005-02-15 21:45:57 +1100 | [diff] [blame] | 262 | buffer_append(loginmsg, msg, strlen(msg)); |
Darren Tucker | 0a9d43d | 2004-06-23 13:45:24 +1000 | [diff] [blame] | 263 | if (msg == NULL) |
| 264 | msg = xstrdup("(none)"); |
| 265 | aix_remove_embedded_newlines(msg); |
| 266 | debug3("AIX/loginrestrictions returned %d msg %.100s", result, msg); |
| 267 | |
| 268 | if (!permitted) |
| 269 | logit("Login restricted for %s: %.100s", pw->pw_name, msg); |
| 270 | xfree(msg); |
| 271 | return permitted; |
| 272 | } |
| 273 | |
Darren Tucker | 397a2f2 | 2004-08-15 00:09:11 +1000 | [diff] [blame] | 274 | int |
Darren Tucker | 691d523 | 2005-02-15 21:45:57 +1100 | [diff] [blame] | 275 | sys_auth_record_login(const char *user, const char *host, const char *ttynm, |
| 276 | Buffer *loginmsg) |
Darren Tucker | 397a2f2 | 2004-08-15 00:09:11 +1000 | [diff] [blame] | 277 | { |
Darren Tucker | 782727a | 2005-05-29 10:28:48 +1000 | [diff] [blame] | 278 | char *msg = NULL; |
Darren Tucker | 26d4e19 | 2006-08-30 22:33:09 +1000 | [diff] [blame] | 279 | static int msg_done = 0; |
Darren Tucker | 397a2f2 | 2004-08-15 00:09:11 +1000 | [diff] [blame] | 280 | int success = 0; |
| 281 | |
| 282 | aix_setauthdb(user); |
Darren Tucker | b4d3012 | 2005-02-08 21:06:55 +1100 | [diff] [blame] | 283 | if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) { |
Darren Tucker | 397a2f2 | 2004-08-15 00:09:11 +1000 | [diff] [blame] | 284 | success = 1; |
Darren Tucker | 26d4e19 | 2006-08-30 22:33:09 +1000 | [diff] [blame] | 285 | if (msg != NULL && loginmsg != NULL && !msg_done) { |
Darren Tucker | b4d3012 | 2005-02-08 21:06:55 +1100 | [diff] [blame] | 286 | debug("AIX/loginsuccess: msg %s", msg); |
Darren Tucker | 691d523 | 2005-02-15 21:45:57 +1100 | [diff] [blame] | 287 | buffer_append(loginmsg, msg, strlen(msg)); |
Darren Tucker | 397a2f2 | 2004-08-15 00:09:11 +1000 | [diff] [blame] | 288 | xfree(msg); |
Darren Tucker | 26d4e19 | 2006-08-30 22:33:09 +1000 | [diff] [blame] | 289 | msg_done = 1; |
Darren Tucker | 397a2f2 | 2004-08-15 00:09:11 +1000 | [diff] [blame] | 290 | } |
| 291 | } |
| 292 | aix_restoreauthdb(); |
| 293 | return (success); |
| 294 | } |
| 295 | |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 296 | # ifdef CUSTOM_FAILED_LOGIN |
Darren Tucker | 97363a8 | 2003-05-02 23:42:25 +1000 | [diff] [blame] | 297 | /* |
| 298 | * record_failed_login: generic "login failed" interface function |
| 299 | */ |
| 300 | void |
Darren Tucker | 42d9dc7 | 2005-02-02 17:10:11 +1100 | [diff] [blame] | 301 | record_failed_login(const char *user, const char *hostname, const char *ttyname) |
Darren Tucker | 97363a8 | 2003-05-02 23:42:25 +1000 | [diff] [blame] | 302 | { |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 303 | if (geteuid() != 0) |
| 304 | return; |
| 305 | |
| 306 | aix_setauthdb(user); |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 307 | # ifdef AIX_LOGINFAILED_4ARG |
Darren Tucker | b4d3012 | 2005-02-08 21:06:55 +1100 | [diff] [blame] | 308 | loginfailed((char *)user, (char *)hostname, (char *)ttyname, |
| 309 | AUDIT_FAIL_AUTH); |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 310 | # else |
Darren Tucker | b4d3012 | 2005-02-08 21:06:55 +1100 | [diff] [blame] | 311 | loginfailed((char *)user, (char *)hostname, (char *)ttyname); |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 312 | # endif |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 313 | aix_restoreauthdb(); |
Darren Tucker | 97363a8 | 2003-05-02 23:42:25 +1000 | [diff] [blame] | 314 | } |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 315 | # endif /* CUSTOM_FAILED_LOGIN */ |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 316 | |
| 317 | /* |
| 318 | * If we have setauthdb, retrieve the password registry for the user's |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 319 | * account then feed it to setauthdb. This will mean that subsequent AIX auth |
| 320 | * functions will only use the specified loadable module. If we don't have |
| 321 | * setauthdb this is a no-op. |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 322 | */ |
| 323 | void |
| 324 | aix_setauthdb(const char *user) |
| 325 | { |
| 326 | # ifdef HAVE_SETAUTHDB |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 327 | char *registry; |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 328 | |
| 329 | if (setuserdb(S_READ) == -1) { |
| 330 | debug3("%s: Could not open userdb to read", __func__); |
| 331 | return; |
| 332 | } |
| 333 | |
| 334 | if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 335 | if (setauthdb(registry, old_registry) == 0) |
| 336 | debug3("AIX/setauthdb set registry '%s'", registry); |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 337 | else |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 338 | debug3("AIX/setauthdb set registry '%s' failed: %s", |
| 339 | registry, strerror(errno)); |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 340 | } else |
| 341 | debug3("%s: Could not read S_REGISTRY for user: %s", __func__, |
| 342 | strerror(errno)); |
| 343 | enduserdb(); |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 344 | # endif /* HAVE_SETAUTHDB */ |
Darren Tucker | fc3454e | 2003-07-14 16:41:55 +1000 | [diff] [blame] | 345 | } |
Ben Lindstrom | a9c039c | 2002-02-19 20:27:55 +0000 | [diff] [blame] | 346 | |
Darren Tucker | e45674a | 2004-02-06 16:17:51 +1100 | [diff] [blame] | 347 | /* |
| 348 | * Restore the user's registry settings from old_registry. |
| 349 | * Note that if the first aix_setauthdb fails, setauthdb("") is still safe |
| 350 | * (it restores the system default behaviour). If we don't have setauthdb, |
| 351 | * this is a no-op. |
| 352 | */ |
| 353 | void |
| 354 | aix_restoreauthdb(void) |
| 355 | { |
| 356 | # ifdef HAVE_SETAUTHDB |
| 357 | if (setauthdb(old_registry, NULL) == 0) |
| 358 | debug3("%s: restoring old registry '%s'", __func__, |
| 359 | old_registry); |
| 360 | else |
| 361 | debug3("%s: failed to restore old registry %s", __func__, |
| 362 | old_registry); |
| 363 | # endif /* HAVE_SETAUTHDB */ |
| 364 | } |
| 365 | |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 366 | # endif /* WITH_AIXAUTHENTICATE */ |
| 367 | |
Darren Tucker | 691d523 | 2005-02-15 21:45:57 +1100 | [diff] [blame] | 368 | # if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) |
| 369 | # undef getnameinfo |
| 370 | /* |
| 371 | * For some reason, AIX's getnameinfo will refuse to resolve the all-zeros |
| 372 | * IPv6 address into its textual representation ("::"), so we wrap it |
| 373 | * with a function that will. |
| 374 | */ |
| 375 | int |
| 376 | sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, |
| 377 | size_t hostlen, char *serv, size_t servlen, int flags) |
| 378 | { |
| 379 | struct sockaddr_in6 *sa6; |
| 380 | u_int32_t *a6; |
| 381 | |
| 382 | if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) && |
| 383 | sa->sa_family == AF_INET6) { |
| 384 | sa6 = (struct sockaddr_in6 *)sa; |
| 385 | a6 = sa6->sin6_addr.u6_addr.u6_addr32; |
| 386 | |
| 387 | if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { |
| 388 | strlcpy(host, "::", hostlen); |
| 389 | snprintf(serv, servlen, "%d", sa6->sin6_port); |
| 390 | return 0; |
| 391 | } |
| 392 | } |
| 393 | return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); |
| 394 | } |
| 395 | # endif /* AIX_GETNAMEINFO_HACK */ |
| 396 | |
Darren Tucker | d763416 | 2003-11-22 14:16:56 +1100 | [diff] [blame] | 397 | #endif /* _AIX */ |