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