1/* 2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "kdc_locl.h" 35 36RCSID("$Id: misc.c,v 1.1.1.1 2011/06/10 09:34:43 andrew Exp $"); 37 38struct timeval _kdc_now; 39 40krb5_error_code 41_kdc_db_fetch(krb5_context context, 42 krb5_kdc_configuration *config, 43 krb5_const_principal principal, 44 unsigned flags, 45 HDB **db, 46 hdb_entry_ex **h) 47{ 48 hdb_entry_ex *ent; 49 krb5_error_code ret; 50 int i; 51 52 ent = calloc (1, sizeof (*ent)); 53 if (ent == NULL) { 54 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 55 return ENOMEM; 56 } 57 58 for(i = 0; i < config->num_db; i++) { 59 krb5_principal enterprise_principal = NULL; 60 if (!(config->db[i]->hdb_capability_flags & HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL) 61 && principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { 62 if (principal->name.name_string.len != 1) { 63 ret = KRB5_PARSE_MALFORMED; 64 krb5_set_error_message(context, ret, 65 "malformed request: " 66 "enterprise name with %d name components", 67 principal->name.name_string.len); 68 free(ent); 69 return ret; 70 } 71 ret = krb5_parse_name(context, principal->name.name_string.val[0], 72 &enterprise_principal); 73 if (ret) { 74 free(ent); 75 return ret; 76 } 77 78 principal = enterprise_principal; 79 } 80 81 ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0); 82 if (ret) { 83 kdc_log(context, config, 0, "Failed to open database: %s", 84 krb5_get_err_text(context, ret)); 85 continue; 86 } 87 88 ret = config->db[i]->hdb_fetch(context, 89 config->db[i], 90 principal, 91 flags | HDB_F_DECRYPT, 92 ent); 93 krb5_free_principal(context, enterprise_principal); 94 95 config->db[i]->hdb_close(context, config->db[i]); 96 if(ret == 0) { 97 if (db) 98 *db = config->db[i]; 99 *h = ent; 100 return 0; 101 } 102 } 103 free(ent); 104 krb5_set_error_message(context, HDB_ERR_NOENTRY, 105 "no such entry found in hdb"); 106 return HDB_ERR_NOENTRY; 107} 108 109void 110_kdc_free_ent(krb5_context context, hdb_entry_ex *ent) 111{ 112 hdb_free_entry (context, ent); 113 free (ent); 114} 115 116/* 117 * Use the order list of preferred encryption types and sort the 118 * available keys and return the most preferred key. 119 */ 120 121krb5_error_code 122_kdc_get_preferred_key(krb5_context context, 123 krb5_kdc_configuration *config, 124 hdb_entry_ex *h, 125 const char *name, 126 krb5_enctype *enctype, 127 Key **key) 128{ 129 const krb5_enctype *p; 130 krb5_error_code ret; 131 int i; 132 133 p = krb5_kerberos_enctypes(context); 134 135 for (i = 0; p[i] != ETYPE_NULL; i++) { 136 if (krb5_enctype_valid(context, p[i]) != 0) 137 continue; 138 ret = hdb_enctype2key(context, &h->entry, p[i], key); 139 if (ret == 0) { 140 *enctype = p[i]; 141 return 0; 142 } 143 } 144 145 krb5_set_error_message(context, EINVAL, 146 "No valid kerberos key found for %s", name); 147 return EINVAL; 148} 149 150