/* * Do authentication via AIX's authenticate routine. We loop until the * reenter parameter is 0, but normally authenticate is called only once. * * Note: this function returns 1 on success, whereas AIX's authenticate() * returns 0. */ int sys_auth_passwd(Authctxt *ctxt, const char *password) { char *authmsg = NULL, *msg = NULL, *name = ctxt->pw->pw_name; int authsuccess = 0, expired, reenter, result; do { result = authenticate((char *)name, (char *)password, &reenter, &authmsg); aix_remove_embedded_newlines(authmsg); debug3("AIX/authenticate result %d, authmsg %.100s", result, authmsg); } while (reenter); if (!aix_valid_authentications(name)) result = -1; if (result == 0) { authsuccess = 1; /* * Record successful login. We don't have a pty yet, so just * label the line as "ssh" */ aix_setauthdb(name); /* * Check if the user's password is expired. */ expired = passwdexpired(name, &msg); if (msg && *msg) { buffer_append(ctxt->loginmsg, msg, strlen(msg)); aix_remove_embedded_newlines(msg); } debug3("AIX/passwdexpired returned %d msg %.100s", expired, msg); switch (expired) { case 0: /* password not expired */ break; case 1: /* expired, password change required */ ctxt->force_pwchange = 1; break; default: /* user can't change(2) or other error (-1) */ logit("Password can't be changed for user %s: %.100s", name, msg); if (msg) xfree(msg); authsuccess = 0; } aix_restoreauthdb(); } if (authmsg != NULL) xfree(authmsg); return authsuccess; }
/* * Check if specified account is permitted to log in. * Returns 1 if login is allowed, 0 if not allowed. */ int sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) { char *msg = NULL; int result, permitted = 0; struct stat st; /* * Don't perform checks for root account (PermitRootLogin controls * logins via ssh) or if running as non-root user (since * loginrestrictions will always fail due to insufficient privilege). */ if (pw->pw_uid == 0 || geteuid() != 0) { debug3("%s: not checking", __func__); return 1; } result = loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg); if (result == 0) permitted = 1; /* * If restricted because /etc/nologin exists, the login will be denied * in session.c after the nologin message is sent, so allow for now * and do not append the returned message. */ if (result == -1 && errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0) permitted = 1; else if (msg != NULL) buffer_append(loginmsg, msg, strlen(msg)); if (msg == NULL) msg = xstrdup("(none)"); aix_remove_embedded_newlines(msg); debug3("AIX/loginrestrictions returned %d msg %.100s", result, msg); if (!permitted) logit("Login restricted for %s: %.100s", pw->pw_name, msg); xfree(msg); return permitted; }
/* * Check if the user is allowed to log in via ssh. If user is listed * in DenyUsers or one of user's groups is listed in DenyGroups, false * will be returned. If AllowUsers isn't empty and user isn't listed * there, or if AllowGroups isn't empty and one of user's groups isn't * listed there, false will be returned. * If the user's shell is not executable, false will be returned. * Otherwise true is returned. */ int allowed_user(struct passwd * pw) { struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; char *shell; int i; #ifdef USE_SHADOW struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; #ifdef USE_SHADOW if (!options.use_pam) spw = getspnam(pw->pw_name); #ifdef HAS_SHADOW_EXPIRE if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) return 0; #endif /* HAS_SHADOW_EXPIRE */ #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ #ifdef USE_SHADOW if (spw != NULL) passwd = spw->sp_pwdp; #else passwd = pw->pw_passwd; #endif /* check for locked account */ if (!options.use_pam && passwd && *passwd) { int locked = 0; #ifdef LOCKED_PASSWD_STRING if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_PREFIX if (strncmp(passwd, LOCKED_PASSWD_PREFIX, strlen(LOCKED_PASSWD_PREFIX)) == 0) locked = 1; #endif #ifdef LOCKED_PASSWD_SUBSTR if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); return 0; } } /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { logit("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { logit("User %.100s not allowed because shell %.100s is not executable", pw->pw_name, shell); return 0; } if (options.num_deny_users > 0 || options.num_allow_users > 0) { hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { logit("User %.100s not allowed because listed in DenyUsers", pw->pw_name); return 0; } } /* Return false if AllowUsers isn't empty and user isn't listed there */ if (options.num_allow_users > 0) { for (i = 0; i < options.num_allow_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i])) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { logit("User %.100s not allowed because not listed in AllowUsers", pw->pw_name); return 0; } } if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { /* Get the user's group access list (primary and supplementary) */ if (ga_init(pw->pw_name, pw->pw_gid) == 0) { logit("User %.100s not allowed because not in any group", pw->pw_name); return 0; } /* Return false if one of user's groups is listed in DenyGroups */ if (options.num_deny_groups > 0) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); logit("User %.100s not allowed because a group is listed in DenyGroups", pw->pw_name); return 0; } /* * Return false if AllowGroups isn't empty and one of user's groups * isn't listed there */ if (options.num_allow_groups > 0) if (!ga_match(options.allow_groups, options.num_allow_groups)) { ga_free(); logit("User %.100s not allowed because none of user's groups are listed in AllowGroups", pw->pw_name); return 0; } ga_free(); } #ifdef WITH_AIXAUTHENTICATE /* * Don't check loginrestrictions() for root account (use * PermitRootLogin to control logins via ssh), or if running as * non-root user (since loginrestrictions will always fail). */ if ((pw->pw_uid != 0) && (geteuid() == 0)) { char *msg; if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) { int loginrestrict_errno = errno; if (msg && *msg) { buffer_append(&loginmsg, msg, strlen(msg)); aix_remove_embedded_newlines(msg); logit("Login restricted for %s: %.100s", pw->pw_name, msg); } /* Don't fail if /etc/nologin set */ if (!(loginrestrict_errno == EPERM && stat(_PATH_NOLOGIN, &st) == 0)) return 0; } } #endif /* WITH_AIXAUTHENTICATE */ /* We found no reason not to let this user try to log on... */ return 1; }
/* * Tries to authenticate the user using password. Returns true if * authentication succeeds. */ int auth_password(Authctxt *authctxt, const char *password) { struct passwd * pw = authctxt->pw; int ok = authctxt->valid; /* deny if no user. */ if (pw == NULL) return 0; #ifndef HAVE_CYGWIN if (pw && pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) ok = 0; #endif if (*password == '\0' && options.permit_empty_passwd == 0) return 0; #if defined(HAVE_OSF_SIA) return auth_sia_password(authctxt, password) && ok; #else # ifdef KRB5 if (options.kerberos_authentication == 1) { int ret = auth_krb5_password(authctxt, password); if (ret == 1 || ret == 0) return ret && ok; /* Fall back to ordinary passwd authentication. */ } # endif # ifdef HAVE_CYGWIN if (is_winnt) { HANDLE hToken = cygwin_logon_user(pw, password); if (hToken == INVALID_HANDLE_VALUE) return 0; cygwin_set_impersonation_token(hToken); return ok; } # endif # ifdef WITH_AIXAUTHENTICATE { char *authmsg = NULL; int reenter = 1; int authsuccess = 0; if (authenticate(pw->pw_name, password, &reenter, &authmsg) == 0 && ok) { char *msg; char *host = (char *)get_canonical_hostname(options.use_dns); authsuccess = 1; aix_remove_embedded_newlines(authmsg); debug3("AIX/authenticate succeeded for user %s: %.100s", pw->pw_name, authmsg); /* No pty yet, so just label the line as "ssh" */ aix_setauthdb(authctxt->user); if (loginsuccess(authctxt->user, host, "ssh", &msg) == 0) { if (msg != NULL) { debug("%s: msg %s", __func__, msg); buffer_append(&loginmsg, msg, strlen(msg)); xfree(msg); } } } else { debug3("AIX/authenticate failed for user %s: %.100s", pw->pw_name, authmsg); } if (authmsg != NULL) xfree(authmsg); return authsuccess; } # endif # ifdef BSD_AUTH if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", (char *)password) == 0) return 0; else return ok; # else { /* Just use the supplied fake password if authctxt is invalid */ char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; /* Check for users with no password. */ if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) return ok; else { /* Encrypt the candidate password using the proper salt. */ char *encrypted_password = xcrypt(password, (pw_password[0] && pw_password[1]) ? pw_password : "******"); /* * Authentication is accepted if the encrypted passwords * are identical. */ return (strcmp(encrypted_password, pw_password) == 0) && ok; } } # endif #endif /* !HAVE_OSF_SIA */ }