No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / external / bsd / openssh / dist / auth-krb5.c
blob48ba33c35a455e62bfe6d165d3ec1ac7c01364c6
1 /* $NetBSD$ */
2 /* $OpenBSD: auth-krb5.c,v 1.19 2006/08/03 03:34:41 deraadt Exp $ */
3 /*
4 * Kerberos v5 authentication and ticket-passing routines.
6 * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
7 */
8 /*
9 * Copyright (c) 2002 Daniel Kouril. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "includes.h"
33 __RCSID("$NetBSD: auth-krb5.c,v 1.17 2006/09/28 21:22:14 christos Exp $");
34 #include <sys/types.h>
35 #include <pwd.h>
36 #include <stdarg.h>
37 #include <string.h>
39 #include "xmalloc.h"
40 #include "ssh.h"
41 #include "ssh1.h"
42 #include "packet.h"
43 #include "log.h"
44 #include "buffer.h"
45 #include "servconf.h"
46 #include "uidswap.h"
47 #include "key.h"
48 #include "hostfile.h"
49 #include "auth.h"
51 #ifdef KRB5
52 #include <krb5.h>
54 extern ServerOptions options;
56 static int
57 krb5_init(void *context)
59 Authctxt *authctxt = (Authctxt *)context;
60 krb5_error_code problem;
62 if (authctxt->krb5_ctx == NULL) {
63 problem = krb5_init_context(&authctxt->krb5_ctx);
64 if (problem)
65 return (problem);
66 krb5_init_ets(authctxt->krb5_ctx);
68 return (0);
72 * Try krb5 authentication. server_user is passed for logging purposes
73 * only, in auth is received ticket, in client is returned principal
74 * from the ticket
76 int
77 auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
79 krb5_error_code problem;
80 krb5_principal server;
81 krb5_ticket *ticket;
82 int fd, ret;
84 ret = 0;
85 server = NULL;
86 ticket = NULL;
87 reply->length = 0;
89 problem = krb5_init(authctxt);
90 if (problem)
91 goto err;
93 problem = krb5_auth_con_init(authctxt->krb5_ctx,
94 &authctxt->krb5_auth_ctx);
95 if (problem)
96 goto err;
98 fd = packet_get_connection_in();
99 problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
100 authctxt->krb5_auth_ctx, &fd);
101 if (problem)
102 goto err;
104 problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
105 KRB5_NT_SRV_HST, &server);
106 if (problem)
107 goto err;
109 problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
110 auth, server, NULL, NULL, &ticket);
111 if (problem)
112 goto err;
114 problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
115 &authctxt->krb5_user);
116 if (problem)
117 goto err;
119 /* if client wants mutual auth */
120 problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
121 reply);
122 if (problem)
123 goto err;
125 /* Check .k5login authorization now. */
126 if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
127 authctxt->pw->pw_name))
128 goto err;
130 if (client)
131 krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
132 client);
134 ret = 1;
135 err:
136 if (server)
137 krb5_free_principal(authctxt->krb5_ctx, server);
138 if (ticket)
139 krb5_free_ticket(authctxt->krb5_ctx, ticket);
140 if (!ret && reply->length) {
141 xfree(reply->data);
142 memset(reply, 0, sizeof(*reply));
145 if (problem) {
146 if (authctxt->krb5_ctx != NULL)
147 debug("Kerberos v5 authentication failed: %s",
148 krb5_get_err_text(authctxt->krb5_ctx, problem));
149 else
150 debug("Kerberos v5 authentication failed: %d",
151 problem);
154 return (ret);
158 auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
160 krb5_error_code problem;
161 krb5_ccache ccache = NULL;
162 char *pname;
164 if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
165 return (0);
167 temporarily_use_uid(authctxt->pw);
169 problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
170 if (problem)
171 goto fail;
173 problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
174 authctxt->krb5_user);
175 if (problem)
176 goto fail;
178 problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
179 ccache, tgt);
180 if (problem)
181 goto fail;
183 authctxt->krb5_fwd_ccache = ccache;
184 ccache = NULL;
186 authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
188 problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
189 &pname);
190 if (problem)
191 goto fail;
193 #ifdef USE_PAM
194 if (options.use_pam)
195 do_pam_putenv("KRB5CCNAME", authctxt->krb5_ticket_file);
196 #endif
197 debug("Kerberos v5 TGT accepted (%s)", pname);
199 restore_uid();
201 return (1);
203 fail:
204 if (problem)
205 debug("Kerberos v5 TGT passing failed: %s",
206 krb5_get_err_text(authctxt->krb5_ctx, problem));
207 if (ccache)
208 krb5_cc_destroy(authctxt->krb5_ctx, ccache);
210 restore_uid();
212 return (0);
217 auth_krb5_password(Authctxt *authctxt, const char *password)
219 krb5_error_code problem;
220 krb5_ccache ccache = NULL;
222 temporarily_use_uid(authctxt->pw);
224 problem = krb5_init(authctxt);
225 if (problem)
226 goto out;
228 problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
229 &authctxt->krb5_user);
230 if (problem)
231 goto out;
233 problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
234 if (problem)
235 goto out;
237 problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
238 authctxt->krb5_user);
239 if (problem)
240 goto out;
242 restore_uid();
244 problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
245 ccache, password, 1, NULL);
247 temporarily_use_uid(authctxt->pw);
249 if (problem)
250 goto out;
252 problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
253 &authctxt->krb5_fwd_ccache);
254 if (problem)
255 goto out;
257 problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache,
258 authctxt->krb5_fwd_ccache);
259 krb5_cc_destroy(authctxt->krb5_ctx, ccache);
260 ccache = NULL;
261 if (problem)
262 goto out;
264 authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx,
265 authctxt->krb5_fwd_ccache);
267 out:
268 restore_uid();
270 if (problem) {
271 if (ccache)
272 krb5_cc_destroy(authctxt->krb5_ctx, ccache);
274 if (authctxt->krb5_ctx != NULL)
275 debug("Kerberos password authentication failed: %s",
276 krb5_get_err_text(authctxt->krb5_ctx, problem));
277 else
278 debug("Kerberos password authentication failed: %d",
279 problem);
281 krb5_cleanup_proc(authctxt);
283 if (options.kerberos_or_local_passwd)
284 return (-1);
285 else
286 return (0);
288 return (authctxt->valid ? 1 : 0);
291 void
292 krb5_cleanup_proc(Authctxt *authctxt)
294 debug("krb5_cleanup_proc called");
295 if (authctxt->krb5_fwd_ccache) {
296 krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
297 authctxt->krb5_fwd_ccache = NULL;
299 if (authctxt->krb5_user) {
300 krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
301 authctxt->krb5_user = NULL;
303 if (authctxt->krb5_auth_ctx) {
304 krb5_auth_con_free(authctxt->krb5_ctx,
305 authctxt->krb5_auth_ctx);
306 authctxt->krb5_auth_ctx = NULL;
308 if (authctxt->krb5_ctx) {
309 krb5_free_context(authctxt->krb5_ctx);
310 authctxt->krb5_ctx = NULL;
314 #endif /* KRB5 */