1 /* 2 * Copyright (c) 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 "krb5_locl.h" 35 36 RCSID("$Id: keytab_any.c,v 1.2 2001/05/14 06:14:48 assar Exp $"); 37 38 struct any_data { 39 krb5_keytab kt; 40 char *name; 41 struct any_data *next; 42 }; 43 44 static void 45 free_list (struct any_data *a) 46 { 47 struct any_data *next; 48 49 for (; a != NULL; a = next) { 50 next = a->next; 51 free (a->name); 52 free (a); 53 } 54 } 55 56 static krb5_error_code 57 any_resolve(krb5_context context, const char *name, krb5_keytab id) 58 { 59 struct any_data *a, *a0 = NULL, *prev = NULL; 60 krb5_error_code ret; 61 char buf[256]; 62 63 while (strsep_copy(&name, ",", buf, sizeof(buf)) != -1) { 64 a = malloc(sizeof(*a)); 65 if (a == NULL) { 66 ret = ENOMEM; 67 goto fail; 68 } 69 if (a0 == NULL) { 70 a0 = a; 71 a->name = strdup(name); 72 if (a->name == NULL) { 73 krb5_set_error_string(context, "malloc: out of memory"); 74 ret = ENOMEM; 75 goto fail; 76 } 77 } else 78 a->name = NULL; 79 if (prev != NULL) 80 prev->next = a; 81 a->next = NULL; 82 ret = krb5_kt_resolve (context, buf, &a->kt); 83 if (ret) 84 goto fail; 85 prev = a; 86 } 87 if (a0 == NULL) { 88 krb5_set_error_string(context, "empty ANY: keytab"); 89 return ENOENT; 90 } 91 id->data = a0; 92 return 0; 93 fail: 94 free_list (a0); 95 return ret; 96 } 97 98 static krb5_error_code 99 any_get_name (krb5_context context, 100 krb5_keytab id, 101 char *name, 102 size_t namesize) 103 { 104 struct any_data *a = id->data; 105 strlcpy(name, a->name, namesize); 106 return 0; 107 } 108 109 static krb5_error_code 110 any_close (krb5_context context, 111 krb5_keytab id) 112 { 113 struct any_data *a = id->data; 114 115 free_list (a); 116 return 0; 117 } 118 119 struct any_cursor_extra_data { 120 struct any_data *a; 121 krb5_kt_cursor cursor; 122 }; 123 124 static krb5_error_code 125 any_start_seq_get(krb5_context context, 126 krb5_keytab id, 127 krb5_kt_cursor *c) 128 { 129 struct any_data *a = id->data; 130 struct any_cursor_extra_data *ed; 131 krb5_error_code ret; 132 133 c->data = malloc (sizeof(struct any_cursor_extra_data)); 134 if(c->data == NULL){ 135 krb5_set_error_string (context, "malloc: out of memory"); 136 return ENOMEM; 137 } 138 ed = (struct any_cursor_extra_data *)c->data; 139 ed->a = a; 140 ret = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); 141 if (ret) { 142 free (ed); 143 free (c->data); 144 c->data = NULL; 145 krb5_set_error_string (context, "malloc: out of memory"); 146 return ENOMEM; 147 } 148 return 0; 149 } 150 151 static krb5_error_code 152 any_next_entry (krb5_context context, 153 krb5_keytab id, 154 krb5_keytab_entry *entry, 155 krb5_kt_cursor *cursor) 156 { 157 krb5_error_code ret, ret2; 158 struct any_cursor_extra_data *ed; 159 160 ed = (struct any_cursor_extra_data *)cursor->data; 161 do { 162 ret = krb5_kt_next_entry(context, ed->a->kt, entry, &ed->cursor); 163 if (ret == 0) 164 return 0; 165 else if (ret == KRB5_CC_END) { 166 ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor); 167 if (ret2) 168 return ret2; 169 ed->a = ed->a->next; 170 if (ed->a == NULL) { 171 krb5_clear_error_string (context); 172 return KRB5_CC_END; 173 } 174 ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); 175 if (ret2) 176 return ret2; 177 } else 178 return ret; 179 } while (ret == KRB5_CC_END); 180 return ret; 181 } 182 183 static krb5_error_code 184 any_end_seq_get(krb5_context context, 185 krb5_keytab id, 186 krb5_kt_cursor *cursor) 187 { 188 krb5_error_code ret = 0; 189 struct any_cursor_extra_data *ed; 190 191 ed = (struct any_cursor_extra_data *)cursor->data; 192 if (ed->a != NULL) 193 ret = krb5_kt_end_seq_get(context, ed->a->kt, &ed->cursor); 194 free (ed); 195 cursor->data = NULL; 196 return ret; 197 } 198 199 const krb5_kt_ops krb5_any_ops = { 200 "ANY", 201 any_resolve, 202 any_get_name, 203 any_close, 204 NULL, /* get */ 205 any_start_seq_get, 206 any_next_entry, 207 any_end_seq_get, 208 NULL, /* add_entry */ 209 NULL /* remote_entry */ 210 }; 211