1 /* 2 * Copyright (c) 2009 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2009 Apple Inc. 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 "hdb_locl.h" 37 #include <assert.h> 38 39 typedef struct { 40 char *path; 41 krb5_keytab keytab; 42 } *hdb_keytab; 43 44 /* 45 * 46 */ 47 48 static krb5_error_code 49 hkt_close(krb5_context context, HDB *db) 50 { 51 hdb_keytab k = (hdb_keytab)db->hdb_db; 52 krb5_error_code ret; 53 54 assert(k->keytab); 55 56 ret = krb5_kt_close(context, k->keytab); 57 k->keytab = NULL; 58 59 return ret; 60 } 61 62 static krb5_error_code 63 hkt_destroy(krb5_context context, HDB *db) 64 { 65 hdb_keytab k = (hdb_keytab)db->hdb_db; 66 krb5_error_code ret; 67 68 ret = hdb_clear_master_key (context, db); 69 70 free(k->path); 71 free(k); 72 73 free(db->hdb_name); 74 free(db); 75 return ret; 76 } 77 78 static krb5_error_code 79 hkt_lock(krb5_context context, HDB *db, int operation) 80 { 81 return 0; 82 } 83 84 static krb5_error_code 85 hkt_unlock(krb5_context context, HDB *db) 86 { 87 return 0; 88 } 89 90 static krb5_error_code 91 hkt_firstkey(krb5_context context, HDB *db, 92 unsigned flags, hdb_entry_ex *entry) 93 { 94 return HDB_ERR_DB_INUSE; 95 } 96 97 static krb5_error_code 98 hkt_nextkey(krb5_context context, HDB * db, unsigned flags, 99 hdb_entry_ex * entry) 100 { 101 return HDB_ERR_DB_INUSE; 102 } 103 104 static krb5_error_code 105 hkt_open(krb5_context context, HDB * db, int flags, mode_t mode) 106 { 107 hdb_keytab k = (hdb_keytab)db->hdb_db; 108 krb5_error_code ret; 109 110 assert(k->keytab == NULL); 111 112 ret = krb5_kt_resolve(context, k->path, &k->keytab); 113 if (ret) 114 return ret; 115 116 return 0; 117 } 118 119 static krb5_error_code 120 hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, 121 unsigned flags, krb5_kvno kvno, hdb_entry_ex * entry) 122 { 123 hdb_keytab k = (hdb_keytab)db->hdb_db; 124 krb5_error_code ret; 125 krb5_keytab_entry ktentry; 126 127 if (!(flags & HDB_F_KVNO_SPECIFIED)) { 128 /* Preserve previous behaviour if no kvno specified */ 129 kvno = 0; 130 } 131 132 memset(&ktentry, 0, sizeof(ktentry)); 133 134 entry->entry.flags.server = 1; 135 entry->entry.flags.forwardable = 1; 136 entry->entry.flags.renewable = 1; 137 138 /* Not recorded in the OD backend, make something up */ 139 ret = krb5_parse_name(context, "hdb/keytab@WELL-KNOWN:KEYTAB-BACKEND", 140 &entry->entry.created_by.principal); 141 if (ret) 142 goto out; 143 144 /* 145 * XXX really needs to try all enctypes and just not pick the 146 * first one, even if that happens to be des3-cbc-sha1 (ie best 147 * enctype) in the Apple case. A while loop over all known 148 * enctypes should work. 149 */ 150 151 ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry); 152 if (ret) { 153 ret = HDB_ERR_NOENTRY; 154 goto out; 155 } 156 157 ret = krb5_copy_principal(context, principal, &entry->entry.principal); 158 if (ret) 159 goto out; 160 161 ret = _hdb_keytab2hdb_entry(context, &ktentry, entry); 162 163 out: 164 if (ret) { 165 free_hdb_entry(&entry->entry); 166 memset(&entry->entry, 0, sizeof(entry->entry)); 167 } 168 krb5_kt_free_entry(context, &ktentry); 169 170 return ret; 171 } 172 173 static krb5_error_code 174 hkt_store(krb5_context context, HDB * db, unsigned flags, 175 hdb_entry_ex * entry) 176 { 177 return HDB_ERR_DB_INUSE; 178 } 179 180 181 krb5_error_code 182 hdb_keytab_create(krb5_context context, HDB ** db, const char *arg) 183 { 184 hdb_keytab k; 185 186 *db = calloc(1, sizeof(**db)); 187 if (*db == NULL) { 188 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 189 return ENOMEM; 190 } 191 memset(*db, 0, sizeof(**db)); 192 193 k = calloc(1, sizeof(*k)); 194 if (k == NULL) { 195 free(*db); 196 *db = NULL; 197 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 198 return ENOMEM; 199 } 200 201 k->path = strdup(arg); 202 if (k->path == NULL) { 203 free(k); 204 free(*db); 205 *db = NULL; 206 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 207 return ENOMEM; 208 } 209 210 211 (*db)->hdb_db = k; 212 213 (*db)->hdb_master_key_set = 0; 214 (*db)->hdb_openp = 0; 215 (*db)->hdb_open = hkt_open; 216 (*db)->hdb_close = hkt_close; 217 (*db)->hdb_fetch_kvno = hkt_fetch_kvno; 218 (*db)->hdb_store = hkt_store; 219 (*db)->hdb_remove = NULL; 220 (*db)->hdb_firstkey = hkt_firstkey; 221 (*db)->hdb_nextkey = hkt_nextkey; 222 (*db)->hdb_lock = hkt_lock; 223 (*db)->hdb_unlock = hkt_unlock; 224 (*db)->hdb_rename = NULL; 225 (*db)->hdb__get = NULL; 226 (*db)->hdb__put = NULL; 227 (*db)->hdb__del = NULL; 228 (*db)->hdb_destroy = hkt_destroy; 229 230 return 0; 231 } 232