diff options
Diffstat (limited to 'crypto/heimdal/lib/krb5/keytab_any.c')
-rw-r--r-- | crypto/heimdal/lib/krb5/keytab_any.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/crypto/heimdal/lib/krb5/keytab_any.c b/crypto/heimdal/lib/krb5/keytab_any.c new file mode 100644 index 0000000..490a8f3 --- /dev/null +++ b/crypto/heimdal/lib/krb5/keytab_any.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5_locl.h" + +RCSID("$Id: keytab_any.c,v 1.2 2001/05/14 06:14:48 assar Exp $"); + +struct any_data { + krb5_keytab kt; + char *name; + struct any_data *next; +}; + +static void +free_list (struct any_data *a) +{ + struct any_data *next; + + for (; a != NULL; a = next) { + next = a->next; + free (a->name); + free (a); + } +} + +static krb5_error_code +any_resolve(krb5_context context, const char *name, krb5_keytab id) +{ + struct any_data *a, *a0 = NULL, *prev = NULL; + krb5_error_code ret; + char buf[256]; + + while (strsep_copy(&name, ",", buf, sizeof(buf)) != -1) { + a = malloc(sizeof(*a)); + if (a == NULL) { + ret = ENOMEM; + goto fail; + } + if (a0 == NULL) { + a0 = a; + a->name = strdup(name); + if (a->name == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + goto fail; + } + } else + a->name = NULL; + if (prev != NULL) + prev->next = a; + a->next = NULL; + ret = krb5_kt_resolve (context, buf, &a->kt); + if (ret) + goto fail; + prev = a; + } + if (a0 == NULL) { + krb5_set_error_string(context, "empty ANY: keytab"); + return ENOENT; + } + id->data = a0; + return 0; + fail: + free_list (a0); + return ret; +} + +static krb5_error_code +any_get_name (krb5_context context, + krb5_keytab id, + char *name, + size_t namesize) +{ + struct any_data *a = id->data; + strlcpy(name, a->name, namesize); + return 0; +} + +static krb5_error_code +any_close (krb5_context context, + krb5_keytab id) +{ + struct any_data *a = id->data; + + free_list (a); + return 0; +} + +struct any_cursor_extra_data { + struct any_data *a; + krb5_kt_cursor cursor; +}; + +static krb5_error_code +any_start_seq_get(krb5_context context, + krb5_keytab id, + krb5_kt_cursor *c) +{ + struct any_data *a = id->data; + struct any_cursor_extra_data *ed; + krb5_error_code ret; + + c->data = malloc (sizeof(struct any_cursor_extra_data)); + if(c->data == NULL){ + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } + ed = (struct any_cursor_extra_data *)c->data; + ed->a = a; + ret = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); + if (ret) { + free (ed); + free (c->data); + c->data = NULL; + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } + return 0; +} + +static krb5_error_code +any_next_entry (krb5_context context, + krb5_keytab id, + krb5_keytab_entry *entry, + krb5_kt_cursor *cursor) +{ + krb5_error_code ret, ret2; + struct any_cursor_extra_data *ed; + + ed = (struct any_cursor_extra_data *)cursor->data; + do { + ret = krb5_kt_next_entry(context, ed->a->kt, entry, &ed->cursor); + if (ret == 0) + return 0; + else if (ret == KRB5_CC_END) { + ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor); + if (ret2) + return ret2; + ed->a = ed->a->next; + if (ed->a == NULL) { + krb5_clear_error_string (context); + return KRB5_CC_END; + } + ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); + if (ret2) + return ret2; + } else + return ret; + } while (ret == KRB5_CC_END); + return ret; +} + +static krb5_error_code +any_end_seq_get(krb5_context context, + krb5_keytab id, + krb5_kt_cursor *cursor) +{ + krb5_error_code ret = 0; + struct any_cursor_extra_data *ed; + + ed = (struct any_cursor_extra_data *)cursor->data; + if (ed->a != NULL) + ret = krb5_kt_end_seq_get(context, ed->a->kt, &ed->cursor); + free (ed); + cursor->data = NULL; + return ret; +} + +const krb5_kt_ops krb5_any_ops = { + "ANY", + any_resolve, + any_get_name, + any_close, + NULL, /* get */ + any_start_seq_get, + any_next_entry, + any_end_seq_get, + NULL, /* add_entry */ + NULL /* remote_entry */ +}; |