1/* $NetBSD: kerberos.c,v 1.3 2021/08/14 16:14:52 christos Exp $ */ 2 3/* $OpenLDAP$ */ 4/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2021 The OpenLDAP Foundation. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 18#include <sys/cdefs.h> 19__RCSID("$NetBSD: kerberos.c,v 1.3 2021/08/14 16:14:52 christos Exp $"); 20 21#include "portable.h" 22 23#include <unistd.h> 24 25#include <lber.h> 26#include <lber_pvt.h> /* BER_BVC definition */ 27#include "lutil.h" 28#include <ac/string.h> 29 30#ifdef HAVE_KRB5 31#include <krb5.h> 32#elif defined(HAVE_KRB4) 33#include <krb.h> 34#endif 35 36/* From <ldap_pvt.h> */ 37LDAP_F( char *) ldap_pvt_get_fqdn LDAP_P(( char * )); 38 39static LUTIL_PASSWD_CHK_FUNC chk_kerberos; 40static const struct berval scheme = BER_BVC("{KERBEROS}"); 41 42static int chk_kerberos( 43 const struct berval *sc, 44 const struct berval * passwd, 45 const struct berval * cred, 46 const char **text ) 47{ 48 unsigned int i; 49 int rtn; 50 51 for( i=0; i<cred->bv_len; i++) { 52 if(cred->bv_val[i] == '\0') { 53 return LUTIL_PASSWD_ERR; /* NUL character in password */ 54 } 55 } 56 57 if( cred->bv_val[i] != '\0' ) { 58 return LUTIL_PASSWD_ERR; /* cred must behave like a string */ 59 } 60 61 for( i=0; i<passwd->bv_len; i++) { 62 if(passwd->bv_val[i] == '\0') { 63 return LUTIL_PASSWD_ERR; /* NUL character in password */ 64 } 65 } 66 67 if( passwd->bv_val[i] != '\0' ) { 68 return LUTIL_PASSWD_ERR; /* passwd must behave like a string */ 69 } 70 71 rtn = LUTIL_PASSWD_ERR; 72 73#ifdef HAVE_KRB5 /* HAVE_HEIMDAL_KRB5 */ 74 { 75/* Portions: 76 * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\xf6gskolan 77 * (Royal Institute of Technology, Stockholm, Sweden). 78 * All rights reserved. 79 * 80 * Redistribution and use in source and binary forms, with or without 81 * modification, are permitted provided that the following conditions 82 * are met: 83 * 84 * 1. Redistributions of source code must retain the above copyright 85 * notice, this list of conditions and the following disclaimer. 86 * 87 * 2. Redistributions in binary form must reproduce the above copyright 88 * notice, this list of conditions and the following disclaimer in the 89 * documentation and/or other materials provided with the distribution. 90 * 91 * 3. Neither the name of the Institute nor the names of its contributors 92 * may be used to endorse or promote products derived from this software 93 * without specific prior written permission. 94 * 95 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 96 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 97 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 98 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 99 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 100 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 101 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 102 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 103 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 104 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 105 * SUCH DAMAGE. 106 */ 107 108 krb5_context context; 109 krb5_error_code ret; 110 krb5_creds creds; 111 krb5_get_init_creds_opt get_options; 112 krb5_verify_init_creds_opt verify_options; 113 krb5_principal client, server; 114#ifdef notdef 115 krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP}; 116#endif 117 118 ret = krb5_init_context( &context ); 119 if (ret) { 120 return LUTIL_PASSWD_ERR; 121 } 122 123#ifdef notdef 124 krb5_get_init_creds_opt_set_preauth_list(&get_options, 125 pre_auth_types, 1); 126#endif 127 128 krb5_get_init_creds_opt_init( &get_options ); 129 130 krb5_verify_init_creds_opt_init( &verify_options ); 131 132 ret = krb5_parse_name( context, passwd->bv_val, &client ); 133 134 if (ret) { 135 krb5_free_context( context ); 136 return LUTIL_PASSWD_ERR; 137 } 138 139 ret = krb5_get_init_creds_password( context, 140 &creds, client, cred->bv_val, NULL, 141 NULL, 0, NULL, &get_options ); 142 143 if (ret) { 144 krb5_free_principal( context, client ); 145 krb5_free_context( context ); 146 return LUTIL_PASSWD_ERR; 147 } 148 149 { 150 char *host = ldap_pvt_get_fqdn( NULL ); 151 152 if( host == NULL ) { 153 krb5_free_principal( context, client ); 154 krb5_free_context( context ); 155 return LUTIL_PASSWD_ERR; 156 } 157 158 ret = krb5_sname_to_principal( context, 159 host, "ldap", KRB5_NT_SRV_HST, &server ); 160 161 ber_memfree( host ); 162 } 163 164 if (ret) { 165 krb5_free_principal( context, client ); 166 krb5_free_context( context ); 167 return LUTIL_PASSWD_ERR; 168 } 169 170 ret = krb5_verify_init_creds( context, 171 &creds, server, NULL, NULL, &verify_options ); 172 173 krb5_free_principal( context, client ); 174 krb5_free_principal( context, server ); 175 krb5_free_cred_contents( context, &creds ); 176 krb5_free_context( context ); 177 178 rtn = ret ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 179 } 180#elif defined(HAVE_KRB4) 181 { 182 /* Borrowed from Heimdal kpopper */ 183/* Portions: 184 * Copyright (c) 1989 Regents of the University of California. 185 * All rights reserved. The Berkeley software License Agreement 186 * specifies the terms and conditions for redistribution. 187 */ 188 189 int status; 190 char lrealm[REALM_SZ]; 191 char tkt[MAXHOSTNAMELEN]; 192 193 status = krb_get_lrealm(lrealm,1); 194 if (status == KFAILURE) { 195 return LUTIL_PASSWD_ERR; 196 } 197 198 snprintf(tkt, sizeof(tkt), "%s_slapd.%u", 199 TKT_ROOT, (unsigned)getpid()); 200 krb_set_tkt_string (tkt); 201 202 status = krb_verify_user( passwd->bv_val, "", lrealm, 203 cred->bv_val, 1, "ldap"); 204 205 dest_tkt(); /* no point in keeping the tickets */ 206 207 return status == KFAILURE ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK; 208 } 209#endif 210 211 return rtn; 212} 213 214int init_module(int argc, char *argv[]) { 215 return lutil_passwd_add( (struct berval *)&scheme, chk_kerberos, NULL ); 216} 217