diff options
author | Heimdal Import User <samba-bugs@samba.org> | 2005-07-11 01:16:55 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:19:33 -0500 |
commit | 954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9 (patch) | |
tree | fc11a048c8a582e2ca66415ff04dacf74f9abf22 /source4/heimdal/lib/krb5/keytab_any.c | |
parent | 7ead5ab06cea9f33e954a4579163262f97ea06ff (diff) | |
download | samba-954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9.tar.gz samba-954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9.tar.bz2 samba-954c01728e0c7485b72c9a5d5737e5f6bd0cf0b9.zip |
r8302: import mini HEIMDAL into the tree
(This used to be commit 118be28a7aef233799956615a99d1a2a74dac175)
Diffstat (limited to 'source4/heimdal/lib/krb5/keytab_any.c')
-rw-r--r-- | source4/heimdal/lib/krb5/keytab_any.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c new file mode 100644 index 0000000000..667788c69d --- /dev/null +++ b/source4/heimdal/lib/krb5/keytab_any.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2001-2002 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.7 2002/10/21 13:36:59 joda Exp $"); + +struct any_data { + krb5_keytab kt; + char *name; + struct any_data *next; +}; + +static void +free_list (krb5_context context, struct any_data *a) +{ + struct any_data *next; + + for (; a != NULL; a = next) { + next = a->next; + free (a->name); + if(a->kt) + krb5_kt_close(context, a->kt); + 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(buf); + 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 (context, 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 (context, 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 (c->data); + c->data = NULL; + return ret; + } + 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_KT_END) { + ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor); + if (ret2) + return ret2; + while ((ed->a = ed->a->next) != NULL) { + ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor); + if (ret2 == 0) + break; + } + if (ed->a == NULL) { + krb5_clear_error_string (context); + return KRB5_KT_END; + } + } else + return ret; + } while (ret == KRB5_KT_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; +} + +static krb5_error_code +any_add_entry(krb5_context context, + krb5_keytab id, + krb5_keytab_entry *entry) +{ + struct any_data *a = id->data; + krb5_error_code ret; + while(a != NULL) { + ret = krb5_kt_add_entry(context, a->kt, entry); + if(ret != 0 && ret != KRB5_KT_NOWRITE) { + krb5_set_error_string(context, "failed to add entry to %s", + a->name); + return ret; + } + a = a->next; + } + return 0; +} + +static krb5_error_code +any_remove_entry(krb5_context context, + krb5_keytab id, + krb5_keytab_entry *entry) +{ + struct any_data *a = id->data; + krb5_error_code ret; + int found = 0; + while(a != NULL) { + ret = krb5_kt_remove_entry(context, a->kt, entry); + if(ret == 0) + found++; + else { + if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) { + krb5_set_error_string(context, "failed to remove entry from %s", + a->name); + return ret; + } + } + a = a->next; + } + if(!found) + return KRB5_KT_NOTFOUND; + return 0; +} + +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, + any_add_entry, + any_remove_entry +}; |