/* * If we have setauthdb, retrieve the password registry for the user's * account then feed it to setauthdb. This may load registry-specific method * code. If we don't have setauthdb or have already called it this is a no-op. */ void aix_setauthdb(const char *user) { # ifdef HAVE_SETAUTHDB static char *registry = NULL; if (registry != NULL) /* have already done setauthdb */ return; if (setuserdb(S_READ) == -1) { debug3("%s: Could not open userdb to read", __func__); return; } if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { if (setauthdb(registry, NULL) == 0) debug3("%s: AIX/setauthdb set registry %s", __func__, registry); else debug3("%s: AIX/setauthdb set registry %s failed: %s", __func__, registry, strerror(errno)); } else debug3("%s: Could not read S_REGISTRY for user: %s", __func__, strerror(errno)); enduserdb(); # endif }
/* * aix_krb5_get_principal_name: returns the user's kerberos client principal name if * configured, otherwise NULL. Caller must free returned string. */ char * aix_krb5_get_principal_name(char *pw_name) { char *authname = NULL, *authdomain = NULL, *principal = NULL; setuserdb(S_READ); if (getuserattr(pw_name, S_AUTHDOMAIN, &authdomain, SEC_CHAR) != 0) debug("AIX getuserattr S_AUTHDOMAIN: %s", strerror(errno)); if (getuserattr(pw_name, S_AUTHNAME, &authname, SEC_CHAR) != 0) debug("AIX getuserattr S_AUTHNAME: %s", strerror(errno)); if (authdomain != NULL) xasprintf(&principal, "%s@%s", authname ? authname : pw_name, authdomain); else if (authname != NULL) principal = xstrdup(authname); enduserdb(); return principal; }
/* * If we have setauthdb, retrieve the password registry for the user's * account then feed it to setauthdb. This will mean that subsequent AIX auth * functions will only use the specified loadable module. If we don't have * setauthdb this is a no-op. */ void aix_setauthdb(const char *user) { # ifdef HAVE_SETAUTHDB char *registry; if (setuserdb(S_READ) == -1) { debug3("%s: Could not open userdb to read", __func__); return; } if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { if (setauthdb(registry, old_registry) == 0) debug3("AIX/setauthdb set registry '%s'", registry); else debug3("AIX/setauthdb set registry '%s' failed: %s", registry, strerror(errno)); } else debug3("%s: Could not read S_REGISTRY for user: %s", __func__, strerror(errno)); enduserdb(); # endif /* HAVE_SETAUTHDB */ }
Boolean ssh_login_permitted(const char *user, SshUser uc) { char passwd[20]; /* Only for account lock check */ strncpy(passwd, uc->correct_encrypted_passwd, sizeof(passwd)); passwd[sizeof(passwd) - 1] = '\0'; #ifdef HAVE_USERSEC_H { char *expiration, current_time[100], normalized[100]; int rlogin_permitted; ssh_time t; struct SshCalendarTimeRec tm[1]; int account_is_locked; if (setuserdb(S_READ) < 0) { if (getuid() == 0) /* It's OK to fail here if we are not root */ { SSH_DEBUG(2, ("setuserdb S_READ failed: %.200s.", strerror(errno))); } return FALSE; } if (getuserattr((char *)user, S_RLOGINCHK, &rlogin_permitted, SEC_BOOL) < 0) { if (getuid() == 0) /* It's OK to fail here if we are not root */ { SSH_DEBUG(2, ("getuserattr S_RLOGINCHK failed: %.200s", strerror(errno))); } enduserdb(); return FALSE; } if (getuserattr((char *)user, S_EXPIRATION, &expiration, SEC_CHAR) < 0) { SSH_DEBUG(2, ("getuserattr S_EXPIRATION failed: %.200s.", strerror(errno))); enduserdb(); return FALSE; } #ifdef S_LOCKED if (getuserattr(user, S_LOCKED, &account_is_locked, SEC_BOOL) < 0) { SSH_DEBUG(2, ("getuserattr S_LOCKED failed: %.200s.", strerror(errno))); enduserdb(); return FALSE; } if (account_is_locked) { SSH_DEBUG(2, ("Account %.100s is locked.", user)); enduserdb(); return FALSE; } #endif /* S_LOCKED */ if (!rlogin_permitted) { SSH_DEBUG(2, ("Remote logins to account %.100s not permitted by " "user profile.", user)); enduserdb(); return FALSE; } if (strcmp(expiration, "0") == 0) { /* The account does not expire - return success immediately. */ enduserdb(); return TRUE; } if (strlen(expiration) != 10) { SSH_DEBUG(2, ("Account %.100s expiration date is in wrong format.", user)); enduserdb(); return FALSE; } t = ssh_time(); ssh_calendar_time(t, tm, TRUE); snprintf(current_time, sizeof(current_time), "%04d%02d%02d%02d%02d", tm->year, tm->month + 1, tm->monthday, tm->hour, tm->minute); if (expiration[8] < '7') /* Assume year < 70 is 20YY. */ strcpy(normalized, "20"); else strcpy(normalized, "19"); strcat(normalized, expiration + 8); strcat(normalized, expiration); normalized[12] = '\0'; if (strcmp(normalized, current_time) < 0) { SSH_DEBUG(2, ("Account %.100s has expired - access denied.", user)); enduserdb(); return FALSE; } enduserdb(); } #endif /* HAVE_USERSEC_H */ #ifdef HAVE_ETC_SHADOW { struct spwd *sp; sp = (struct spwd *)getspnam(user); #if defined(SECURE_RPC) && defined(NIS_PLUS) if (geteuid() == UID_ROOT && ssh_user_uid(uc) != UID_ROOT && (!sp || !sp->sp_pwdp || !strcmp(sp->sp_pwdp,"*NP*"))) { if (seteuid(ssh_user_uid(uc)) >= 0) { sp = getspnam(user); /* retry as user */ seteuid(UID_ROOT); } } #endif /* SECURE_RPC && NIS_PLUS */ if (!sp) { /* * Some systems, e.g.: IRIX, may or may not have /etc/shadow. * Just check if there is one. If such system is also an YP * client, then valid password might already be present in passwd * structure. Just check if it's other than "x". Assume that * YP server is always right if this is the case. * [email protected] */ struct stat sbf; if ((stat(SHADOW, &sbf) == 0) && strcmp(uc->correct_encrypted_passwd, "x") == 0) { SSH_DEBUG(2, ("Can't find %.100s's shadow - access denied.", user)); endspent(); return FALSE; } } else { SshTime today = ssh_time()/24/60/60; /* what a day! */ #ifdef HAVE_STRUCT_SPWD_EXPIRE /* Check for expiration date */ if (sp->sp_expire > 0 && today > sp->sp_expire) { SSH_DEBUG(2, ("Account %.100s has expired - access denied.", user)); endspent(); return FALSE; } #endif #ifdef HAVE_STRUCT_SPWD_INACT /* Check for last login */ if (sp->sp_inact > 0) { char buf[64]; SshTime llt; llt = ssh_user_get_last_login_time(uc, buf, sizeof(buf)); if (llt && (today - llt/24/60/60) > sp->sp_inact) { SSH_DEBUG(2, ("Account %.100s was inactive for more than %d days.", user, sp->sp_inact)); endspent(); return FALSE; } } #endif /* Check if password is valid */ if (sp->sp_lstchg == 0 || (sp->sp_max > 0 && today > sp->sp_lstchg + sp->sp_max)) { SSH_DEBUG(2, ("Account %.100s's password is too old - forced to change.", user)); uc->password_needs_change = TRUE; } strncpy(passwd, sp->sp_pwdp, sizeof(passwd)); passwd[sizeof(passwd) - 1] = '\0'; } endspent(); } #endif /* HAVE_ETC_SHADOW */ /* * Check if account is locked. Check if encrypted password starts * with "*LK*". */ { if (strncmp(passwd,"*LK*", 4) == 0) { SSH_DEBUG(2, ("Account %.100s is locked.", user)); return FALSE; } } #ifdef CHECK_ETC_SHELLS { int invalid = 1; char *shell = pwd->pw_shell, *etc_shell, *getusershell(); if (!shell || !*shell) shell = DEFAULT_SHELL; while (invalid && (etc_shell = getusershell())) invalid = strcmp(etc_shell, shell); endusershell(); if (invalid) { SSH_DEBUG(2, ("Account %.100s doesn't have valid shell", user)); return FALSE; } } #endif /* CHECK_ETC_SHELLS */ return TRUE; }