1 /* 2 * Copyright (c) 1997 - 2000 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 "krb5_locl.h" 35 36 RCSID("$Id: keytab_memory.c,v 1.4 2000/02/07 03:18:39 assar Exp $"); 37 38 /* memory operations -------------------------------------------- */ 39 40 struct mkt_data { 41 krb5_keytab_entry *entries; 42 int num_entries; 43 }; 44 45 static krb5_error_code 46 mkt_resolve(krb5_context context, const char *name, krb5_keytab id) 47 { 48 struct mkt_data *d; 49 d = malloc(sizeof(*d)); 50 if(d == NULL) 51 return ENOMEM; 52 d->entries = NULL; 53 d->num_entries = 0; 54 id->data = d; 55 return 0; 56 } 57 58 static krb5_error_code 59 mkt_close(krb5_context context, krb5_keytab id) 60 { 61 struct mkt_data *d = id->data; 62 int i; 63 for(i = 0; i < d->num_entries; i++) 64 krb5_kt_free_entry(context, &d->entries[i]); 65 free(d->entries); 66 free(d); 67 return 0; 68 } 69 70 static krb5_error_code 71 mkt_get_name(krb5_context context, 72 krb5_keytab id, 73 char *name, 74 size_t namesize) 75 { 76 strlcpy(name, "", namesize); 77 return 0; 78 } 79 80 static krb5_error_code 81 mkt_start_seq_get(krb5_context context, 82 krb5_keytab id, 83 krb5_kt_cursor *c) 84 { 85 /* XXX */ 86 c->fd = 0; 87 return 0; 88 } 89 90 static krb5_error_code 91 mkt_next_entry(krb5_context context, 92 krb5_keytab id, 93 krb5_keytab_entry *entry, 94 krb5_kt_cursor *c) 95 { 96 struct mkt_data *d = id->data; 97 if(c->fd >= d->num_entries) 98 return KRB5_KT_END; 99 return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry); 100 } 101 102 static krb5_error_code 103 mkt_end_seq_get(krb5_context context, 104 krb5_keytab id, 105 krb5_kt_cursor *cursor) 106 { 107 return 0; 108 } 109 110 static krb5_error_code 111 mkt_add_entry(krb5_context context, 112 krb5_keytab id, 113 krb5_keytab_entry *entry) 114 { 115 struct mkt_data *d = id->data; 116 krb5_keytab_entry *tmp; 117 tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries)); 118 if(tmp == NULL) 119 return ENOMEM; 120 d->entries = tmp; 121 return krb5_kt_copy_entry_contents(context, entry, 122 &d->entries[d->num_entries++]); 123 } 124 125 static krb5_error_code 126 mkt_remove_entry(krb5_context context, 127 krb5_keytab id, 128 krb5_keytab_entry *entry) 129 { 130 struct mkt_data *d = id->data; 131 krb5_keytab_entry *e, *end; 132 133 /* do this backwards to minimize copying */ 134 for(end = d->entries + d->num_entries, e = end - 1; e >= d->entries; e--) { 135 if(krb5_kt_compare(context, e, entry->principal, 136 entry->vno, entry->keyblock.keytype)) { 137 krb5_kt_free_entry(context, e); 138 memmove(e, e + 1, (end - e - 1) * sizeof(*e)); 139 memset(end - 1, 0, sizeof(*end)); 140 d->num_entries--; 141 end--; 142 } 143 } 144 e = realloc(d->entries, d->num_entries * sizeof(*d->entries)); 145 if(e != NULL) 146 d->entries = e; 147 return 0; 148 } 149 150 const krb5_kt_ops krb5_mkt_ops = { 151 "MEMORY", 152 mkt_resolve, 153 mkt_get_name, 154 mkt_close, 155 NULL, /* get */ 156 mkt_start_seq_get, 157 mkt_next_entry, 158 mkt_end_seq_get, 159 mkt_add_entry, 160 mkt_remove_entry 161 }; 162