-/* $OpenBSD: auth-passwd.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
*/
#include "includes.h"
+RCSID("$OpenBSD: auth-passwd.c,v 1.23 2001/06/26 16:15:23 dugsong Exp $");
-#include <sys/types.h>
-
-#include <pwd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
+#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
#include "packet.h"
-#include "buffer.h"
+#include "xmalloc.h"
#include "log.h"
#include "servconf.h"
-#include "key.h"
-#include "hostfile.h"
#include "auth.h"
-#include "auth-options.h"
-
-extern Buffer loginmsg;
-extern ServerOptions options;
-#ifdef HAVE_LOGIN_CAP
-extern login_cap_t *lc;
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#endif
+#ifdef WITH_AIXAUTHENTICATE
+# include <login.h>
+#endif
+#ifdef __hpux
+# include <hpsecurity.h>
+# include <prot.h>
+#endif
+#ifdef HAVE_SCO_PROTECTED_PW
+# include <sys/security.h>
+# include <sys/audit.h>
+# include <prot.h>
+#endif /* HAVE_SCO_PROTECTED_PW */
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+# include <shadow.h>
+#endif
+#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
+# include <sys/label.h>
+# include <sys/audit.h>
+# include <pwdadj.h>
#endif
+#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT)
+# include "md5crypt.h"
+#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */
+#ifdef HAVE_CYGWIN
+#undef ERROR
+#include <windows.h>
+#include <sys/cygwin.h>
+#define is_winnt (GetVersion() < 0x80000000)
+#endif
-#define DAY (24L * 60 * 60) /* 1 day in seconds */
-#define TWO_WEEKS (2L * 7 * DAY) /* 2 weeks in seconds */
-void
-disable_forwarding(void)
-{
- no_port_forwarding_flag = 1;
- no_agent_forwarding_flag = 1;
- no_x11_forwarding_flag = 1;
-}
+extern ServerOptions options;
/*
* Tries to authenticate the user using password. Returns true if
auth_password(Authctxt *authctxt, const char *password)
{
struct passwd * pw = authctxt->pw;
- int result, ok = authctxt->valid;
-#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
- static int expire_checked = 0;
+ char *encrypted_password;
+ char *pw_password;
+ char *salt;
+#ifdef __hpux
+ struct pr_passwd *spw;
+#endif
+#ifdef HAVE_SCO_PROTECTED_PW
+ struct pr_passwd *spw;
+#endif /* HAVE_SCO_PROTECTED_PW */
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+ struct spwd *spw;
+#endif
+#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
+ struct passwd_adjunct *spw;
+#endif
+#ifdef WITH_AIXAUTHENTICATE
+ char *authmsg;
+ char *loginmsg;
+ int reenter = 1;
#endif
+ /* deny if no user. */
+ if (pw == NULL)
+ return 0;
#ifndef HAVE_CYGWIN
- if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
- ok = 0;
+ if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
+ return 0;
+#endif
+#ifdef HAVE_CYGWIN
+ /*
+ * Empty password is only possible on NT if the user has _really_
+ * an empty password and authentication is done, though.
+ */
+ if (!is_winnt)
#endif
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
-
#ifdef KRB5
if (options.kerberos_authentication == 1) {
int ret = auth_krb5_password(authctxt, password);
if (ret == 1 || ret == 0)
- return ret && ok;
+ return ret;
/* Fall back to ordinary passwd authentication. */
}
#endif
if (hToken == INVALID_HANDLE_VALUE)
return 0;
cygwin_set_impersonation_token(hToken);
- return ok;
+ return 1;
}
#endif
-#ifdef USE_PAM
- if (options.use_pam)
- return (sshpam_auth_passwd(authctxt, password) && ok);
+#ifdef WITH_AIXAUTHENTICATE
+ return (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
#endif
-#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
- if (!expire_checked) {
- expire_checked = 1;
- if (auth_shadow_pwexpired(authctxt))
- authctxt->force_pwchange = 1;
+#ifdef KRB4
+ if (options.kerberos_authentication == 1) {
+ int ret = auth_krb4_password(authctxt, password);
+ if (ret == 1 || ret == 0)
+ return ret;
+ /* Fall back to ordinary passwd authentication. */
}
#endif
- result = sys_auth_passwd(authctxt, password);
- if (authctxt->force_pwchange)
- disable_forwarding();
- return (result && ok);
-}
-
#ifdef BSD_AUTH
-static void
-warn_expiry(Authctxt *authctxt, auth_session_t *as)
-{
- char buf[256];
- quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
-
- pwwarntime = acwarntime = TWO_WEEKS;
-
- pwtimeleft = auth_check_change(as);
- actimeleft = auth_check_expire(as);
-#ifdef HAVE_LOGIN_CAP
- if (authctxt->valid) {
- pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS,
- TWO_WEEKS);
- acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS,
- TWO_WEEKS);
- }
+ if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
+ (char *)password) == 0)
+ return 0;
+ else
+ return 1;
#endif
- if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
- daysleft = pwtimeleft / DAY + 1;
- snprintf(buf, sizeof(buf),
- "Your password will expire in %lld day%s.\n",
- daysleft, daysleft == 1 ? "" : "s");
- buffer_append(&loginmsg, buf, strlen(buf));
- }
- if (actimeleft != 0 && actimeleft < acwarntime) {
- daysleft = actimeleft / DAY + 1;
- snprintf(buf, sizeof(buf),
- "Your account will expire in %lld day%s.\n",
- daysleft, daysleft == 1 ? "" : "s");
- buffer_append(&loginmsg, buf, strlen(buf));
- }
-}
-
-int
-sys_auth_passwd(Authctxt *authctxt, const char *password)
-{
- struct passwd *pw = authctxt->pw;
- auth_session_t *as;
- static int expire_checked = 0;
-
- as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
- (char *)password);
- if (as == NULL)
- return (0);
- if (auth_getstate(as) & AUTH_PWEXPIRED) {
- auth_close(as);
- disable_forwarding();
- authctxt->force_pwchange = 1;
- return (1);
- } else {
- if (!expire_checked) {
- expire_checked = 1;
- warn_expiry(authctxt, as);
- }
- return (auth_close(as));
- }
-}
-#elif !defined(CUSTOM_SYS_AUTH_PASSWD)
-int
-sys_auth_passwd(Authctxt *authctxt, const char *password)
-{
- struct passwd *pw = authctxt->pw;
- char *encrypted_password;
-
- /* 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 (1);
-
- /* Encrypt the candidate password using the proper salt. */
- encrypted_password = xcrypt(password,
- (pw_password[0] && pw_password[1]) ? pw_password : "xx");
+ pw_password = pw->pw_passwd;
/*
- * Authentication is accepted if the encrypted passwords
- * are identical.
+ * Various interfaces to shadow or protected password data
*/
+#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
+ spw = getspnam(pw->pw_name);
+ if (spw != NULL)
+ pw_password = spw->sp_pwdp;
+#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
+
+#ifdef HAVE_SCO_PROTECTED_PW
+ spw = getprpwnam(pw->pw_name);
+ if (spw != NULL)
+ pw_password = spw->ufld.fd_encrypt;
+#endif /* HAVE_SCO_PROTECTED_PW */
+
+#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
+ if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL)
+ pw_password = spw->pwa_passwd;
+#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */
+
+#if defined(__hpux)
+ if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL)
+ pw_password = spw->ufld.fd_encrypt;
+#endif /* defined(__hpux) */
+
+ /* Check for users with no password. */
+ if ((password[0] == '\0') && (pw_password[0] == '\0'))
+ return 1;
+
+ if (pw_password[0] != '\0')
+ salt = pw_password;
+ else
+ salt = "xx";
+
+#ifdef HAVE_MD5_PASSWORDS
+ if (is_md5_salt(salt))
+ encrypted_password = md5_crypt(password, salt);
+ else
+ encrypted_password = crypt(password, salt);
+#else /* HAVE_MD5_PASSWORDS */
+# ifdef __hpux
+ if (iscomsec())
+ encrypted_password = bigcrypt(password, salt);
+ else
+ encrypted_password = crypt(password, salt);
+# else
+ encrypted_password = crypt(password, salt);
+# endif /* __hpux */
+#endif /* HAVE_MD5_PASSWORDS */
+
+ /* Authentication is accepted if the encrypted passwords are identical. */
return (strcmp(encrypted_password, pw_password) == 0);
}
-#endif
+#endif /* !USE_PAM && !HAVE_OSF_SIA */