14b17dab0SDag-Erling Smørgrav /* 24b17dab0SDag-Erling Smørgrav * 34b17dab0SDag-Erling Smørgrav * Copyright (c) 2001 Gert Doering. All rights reserved. 4d4af9e69SDag-Erling Smørgrav * Copyright (c) 2003,2004,2005,2006 Darren Tucker. All rights reserved. 54b17dab0SDag-Erling Smørgrav * 64b17dab0SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 74b17dab0SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 84b17dab0SDag-Erling Smørgrav * are met: 94b17dab0SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 104b17dab0SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 114b17dab0SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 124b17dab0SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 134b17dab0SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 144b17dab0SDag-Erling Smørgrav * 154b17dab0SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 164b17dab0SDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 174b17dab0SDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 184b17dab0SDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 194b17dab0SDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 204b17dab0SDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 214b17dab0SDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 224b17dab0SDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 234b17dab0SDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 244b17dab0SDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 254b17dab0SDag-Erling Smørgrav * 264b17dab0SDag-Erling Smørgrav */ 2783d2307dSDag-Erling Smørgrav #include "includes.h" 28761efaa7SDag-Erling Smørgrav 29761efaa7SDag-Erling Smørgrav #include "xmalloc.h" 30761efaa7SDag-Erling Smørgrav #include "buffer.h" 31761efaa7SDag-Erling Smørgrav #include "key.h" 32761efaa7SDag-Erling Smørgrav #include "hostfile.h" 33efcad6b7SDag-Erling Smørgrav #include "auth.h" 34d95e11bfSDag-Erling Smørgrav #include "ssh.h" 35d95e11bfSDag-Erling Smørgrav #include "log.h" 3683d2307dSDag-Erling Smørgrav 3783d2307dSDag-Erling Smørgrav #ifdef _AIX 3883d2307dSDag-Erling Smørgrav 39761efaa7SDag-Erling Smørgrav #include <errno.h> 40761efaa7SDag-Erling Smørgrav #if defined(HAVE_NETDB_H) 41761efaa7SDag-Erling Smørgrav # include <netdb.h> 42761efaa7SDag-Erling Smørgrav #endif 4383d2307dSDag-Erling Smørgrav #include <uinfo.h> 44761efaa7SDag-Erling Smørgrav #include <stdarg.h> 45761efaa7SDag-Erling Smørgrav #include <string.h> 46761efaa7SDag-Erling Smørgrav #include <unistd.h> 475e8dbd04SDag-Erling Smørgrav #include <sys/socket.h> 48761efaa7SDag-Erling Smørgrav 49761efaa7SDag-Erling Smørgrav #ifdef WITH_AIXAUTHENTICATE 50761efaa7SDag-Erling Smørgrav # include <login.h> 51761efaa7SDag-Erling Smørgrav # include <userpw.h> 52761efaa7SDag-Erling Smørgrav # if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG) 53761efaa7SDag-Erling Smørgrav # include <sys/audit.h> 54761efaa7SDag-Erling Smørgrav # endif 55761efaa7SDag-Erling Smørgrav # include <usersec.h> 56761efaa7SDag-Erling Smørgrav #endif 57761efaa7SDag-Erling Smørgrav 58d95e11bfSDag-Erling Smørgrav #include "port-aix.h" 59d95e11bfSDag-Erling Smørgrav 607aee6ffeSDag-Erling Smørgrav static char *lastlogin_msg = NULL; 617aee6ffeSDag-Erling Smørgrav 62efcad6b7SDag-Erling Smørgrav # ifdef HAVE_SETAUTHDB 63efcad6b7SDag-Erling Smørgrav static char old_registry[REGISTRY_SIZE] = ""; 64efcad6b7SDag-Erling Smørgrav # endif 6583d2307dSDag-Erling Smørgrav 6683d2307dSDag-Erling Smørgrav /* 674b17dab0SDag-Erling Smørgrav * AIX has a "usrinfo" area where logname and other stuff is stored - 684b17dab0SDag-Erling Smørgrav * a few applications actually use this and die if it's not set 694b17dab0SDag-Erling Smørgrav * 704b17dab0SDag-Erling Smørgrav * NOTE: TTY= should be set, but since no one uses it and it's hard to 714b17dab0SDag-Erling Smørgrav * acquire due to privsep code. We will just drop support. 7283d2307dSDag-Erling Smørgrav */ 7383d2307dSDag-Erling Smørgrav void 744b17dab0SDag-Erling Smørgrav aix_usrinfo(struct passwd *pw) 7583d2307dSDag-Erling Smørgrav { 7683d2307dSDag-Erling Smørgrav u_int i; 77d95e11bfSDag-Erling Smørgrav size_t len; 784b17dab0SDag-Erling Smørgrav char *cp; 7983d2307dSDag-Erling Smørgrav 80d95e11bfSDag-Erling Smørgrav len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); 81d95e11bfSDag-Erling Smørgrav cp = xmalloc(len); 82d95e11bfSDag-Erling Smørgrav 83d95e11bfSDag-Erling Smørgrav i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', 84d95e11bfSDag-Erling Smørgrav pw->pw_name, '\0'); 8583d2307dSDag-Erling Smørgrav if (usrinfo(SETUINFO, cp, i) == -1) 8683d2307dSDag-Erling Smørgrav fatal("Couldn't set usrinfo: %s", strerror(errno)); 8783d2307dSDag-Erling Smørgrav debug3("AIX/UsrInfo: set len %d", i); 88d95e11bfSDag-Erling Smørgrav 8983d2307dSDag-Erling Smørgrav xfree(cp); 9083d2307dSDag-Erling Smørgrav } 9183d2307dSDag-Erling Smørgrav 92d95e11bfSDag-Erling Smørgrav # ifdef WITH_AIXAUTHENTICATE 93d95e11bfSDag-Erling Smørgrav /* 94d95e11bfSDag-Erling Smørgrav * Remove embedded newlines in string (if any). 95d95e11bfSDag-Erling Smørgrav * Used before logging messages returned by AIX authentication functions 96d95e11bfSDag-Erling Smørgrav * so the message is logged on one line. 97d95e11bfSDag-Erling Smørgrav */ 98d95e11bfSDag-Erling Smørgrav void 99d95e11bfSDag-Erling Smørgrav aix_remove_embedded_newlines(char *p) 100d95e11bfSDag-Erling Smørgrav { 101d95e11bfSDag-Erling Smørgrav if (p == NULL) 102d95e11bfSDag-Erling Smørgrav return; 103d95e11bfSDag-Erling Smørgrav 104d95e11bfSDag-Erling Smørgrav for (; *p; p++) { 105d95e11bfSDag-Erling Smørgrav if (*p == '\n') 106d95e11bfSDag-Erling Smørgrav *p = ' '; 107d95e11bfSDag-Erling Smørgrav } 108d95e11bfSDag-Erling Smørgrav /* Remove trailing whitespace */ 109d95e11bfSDag-Erling Smørgrav if (*--p == ' ') 110d95e11bfSDag-Erling Smørgrav *p = '\0'; 111d95e11bfSDag-Erling Smørgrav } 112efcad6b7SDag-Erling Smørgrav 113efcad6b7SDag-Erling Smørgrav /* 1145e8dbd04SDag-Erling Smørgrav * Test specifically for the case where SYSTEM == NONE and AUTH1 contains 1155e8dbd04SDag-Erling Smørgrav * anything other than NONE or SYSTEM, which indicates that the admin has 1165e8dbd04SDag-Erling Smørgrav * configured the account for purely AUTH1-type authentication. 1175e8dbd04SDag-Erling Smørgrav * 1185e8dbd04SDag-Erling Smørgrav * Since authenticate() doesn't check AUTH1, and sshd can't sanely support 1195e8dbd04SDag-Erling Smørgrav * AUTH1 itself, in such a case authenticate() will allow access without 1205e8dbd04SDag-Erling Smørgrav * authentation, which is almost certainly not what the admin intends. 1215e8dbd04SDag-Erling Smørgrav * 1225e8dbd04SDag-Erling Smørgrav * (The native tools, eg login, will process the AUTH1 list in addition to 1235e8dbd04SDag-Erling Smørgrav * the SYSTEM list by using ckuserID(), however ckuserID() and AUTH1 methods 1245e8dbd04SDag-Erling Smørgrav * have been deprecated since AIX 4.2.x and would be very difficult for sshd 1255e8dbd04SDag-Erling Smørgrav * to support. 1265e8dbd04SDag-Erling Smørgrav * 1275e8dbd04SDag-Erling Smørgrav * Returns 0 if an unsupportable combination is found, 1 otherwise. 1285e8dbd04SDag-Erling Smørgrav */ 1295e8dbd04SDag-Erling Smørgrav static int 1305e8dbd04SDag-Erling Smørgrav aix_valid_authentications(const char *user) 1315e8dbd04SDag-Erling Smørgrav { 1325e8dbd04SDag-Erling Smørgrav char *auth1, *sys, *p; 1335e8dbd04SDag-Erling Smørgrav int valid = 1; 1345e8dbd04SDag-Erling Smørgrav 1355e8dbd04SDag-Erling Smørgrav if (getuserattr((char *)user, S_AUTHSYSTEM, &sys, SEC_CHAR) != 0) { 1365e8dbd04SDag-Erling Smørgrav logit("Can't retrieve attribute SYSTEM for %s: %.100s", 1375e8dbd04SDag-Erling Smørgrav user, strerror(errno)); 1385e8dbd04SDag-Erling Smørgrav return 0; 1395e8dbd04SDag-Erling Smørgrav } 1405e8dbd04SDag-Erling Smørgrav 1415e8dbd04SDag-Erling Smørgrav debug3("AIX SYSTEM attribute %s", sys); 1425e8dbd04SDag-Erling Smørgrav if (strcmp(sys, "NONE") != 0) 1435e8dbd04SDag-Erling Smørgrav return 1; /* not "NONE", so is OK */ 1445e8dbd04SDag-Erling Smørgrav 1455e8dbd04SDag-Erling Smørgrav if (getuserattr((char *)user, S_AUTH1, &auth1, SEC_LIST) != 0) { 1465e8dbd04SDag-Erling Smørgrav logit("Can't retrieve attribute auth1 for %s: %.100s", 1475e8dbd04SDag-Erling Smørgrav user, strerror(errno)); 1485e8dbd04SDag-Erling Smørgrav return 0; 1495e8dbd04SDag-Erling Smørgrav } 1505e8dbd04SDag-Erling Smørgrav 1515e8dbd04SDag-Erling Smørgrav p = auth1; 1525e8dbd04SDag-Erling Smørgrav /* A SEC_LIST is concatenated strings, ending with two NULs. */ 1535e8dbd04SDag-Erling Smørgrav while (p[0] != '\0' && p[1] != '\0') { 1545e8dbd04SDag-Erling Smørgrav debug3("AIX auth1 attribute list member %s", p); 1555e8dbd04SDag-Erling Smørgrav if (strcmp(p, "NONE") != 0 && strcmp(p, "SYSTEM")) { 1565e8dbd04SDag-Erling Smørgrav logit("Account %s has unsupported auth1 value '%s'", 1575e8dbd04SDag-Erling Smørgrav user, p); 1585e8dbd04SDag-Erling Smørgrav valid = 0; 1595e8dbd04SDag-Erling Smørgrav } 1605e8dbd04SDag-Erling Smørgrav p += strlen(p) + 1; 1615e8dbd04SDag-Erling Smørgrav } 1625e8dbd04SDag-Erling Smørgrav 1635e8dbd04SDag-Erling Smørgrav return (valid); 1645e8dbd04SDag-Erling Smørgrav } 1655e8dbd04SDag-Erling Smørgrav 1665e8dbd04SDag-Erling Smørgrav /* 167efcad6b7SDag-Erling Smørgrav * Do authentication via AIX's authenticate routine. We loop until the 168efcad6b7SDag-Erling Smørgrav * reenter parameter is 0, but normally authenticate is called only once. 169efcad6b7SDag-Erling Smørgrav * 170efcad6b7SDag-Erling Smørgrav * Note: this function returns 1 on success, whereas AIX's authenticate() 171efcad6b7SDag-Erling Smørgrav * returns 0. 172efcad6b7SDag-Erling Smørgrav */ 173efcad6b7SDag-Erling Smørgrav int 1744518870cSDag-Erling Smørgrav sys_auth_passwd(Authctxt *ctxt, const char *password) 175efcad6b7SDag-Erling Smørgrav { 176043840dfSDag-Erling Smørgrav char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name; 177efcad6b7SDag-Erling Smørgrav int authsuccess = 0, expired, reenter, result; 178efcad6b7SDag-Erling Smørgrav 179efcad6b7SDag-Erling Smørgrav do { 180efcad6b7SDag-Erling Smørgrav result = authenticate((char *)name, (char *)password, &reenter, 181efcad6b7SDag-Erling Smørgrav &authmsg); 182efcad6b7SDag-Erling Smørgrav aix_remove_embedded_newlines(authmsg); 183043840dfSDag-Erling Smørgrav debug3("AIX/authenticate result %d, authmsg %.100s", result, 184efcad6b7SDag-Erling Smørgrav authmsg); 185efcad6b7SDag-Erling Smørgrav } while (reenter); 186efcad6b7SDag-Erling Smørgrav 1875e8dbd04SDag-Erling Smørgrav if (!aix_valid_authentications(name)) 1885e8dbd04SDag-Erling Smørgrav result = -1; 1895e8dbd04SDag-Erling Smørgrav 190efcad6b7SDag-Erling Smørgrav if (result == 0) { 191efcad6b7SDag-Erling Smørgrav authsuccess = 1; 192efcad6b7SDag-Erling Smørgrav 193efcad6b7SDag-Erling Smørgrav /* 194efcad6b7SDag-Erling Smørgrav * Record successful login. We don't have a pty yet, so just 195efcad6b7SDag-Erling Smørgrav * label the line as "ssh" 196efcad6b7SDag-Erling Smørgrav */ 197efcad6b7SDag-Erling Smørgrav aix_setauthdb(name); 198efcad6b7SDag-Erling Smørgrav 199efcad6b7SDag-Erling Smørgrav /* 200efcad6b7SDag-Erling Smørgrav * Check if the user's password is expired. 201efcad6b7SDag-Erling Smørgrav */ 202efcad6b7SDag-Erling Smørgrav expired = passwdexpired(name, &msg); 203efcad6b7SDag-Erling Smørgrav if (msg && *msg) { 2044518870cSDag-Erling Smørgrav buffer_append(ctxt->loginmsg, msg, strlen(msg)); 205efcad6b7SDag-Erling Smørgrav aix_remove_embedded_newlines(msg); 206efcad6b7SDag-Erling Smørgrav } 207efcad6b7SDag-Erling Smørgrav debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); 208efcad6b7SDag-Erling Smørgrav 209efcad6b7SDag-Erling Smørgrav switch (expired) { 210efcad6b7SDag-Erling Smørgrav case 0: /* password not expired */ 211efcad6b7SDag-Erling Smørgrav break; 212efcad6b7SDag-Erling Smørgrav case 1: /* expired, password change required */ 213efcad6b7SDag-Erling Smørgrav ctxt->force_pwchange = 1; 214efcad6b7SDag-Erling Smørgrav break; 215efcad6b7SDag-Erling Smørgrav default: /* user can't change(2) or other error (-1) */ 216efcad6b7SDag-Erling Smørgrav logit("Password can't be changed for user %s: %.100s", 217efcad6b7SDag-Erling Smørgrav name, msg); 218efcad6b7SDag-Erling Smørgrav if (msg) 219efcad6b7SDag-Erling Smørgrav xfree(msg); 220efcad6b7SDag-Erling Smørgrav authsuccess = 0; 221efcad6b7SDag-Erling Smørgrav } 222efcad6b7SDag-Erling Smørgrav 223efcad6b7SDag-Erling Smørgrav aix_restoreauthdb(); 224efcad6b7SDag-Erling Smørgrav } 225efcad6b7SDag-Erling Smørgrav 226efcad6b7SDag-Erling Smørgrav if (authmsg != NULL) 227efcad6b7SDag-Erling Smørgrav xfree(authmsg); 228efcad6b7SDag-Erling Smørgrav 229efcad6b7SDag-Erling Smørgrav return authsuccess; 230efcad6b7SDag-Erling Smørgrav } 231d95e11bfSDag-Erling Smørgrav 232d74d50a8SDag-Erling Smørgrav /* 233d74d50a8SDag-Erling Smørgrav * Check if specified account is permitted to log in. 234d74d50a8SDag-Erling Smørgrav * Returns 1 if login is allowed, 0 if not allowed. 235d74d50a8SDag-Erling Smørgrav */ 236d74d50a8SDag-Erling Smørgrav int 2375e8dbd04SDag-Erling Smørgrav sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) 238d74d50a8SDag-Erling Smørgrav { 239d74d50a8SDag-Erling Smørgrav char *msg = NULL; 240d74d50a8SDag-Erling Smørgrav int result, permitted = 0; 241d74d50a8SDag-Erling Smørgrav struct stat st; 242d74d50a8SDag-Erling Smørgrav 243d74d50a8SDag-Erling Smørgrav /* 244d74d50a8SDag-Erling Smørgrav * Don't perform checks for root account (PermitRootLogin controls 245d4af9e69SDag-Erling Smørgrav * logins via ssh) or if running as non-root user (since 246d74d50a8SDag-Erling Smørgrav * loginrestrictions will always fail due to insufficient privilege). 247d74d50a8SDag-Erling Smørgrav */ 248d74d50a8SDag-Erling Smørgrav if (pw->pw_uid == 0 || geteuid() != 0) { 249d74d50a8SDag-Erling Smørgrav debug3("%s: not checking", __func__); 250d74d50a8SDag-Erling Smørgrav return 1; 251d74d50a8SDag-Erling Smørgrav } 252d74d50a8SDag-Erling Smørgrav 253d74d50a8SDag-Erling Smørgrav result = loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg); 254d74d50a8SDag-Erling Smørgrav if (result == 0) 255d74d50a8SDag-Erling Smørgrav permitted = 1; 256d74d50a8SDag-Erling Smørgrav /* 257d74d50a8SDag-Erling Smørgrav * If restricted because /etc/nologin exists, the login will be denied 258d74d50a8SDag-Erling Smørgrav * in session.c after the nologin message is sent, so allow for now 259d74d50a8SDag-Erling Smørgrav * and do not append the returned message. 260d74d50a8SDag-Erling Smørgrav */ 261d74d50a8SDag-Erling Smørgrav if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) 262d74d50a8SDag-Erling Smørgrav permitted = 1; 263d74d50a8SDag-Erling Smørgrav else if (msg != NULL) 2645e8dbd04SDag-Erling Smørgrav buffer_append(loginmsg, msg, strlen(msg)); 265d74d50a8SDag-Erling Smørgrav if (msg == NULL) 266d74d50a8SDag-Erling Smørgrav msg = xstrdup("(none)"); 267d74d50a8SDag-Erling Smørgrav aix_remove_embedded_newlines(msg); 268d74d50a8SDag-Erling Smørgrav debug3("AIX/loginrestrictions returned %d msg %.100s", result, msg); 269d74d50a8SDag-Erling Smørgrav 270d74d50a8SDag-Erling Smørgrav if (!permitted) 271d74d50a8SDag-Erling Smørgrav logit("Login restricted for %s: %.100s", pw->pw_name, msg); 272d74d50a8SDag-Erling Smørgrav xfree(msg); 273d74d50a8SDag-Erling Smørgrav return permitted; 274d74d50a8SDag-Erling Smørgrav } 275d74d50a8SDag-Erling Smørgrav 276d74d50a8SDag-Erling Smørgrav int 2775e8dbd04SDag-Erling Smørgrav sys_auth_record_login(const char *user, const char *host, const char *ttynm, 2785e8dbd04SDag-Erling Smørgrav Buffer *loginmsg) 279d74d50a8SDag-Erling Smørgrav { 280043840dfSDag-Erling Smørgrav char *msg = NULL; 281d74d50a8SDag-Erling Smørgrav int success = 0; 282d74d50a8SDag-Erling Smørgrav 283d74d50a8SDag-Erling Smørgrav aix_setauthdb(user); 2845e8dbd04SDag-Erling Smørgrav if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) { 285d74d50a8SDag-Erling Smørgrav success = 1; 2867aee6ffeSDag-Erling Smørgrav if (msg != NULL) { 2875e8dbd04SDag-Erling Smørgrav debug("AIX/loginsuccess: msg %s", msg); 2887aee6ffeSDag-Erling Smørgrav if (lastlogin_msg == NULL) 2897aee6ffeSDag-Erling Smørgrav lastlogin_msg = msg; 290d74d50a8SDag-Erling Smørgrav } 291d74d50a8SDag-Erling Smørgrav } 292d74d50a8SDag-Erling Smørgrav aix_restoreauthdb(); 293d74d50a8SDag-Erling Smørgrav return (success); 294d74d50a8SDag-Erling Smørgrav } 295d74d50a8SDag-Erling Smørgrav 2967aee6ffeSDag-Erling Smørgrav char * 2977aee6ffeSDag-Erling Smørgrav sys_auth_get_lastlogin_msg(const char *user, uid_t uid) 2987aee6ffeSDag-Erling Smørgrav { 2997aee6ffeSDag-Erling Smørgrav char *msg = lastlogin_msg; 3007aee6ffeSDag-Erling Smørgrav 3017aee6ffeSDag-Erling Smørgrav lastlogin_msg = NULL; 3027aee6ffeSDag-Erling Smørgrav return msg; 3037aee6ffeSDag-Erling Smørgrav } 3047aee6ffeSDag-Erling Smørgrav 305d95e11bfSDag-Erling Smørgrav # ifdef CUSTOM_FAILED_LOGIN 306d95e11bfSDag-Erling Smørgrav /* 307d95e11bfSDag-Erling Smørgrav * record_failed_login: generic "login failed" interface function 308d95e11bfSDag-Erling Smørgrav */ 309d95e11bfSDag-Erling Smørgrav void 3105e8dbd04SDag-Erling Smørgrav record_failed_login(const char *user, const char *hostname, const char *ttyname) 311d95e11bfSDag-Erling Smørgrav { 312d95e11bfSDag-Erling Smørgrav if (geteuid() != 0) 313d95e11bfSDag-Erling Smørgrav return; 314d95e11bfSDag-Erling Smørgrav 315d95e11bfSDag-Erling Smørgrav aix_setauthdb(user); 316d95e11bfSDag-Erling Smørgrav # ifdef AIX_LOGINFAILED_4ARG 3175e8dbd04SDag-Erling Smørgrav loginfailed((char *)user, (char *)hostname, (char *)ttyname, 3185e8dbd04SDag-Erling Smørgrav AUDIT_FAIL_AUTH); 319d95e11bfSDag-Erling Smørgrav # else 3205e8dbd04SDag-Erling Smørgrav loginfailed((char *)user, (char *)hostname, (char *)ttyname); 321d95e11bfSDag-Erling Smørgrav # endif 322efcad6b7SDag-Erling Smørgrav aix_restoreauthdb(); 323d95e11bfSDag-Erling Smørgrav } 324efcad6b7SDag-Erling Smørgrav # endif /* CUSTOM_FAILED_LOGIN */ 325d95e11bfSDag-Erling Smørgrav 326d95e11bfSDag-Erling Smørgrav /* 327d95e11bfSDag-Erling Smørgrav * If we have setauthdb, retrieve the password registry for the user's 328efcad6b7SDag-Erling Smørgrav * account then feed it to setauthdb. This will mean that subsequent AIX auth 329efcad6b7SDag-Erling Smørgrav * functions will only use the specified loadable module. If we don't have 330efcad6b7SDag-Erling Smørgrav * setauthdb this is a no-op. 331d95e11bfSDag-Erling Smørgrav */ 332d95e11bfSDag-Erling Smørgrav void 333d95e11bfSDag-Erling Smørgrav aix_setauthdb(const char *user) 334d95e11bfSDag-Erling Smørgrav { 335d95e11bfSDag-Erling Smørgrav # ifdef HAVE_SETAUTHDB 336efcad6b7SDag-Erling Smørgrav char *registry; 337d95e11bfSDag-Erling Smørgrav 338d95e11bfSDag-Erling Smørgrav if (setuserdb(S_READ) == -1) { 339d95e11bfSDag-Erling Smørgrav debug3("%s: Could not open userdb to read", __func__); 340d95e11bfSDag-Erling Smørgrav return; 341d95e11bfSDag-Erling Smørgrav } 342d95e11bfSDag-Erling Smørgrav 343d95e11bfSDag-Erling Smørgrav if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { 344efcad6b7SDag-Erling Smørgrav if (setauthdb(registry, old_registry) == 0) 345efcad6b7SDag-Erling Smørgrav debug3("AIX/setauthdb set registry '%s'", registry); 346d95e11bfSDag-Erling Smørgrav else 347efcad6b7SDag-Erling Smørgrav debug3("AIX/setauthdb set registry '%s' failed: %s", 348efcad6b7SDag-Erling Smørgrav registry, strerror(errno)); 349d95e11bfSDag-Erling Smørgrav } else 350d95e11bfSDag-Erling Smørgrav debug3("%s: Could not read S_REGISTRY for user: %s", __func__, 351d95e11bfSDag-Erling Smørgrav strerror(errno)); 352d95e11bfSDag-Erling Smørgrav enduserdb(); 353efcad6b7SDag-Erling Smørgrav # endif /* HAVE_SETAUTHDB */ 354d95e11bfSDag-Erling Smørgrav } 35583d2307dSDag-Erling Smørgrav 356efcad6b7SDag-Erling Smørgrav /* 357efcad6b7SDag-Erling Smørgrav * Restore the user's registry settings from old_registry. 358efcad6b7SDag-Erling Smørgrav * Note that if the first aix_setauthdb fails, setauthdb("") is still safe 359efcad6b7SDag-Erling Smørgrav * (it restores the system default behaviour). If we don't have setauthdb, 360efcad6b7SDag-Erling Smørgrav * this is a no-op. 361efcad6b7SDag-Erling Smørgrav */ 362efcad6b7SDag-Erling Smørgrav void 363efcad6b7SDag-Erling Smørgrav aix_restoreauthdb(void) 364efcad6b7SDag-Erling Smørgrav { 365efcad6b7SDag-Erling Smørgrav # ifdef HAVE_SETAUTHDB 366efcad6b7SDag-Erling Smørgrav if (setauthdb(old_registry, NULL) == 0) 367efcad6b7SDag-Erling Smørgrav debug3("%s: restoring old registry '%s'", __func__, 368efcad6b7SDag-Erling Smørgrav old_registry); 369efcad6b7SDag-Erling Smørgrav else 370efcad6b7SDag-Erling Smørgrav debug3("%s: failed to restore old registry %s", __func__, 371efcad6b7SDag-Erling Smørgrav old_registry); 372efcad6b7SDag-Erling Smørgrav # endif /* HAVE_SETAUTHDB */ 373efcad6b7SDag-Erling Smørgrav } 374efcad6b7SDag-Erling Smørgrav 375efcad6b7SDag-Erling Smørgrav # endif /* WITH_AIXAUTHENTICATE */ 376efcad6b7SDag-Erling Smørgrav 3775e8dbd04SDag-Erling Smørgrav # if defined(AIX_GETNAMEINFO_HACK) && !defined(BROKEN_ADDRINFO) 3785e8dbd04SDag-Erling Smørgrav # undef getnameinfo 3795e8dbd04SDag-Erling Smørgrav /* 3805e8dbd04SDag-Erling Smørgrav * For some reason, AIX's getnameinfo will refuse to resolve the all-zeros 3815e8dbd04SDag-Erling Smørgrav * IPv6 address into its textual representation ("::"), so we wrap it 3825e8dbd04SDag-Erling Smørgrav * with a function that will. 3835e8dbd04SDag-Erling Smørgrav */ 3845e8dbd04SDag-Erling Smørgrav int 3855e8dbd04SDag-Erling Smørgrav sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 3865e8dbd04SDag-Erling Smørgrav size_t hostlen, char *serv, size_t servlen, int flags) 3875e8dbd04SDag-Erling Smørgrav { 3885e8dbd04SDag-Erling Smørgrav struct sockaddr_in6 *sa6; 3895e8dbd04SDag-Erling Smørgrav u_int32_t *a6; 3905e8dbd04SDag-Erling Smørgrav 3915e8dbd04SDag-Erling Smørgrav if (flags & (NI_NUMERICHOST|NI_NUMERICSERV) && 3925e8dbd04SDag-Erling Smørgrav sa->sa_family == AF_INET6) { 3935e8dbd04SDag-Erling Smørgrav sa6 = (struct sockaddr_in6 *)sa; 3945e8dbd04SDag-Erling Smørgrav a6 = sa6->sin6_addr.u6_addr.u6_addr32; 3955e8dbd04SDag-Erling Smørgrav 3965e8dbd04SDag-Erling Smørgrav if (a6[0] == 0 && a6[1] == 0 && a6[2] == 0 && a6[3] == 0) { 3975e8dbd04SDag-Erling Smørgrav strlcpy(host, "::", hostlen); 3985e8dbd04SDag-Erling Smørgrav snprintf(serv, servlen, "%d", sa6->sin6_port); 3995e8dbd04SDag-Erling Smørgrav return 0; 4005e8dbd04SDag-Erling Smørgrav } 4015e8dbd04SDag-Erling Smørgrav } 4025e8dbd04SDag-Erling Smørgrav return getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); 4035e8dbd04SDag-Erling Smørgrav } 4045e8dbd04SDag-Erling Smørgrav # endif /* AIX_GETNAMEINFO_HACK */ 4055e8dbd04SDag-Erling Smørgrav 406d4af9e69SDag-Erling Smørgrav # if defined(USE_GETGRSET) 407d4af9e69SDag-Erling Smørgrav # include <stdlib.h> 408d4af9e69SDag-Erling Smørgrav int 409d4af9e69SDag-Erling Smørgrav getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt) 410d4af9e69SDag-Erling Smørgrav { 411d4af9e69SDag-Erling Smørgrav char *cp, *grplist, *grp; 412d4af9e69SDag-Erling Smørgrav gid_t gid; 413d4af9e69SDag-Erling Smørgrav int ret = 0, ngroups = 0, maxgroups; 414d4af9e69SDag-Erling Smørgrav long l; 415d4af9e69SDag-Erling Smørgrav 416d4af9e69SDag-Erling Smørgrav maxgroups = *grpcnt; 417d4af9e69SDag-Erling Smørgrav 418d4af9e69SDag-Erling Smørgrav if ((cp = grplist = getgrset(user)) == NULL) 419d4af9e69SDag-Erling Smørgrav return -1; 420d4af9e69SDag-Erling Smørgrav 421d4af9e69SDag-Erling Smørgrav /* handle zero-length case */ 422d4af9e69SDag-Erling Smørgrav if (maxgroups <= 0) { 423d4af9e69SDag-Erling Smørgrav *grpcnt = 0; 424d4af9e69SDag-Erling Smørgrav return -1; 425d4af9e69SDag-Erling Smørgrav } 426d4af9e69SDag-Erling Smørgrav 427d4af9e69SDag-Erling Smørgrav /* copy primary group */ 428d4af9e69SDag-Erling Smørgrav groups[ngroups++] = pgid; 429d4af9e69SDag-Erling Smørgrav 430d4af9e69SDag-Erling Smørgrav /* copy each entry from getgrset into group list */ 431d4af9e69SDag-Erling Smørgrav while ((grp = strsep(&grplist, ",")) != NULL) { 432d4af9e69SDag-Erling Smørgrav l = strtol(grp, NULL, 10); 433d4af9e69SDag-Erling Smørgrav if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) { 434d4af9e69SDag-Erling Smørgrav ret = -1; 435d4af9e69SDag-Erling Smørgrav goto out; 436d4af9e69SDag-Erling Smørgrav } 437d4af9e69SDag-Erling Smørgrav gid = (gid_t)l; 438d4af9e69SDag-Erling Smørgrav if (gid == pgid) 439d4af9e69SDag-Erling Smørgrav continue; /* we have already added primary gid */ 440d4af9e69SDag-Erling Smørgrav groups[ngroups++] = gid; 441d4af9e69SDag-Erling Smørgrav } 442d4af9e69SDag-Erling Smørgrav out: 443d4af9e69SDag-Erling Smørgrav free(cp); 444d4af9e69SDag-Erling Smørgrav *grpcnt = ngroups; 445d4af9e69SDag-Erling Smørgrav return ret; 446d4af9e69SDag-Erling Smørgrav } 447d4af9e69SDag-Erling Smørgrav # endif /* USE_GETGRSET */ 448d4af9e69SDag-Erling Smørgrav 449efcad6b7SDag-Erling Smørgrav #endif /* _AIX */ 450