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