1 /* 2 * Kerberos v5 authentication and ticket-passing routines. 3 * 4 * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $ 5 */ 6 /* 7 * Copyright (c) 2002 Daniel Kouril. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "includes.h" 31 RCSID("$OpenBSD: auth-krb5.c,v 1.15 2003/11/21 11:57:02 djm Exp $"); 32 33 #include "ssh.h" 34 #include "ssh1.h" 35 #include "packet.h" 36 #include "xmalloc.h" 37 #include "log.h" 38 #include "servconf.h" 39 #include "uidswap.h" 40 #include "auth.h" 41 42 #ifdef KRB5 43 #include <krb5.h> 44 45 extern ServerOptions options; 46 47 static int 48 krb5_init(void *context) 49 { 50 Authctxt *authctxt = (Authctxt *)context; 51 krb5_error_code problem; 52 53 if (authctxt->krb5_ctx == NULL) { 54 problem = krb5_init_context(&authctxt->krb5_ctx); 55 if (problem) 56 return (problem); 57 krb5_init_ets(authctxt->krb5_ctx); 58 } 59 return (0); 60 } 61 62 int 63 auth_krb5_password(Authctxt *authctxt, const char *password) 64 { 65 krb5_error_code problem; 66 krb5_ccache ccache = NULL; 67 68 if (!authctxt->valid) 69 return (0); 70 71 temporarily_use_uid(authctxt->pw); 72 73 problem = krb5_init(authctxt); 74 if (problem) 75 goto out; 76 77 problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name, 78 &authctxt->krb5_user); 79 if (problem) 80 goto out; 81 82 problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache); 83 if (problem) 84 goto out; 85 86 problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, 87 authctxt->krb5_user); 88 if (problem) 89 goto out; 90 91 restore_uid(); 92 93 problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user, 94 ccache, password, 1, NULL); 95 96 temporarily_use_uid(authctxt->pw); 97 98 if (problem) 99 goto out; 100 101 problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, 102 &authctxt->krb5_fwd_ccache); 103 if (problem) 104 goto out; 105 106 problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache, 107 authctxt->krb5_fwd_ccache); 108 krb5_cc_destroy(authctxt->krb5_ctx, ccache); 109 ccache = NULL; 110 if (problem) 111 goto out; 112 113 authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, 114 authctxt->krb5_fwd_ccache); 115 116 out: 117 restore_uid(); 118 119 if (problem) { 120 if (ccache) 121 krb5_cc_destroy(authctxt->krb5_ctx, ccache); 122 123 if (authctxt->krb5_ctx != NULL) 124 debug("Kerberos password authentication failed: %s", 125 krb5_get_err_text(authctxt->krb5_ctx, problem)); 126 else 127 debug("Kerberos password authentication failed: %d", 128 problem); 129 130 krb5_cleanup_proc(authctxt); 131 132 if (options.kerberos_or_local_passwd) 133 return (-1); 134 else 135 return (0); 136 } 137 return (1); 138 } 139 140 void 141 krb5_cleanup_proc(Authctxt *authctxt) 142 { 143 debug("krb5_cleanup_proc called"); 144 if (authctxt->krb5_fwd_ccache) { 145 krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); 146 authctxt->krb5_fwd_ccache = NULL; 147 } 148 if (authctxt->krb5_user) { 149 krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); 150 authctxt->krb5_user = NULL; 151 } 152 if (authctxt->krb5_ctx) { 153 krb5_free_context(authctxt->krb5_ctx); 154 authctxt->krb5_ctx = NULL; 155 } 156 } 157 158 #endif /* KRB5 */ 159