etc/services - sync with NetBSD-8
[minix.git] / crypto / external / bsd / heimdal / dist / lib / krb5 / keytab_any.c
blob24fc64d4dbe6c387a49b226eec93f2201d2b6c7b
1 /* $NetBSD: keytab_any.c,v 1.1.1.1 2011/04/13 18:15:34 elric Exp $ */
3 /*
4 * Copyright (c) 2001-2002 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
36 #include "krb5_locl.h"
38 struct any_data {
39 krb5_keytab kt;
40 char *name;
41 struct any_data *next;
44 static void
45 free_list (krb5_context context, struct any_data *a)
47 struct any_data *next;
49 for (; a != NULL; a = next) {
50 next = a->next;
51 free (a->name);
52 if(a->kt)
53 krb5_kt_close(context, a->kt);
54 free (a);
58 static krb5_error_code KRB5_CALLCONV
59 any_resolve(krb5_context context, const char *name, krb5_keytab id)
61 struct any_data *a, *a0 = NULL, *prev = NULL;
62 krb5_error_code ret;
63 char buf[256];
65 while (strsep_copy(&name, ",", buf, sizeof(buf)) != -1) {
66 a = calloc(1, sizeof(*a));
67 if (a == NULL) {
68 ret = ENOMEM;
69 goto fail;
71 if (a0 == NULL) {
72 a0 = a;
73 a->name = strdup(buf);
74 if (a->name == NULL) {
75 ret = ENOMEM;
76 krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
77 goto fail;
79 } else
80 a->name = NULL;
81 if (prev != NULL)
82 prev->next = a;
83 a->next = NULL;
84 ret = krb5_kt_resolve (context, buf, &a->kt);
85 if (ret)
86 goto fail;
87 prev = a;
89 if (a0 == NULL) {
90 krb5_set_error_message(context, ENOENT, N_("empty ANY: keytab", ""));
91 return ENOENT;
93 id->data = a0;
94 return 0;
95 fail:
96 free_list (context, a0);
97 return ret;
100 static krb5_error_code KRB5_CALLCONV
101 any_get_name (krb5_context context,
102 krb5_keytab id,
103 char *name,
104 size_t namesize)
106 struct any_data *a = id->data;
107 strlcpy(name, a->name, namesize);
108 return 0;
111 static krb5_error_code KRB5_CALLCONV
112 any_close (krb5_context context,
113 krb5_keytab id)
115 struct any_data *a = id->data;
117 free_list (context, a);
118 return 0;
121 struct any_cursor_extra_data {
122 struct any_data *a;
123 krb5_kt_cursor cursor;
126 static krb5_error_code KRB5_CALLCONV
127 any_start_seq_get(krb5_context context,
128 krb5_keytab id,
129 krb5_kt_cursor *c)
131 struct any_data *a = id->data;
132 struct any_cursor_extra_data *ed;
133 krb5_error_code ret;
135 c->data = malloc (sizeof(struct any_cursor_extra_data));
136 if(c->data == NULL){
137 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
138 return ENOMEM;
140 ed = (struct any_cursor_extra_data *)c->data;
141 for (ed->a = a; ed->a != NULL; ed->a = ed->a->next) {
142 ret = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor);
143 if (ret == 0)
144 break;
146 if (ed->a == NULL) {
147 free (c->data);
148 c->data = NULL;
149 krb5_clear_error_message (context);
150 return KRB5_KT_END;
152 return 0;
155 static krb5_error_code KRB5_CALLCONV
156 any_next_entry (krb5_context context,
157 krb5_keytab id,
158 krb5_keytab_entry *entry,
159 krb5_kt_cursor *cursor)
161 krb5_error_code ret, ret2;
162 struct any_cursor_extra_data *ed;
164 ed = (struct any_cursor_extra_data *)cursor->data;
165 do {
166 ret = krb5_kt_next_entry(context, ed->a->kt, entry, &ed->cursor);
167 if (ret == 0)
168 return 0;
169 else if (ret != KRB5_KT_END)
170 return ret;
172 ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor);
173 if (ret2)
174 return ret2;
175 while ((ed->a = ed->a->next) != NULL) {
176 ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor);
177 if (ret2 == 0)
178 break;
180 if (ed->a == NULL) {
181 krb5_clear_error_message (context);
182 return KRB5_KT_END;
184 } while (1);
187 static krb5_error_code KRB5_CALLCONV
188 any_end_seq_get(krb5_context context,
189 krb5_keytab id,
190 krb5_kt_cursor *cursor)
192 krb5_error_code ret = 0;
193 struct any_cursor_extra_data *ed;
195 ed = (struct any_cursor_extra_data *)cursor->data;
196 if (ed->a != NULL)
197 ret = krb5_kt_end_seq_get(context, ed->a->kt, &ed->cursor);
198 free (ed);
199 cursor->data = NULL;
200 return ret;
203 static krb5_error_code KRB5_CALLCONV
204 any_add_entry(krb5_context context,
205 krb5_keytab id,
206 krb5_keytab_entry *entry)
208 struct any_data *a = id->data;
209 krb5_error_code ret;
210 while(a != NULL) {
211 ret = krb5_kt_add_entry(context, a->kt, entry);
212 if(ret != 0 && ret != KRB5_KT_NOWRITE) {
213 krb5_set_error_message(context, ret,
214 N_("failed to add entry to %s", ""),
215 a->name);
216 return ret;
218 a = a->next;
220 return 0;
223 static krb5_error_code KRB5_CALLCONV
224 any_remove_entry(krb5_context context,
225 krb5_keytab id,
226 krb5_keytab_entry *entry)
228 struct any_data *a = id->data;
229 krb5_error_code ret;
230 int found = 0;
231 while(a != NULL) {
232 ret = krb5_kt_remove_entry(context, a->kt, entry);
233 if(ret == 0)
234 found++;
235 else {
236 if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) {
237 krb5_set_error_message(context, ret,
238 N_("Failed to remove keytab "
239 "entry from %s", "keytab name"),
240 a->name);
241 return ret;
244 a = a->next;
246 if(!found)
247 return KRB5_KT_NOTFOUND;
248 return 0;
251 const krb5_kt_ops krb5_any_ops = {
252 "ANY",
253 any_resolve,
254 any_get_name,
255 any_close,
256 NULL, /* destroy */
257 NULL, /* get */
258 any_start_seq_get,
259 any_next_entry,
260 any_end_seq_get,
261 any_add_entry,
262 any_remove_entry