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