auth-krb5.c revision 1.1.1.1
1/*	$NetBSD: auth-krb5.c,v 1.1.1.1 2009/06/07 22:19:01 christos Exp $	*/
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.
5 *
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.
10 *
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.
19 *
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.
30 */
31
32#include <sys/types.h>
33#include <pwd.h>
34#include <stdarg.h>
35
36#include "xmalloc.h"
37#include "ssh.h"
38#include "ssh1.h"
39#include "packet.h"
40#include "log.h"
41#include "buffer.h"
42#include "servconf.h"
43#include "uidswap.h"
44#include "key.h"
45#include "hostfile.h"
46#include "auth.h"
47
48#ifdef KRB5
49#include <krb5.h>
50
51extern ServerOptions	 options;
52
53static int
54krb5_init(void *context)
55{
56	Authctxt *authctxt = (Authctxt *)context;
57	krb5_error_code problem;
58
59	if (authctxt->krb5_ctx == NULL) {
60		problem = krb5_init_context(&authctxt->krb5_ctx);
61		if (problem)
62			return (problem);
63		krb5_init_ets(authctxt->krb5_ctx);
64	}
65	return (0);
66}
67
68int
69auth_krb5_password(Authctxt *authctxt, const char *password)
70{
71	krb5_error_code problem;
72	krb5_ccache ccache = NULL;
73
74	temporarily_use_uid(authctxt->pw);
75
76	problem = krb5_init(authctxt);
77	if (problem)
78		goto out;
79
80	problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
81		    &authctxt->krb5_user);
82	if (problem)
83		goto out;
84
85	problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
86	if (problem)
87		goto out;
88
89	problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
90		authctxt->krb5_user);
91	if (problem)
92		goto out;
93
94	restore_uid();
95
96	problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
97	    ccache, password, 1, NULL);
98
99	temporarily_use_uid(authctxt->pw);
100
101	if (problem)
102		goto out;
103
104	problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
105	    &authctxt->krb5_fwd_ccache);
106	if (problem)
107		goto out;
108
109	problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache,
110	    authctxt->krb5_fwd_ccache);
111	krb5_cc_destroy(authctxt->krb5_ctx, ccache);
112	ccache = NULL;
113	if (problem)
114		goto out;
115
116	authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx,
117	    authctxt->krb5_fwd_ccache);
118
119 out:
120	restore_uid();
121
122	if (problem) {
123		if (ccache)
124			krb5_cc_destroy(authctxt->krb5_ctx, ccache);
125
126		if (authctxt->krb5_ctx != NULL)
127			debug("Kerberos password authentication failed: %s",
128			    krb5_get_err_text(authctxt->krb5_ctx, problem));
129		else
130			debug("Kerberos password authentication failed: %d",
131			    problem);
132
133		krb5_cleanup_proc(authctxt);
134
135		if (options.kerberos_or_local_passwd)
136			return (-1);
137		else
138			return (0);
139	}
140	return (authctxt->valid ? 1 : 0);
141}
142
143void
144krb5_cleanup_proc(Authctxt *authctxt)
145{
146	debug("krb5_cleanup_proc called");
147	if (authctxt->krb5_fwd_ccache) {
148		krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
149		authctxt->krb5_fwd_ccache = NULL;
150	}
151	if (authctxt->krb5_user) {
152		krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
153		authctxt->krb5_user = NULL;
154	}
155	if (authctxt->krb5_ctx) {
156		krb5_free_context(authctxt->krb5_ctx);
157		authctxt->krb5_ctx = NULL;
158	}
159}
160
161#endif /* KRB5 */
162