]> andersk Git - openssh.git/blame - auth-passwd.c
- Merged very large OpenBSD source code reformat
[openssh.git] / auth-passwd.c
CommitLineData
8efc0c15 1/*
5260325f 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Created: Sat Mar 18 05:11:38 1995 ylo
6 * Password authentication. This file contains the functions to check whether
7 * the password is valid for the user.
8 */
8efc0c15 9
10#include "includes.h"
caf3bc51 11
12#ifndef HAVE_PAM
13
8efc0c15 14RCSID("$Id$");
15
16#include "packet.h"
17#include "ssh.h"
18#include "servconf.h"
19#include "xmalloc.h"
b2344d54 20
21#ifdef HAVE_SHADOW_H
22#include <shadow.h>
23#endif
24
caf3bc51 25#ifdef HAVE_MD5_PASSWORDS
26#include "md5crypt.h"
27#endif
28
5260325f 29/*
30 * Tries to authenticate the user using password. Returns true if
31 * authentication succeeds.
32 */
33int
34auth_password(struct passwd * pw, const char *password)
8efc0c15 35{
5260325f 36 extern ServerOptions options;
37 char *encrypted_password;
b2344d54 38#ifdef HAVE_SHADOW_H
5260325f 39 struct spwd *spw;
b2344d54 40#endif
8efc0c15 41
5260325f 42 if (pw->pw_uid == 0 && options.permit_root_login == 2) {
43 /* Server does not permit root login with password */
44 return 0;
45 }
46 if (*password == '\0' && options.permit_empty_passwd == 0) {
47 /* Server does not permit empty password login */
48 return 0;
49 }
50 /* deny if no user. */
51 if (pw == NULL)
52 return 0;
8efc0c15 53
8efc0c15 54#ifdef SKEY
5260325f 55 if (options.skey_authentication == 1) {
56 if (strncasecmp(password, "s/key", 5) == 0) {
57 char *skeyinfo = skey_keyinfo(pw->pw_name);
58 if (skeyinfo == NULL) {
59 debug("generating fake skeyinfo for %.100s.",
60 pw->pw_name);
61 skeyinfo = skey_fake_keyinfo(pw->pw_name);
62 }
63 if (skeyinfo != NULL)
64 packet_send_debug(skeyinfo);
65 /* Try again. */
66 return 0;
67 } else if (skey_haskey(pw->pw_name) == 0 &&
68 skey_passcheck(pw->pw_name, (char *) password) != -1) {
69 /* Authentication succeeded. */
70 return 1;
71 }
72 /* Fall back to ordinary passwd authentication. */
73 }
8efc0c15 74#endif
75
76#if defined(KRB4)
5260325f 77 /* Support for Kerberos v4 authentication - Dug Song
78 <dugsong@UMICH.EDU> */
79 if (options.kerberos_authentication) {
80 AUTH_DAT adata;
81 KTEXT_ST tkt;
82 struct hostent *hp;
83 unsigned long faddr;
84 char localhost[MAXHOSTNAMELEN];
85 char phost[INST_SZ];
86 char realm[REALM_SZ];
87 int r;
88
89 /* Try Kerberos password authentication only for non-root
90 users and only if Kerberos is installed. */
91 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
92
93 /* Set up our ticket file. */
94 if (!krb4_init(pw->pw_uid)) {
95 log("Couldn't initialize Kerberos ticket file for %s!",
96 pw->pw_name);
97 goto kerberos_auth_failure;
98 }
99 /* Try to get TGT using our password. */
100 r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
101 realm, "krbtgt", realm,
102 DEFAULT_TKT_LIFE, (char *) password);
103 if (r != INTK_OK) {
104 packet_send_debug("Kerberos V4 password "
105 "authentication for %s failed: %s",
106 pw->pw_name, krb_err_txt[r]);
107 goto kerberos_auth_failure;
108 }
109 /* Successful authentication. */
110 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
111
112 /*
113 * Now that we have a TGT, try to get a local
114 * "rcmd" ticket to ensure that we are not talking
115 * to a bogus Kerberos server.
116 */
117 (void) gethostname(localhost, sizeof(localhost));
118 (void) strlcpy(phost, (char *) krb_get_phost(localhost),
119 INST_SZ);
120 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
121
122 if (r == KSUCCESS) {
123 if (!(hp = gethostbyname(localhost))) {
124 log("Couldn't get local host address!");
125 goto kerberos_auth_failure;
126 }
127 memmove((void *) &faddr, (void *) hp->h_addr,
128 sizeof(faddr));
129
130 /* Verify our "rcmd" ticket. */
131 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
132 faddr, &adata, "");
133 if (r == RD_AP_UNDEC) {
134 /*
135 * Probably didn't have a srvtab on
136 * localhost. Allow login.
137 */
138 log("Kerberos V4 TGT for %s unverifiable, "
139 "no srvtab installed? krb_rd_req: %s",
140 pw->pw_name, krb_err_txt[r]);
141 } else if (r != KSUCCESS) {
142 log("Kerberos V4 %s ticket unverifiable: %s",
143 KRB4_SERVICE_NAME, krb_err_txt[r]);
144 goto kerberos_auth_failure;
145 }
146 } else if (r == KDC_PR_UNKNOWN) {
147 /* Allow login if no rcmd service exists,
148 but log the error. */
149 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
150 "not registered, or srvtab is wrong?", pw->pw_name,
151 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
152 } else {
153 /* TGT is bad, forget it. Possibly
154 spoofed! */
155 packet_send_debug("WARNING: Kerberos V4 TGT "
156 "possibly spoofed for %s: %s",
157 pw->pw_name, krb_err_txt[r]);
158 goto kerberos_auth_failure;
159 }
160
161 /* Authentication succeeded. */
162 return 1;
163
164 kerberos_auth_failure:
165 krb4_cleanup_proc(NULL);
166
167 if (!options.kerberos_or_local_passwd)
168 return 0;
169 } else {
170 /* Logging in as root or no local Kerberos realm. */
171 packet_send_debug("Unable to authenticate to Kerberos.");
172 }
173 /* Fall back to ordinary passwd authentication. */
8efc0c15 174 }
5260325f 175#endif /* KRB4 */
176
177 /* Check for users with no password. */
178 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) {
179 packet_send_debug("Login permitted without a password "
180 "because the account has no password.");
181 return 1;
8efc0c15 182 }
8efc0c15 183
b2344d54 184#ifdef HAVE_SHADOW_H
5260325f 185 spw = getspnam(pw->pw_name);
186 if (spw == NULL)
187 return(0);
b2344d54 188
5260325f 189 if ((spw->sp_namp == NULL) || (strcmp(pw->pw_name, spw->sp_namp) != 0))
190 fatal("Shadow lookup returned garbage.");
b2344d54 191
5260325f 192 if (strlen(spw->sp_pwdp) < 3)
193 return(0);
b2344d54 194
5260325f 195 /* Encrypt the candidate password using the proper salt. */
caf3bc51 196#ifdef HAVE_MD5_PASSWORDS
5260325f 197 if (is_md5_salt(spw->sp_pwdp))
198 encrypted_password = md5_crypt(password, spw->sp_pwdp);
199 else
200 encrypted_password = crypt(password, spw->sp_pwdp);
caf3bc51 201#else /* HAVE_MD5_PASSWORDS */
5260325f 202 encrypted_password = crypt(password, spw->sp_pwdp);
caf3bc51 203#endif /* HAVE_MD5_PASSWORDS */
5260325f 204 /* Authentication is accepted if the encrypted passwords are identical. */
205 return (strcmp(encrypted_password, spw->sp_pwdp) == 0);
b2344d54 206#else /* !HAVE_SHADOW_H */
5260325f 207 encrypted_password = crypt(password,
208 (pw->pw_passwd[0] && pw->pw_passwd[1]) ? pw->pw_passwd : "xx");
b2344d54 209
5260325f 210 /* Authentication is accepted if the encrypted passwords are identical. */
211 return (strcmp(encrypted_password, pw->pw_passwd) == 0);
b2344d54 212#endif /* !HAVE_SHADOW_H */
8efc0c15 213}
b2344d54 214#endif /* !HAVE_PAM */
This page took 0.095723 seconds and 5 git commands to generate.