/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- free_list
- any_resolve
- any_get_name
- any_close
- any_start_seq_get
- any_next_entry
- any_end_seq_get
- any_add_entry
- any_remove_entry
1 /*
2 * Copyright (c) 2001-2002 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$");
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 (krb5_context context, struct any_data *a)
/* [<][>][^][v][top][bottom][index][help] */
46 {
47 struct any_data *next;
48
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);
55 }
56 }
57
58 static krb5_error_code
59 any_resolve(krb5_context context, const char *name, krb5_keytab id)
/* [<][>][^][v][top][bottom][index][help] */
60 {
61 struct any_data *a, *a0 = NULL, *prev = NULL;
62 krb5_error_code ret;
63 char buf[256];
64
65 while (strsep_copy(&name, ",", buf, sizeof(buf)) != -1) {
66 a = malloc(sizeof(*a));
67 if (a == NULL) {
68 ret = ENOMEM;
69 goto fail;
70 }
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;
78 }
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;
88 }
89 if (a0 == NULL) {
90 krb5_set_error_message(context, ENOENT, N_("empty ANY: keytab", ""));
91 return ENOENT;
92 }
93 id->data = a0;
94 return 0;
95 fail:
96 free_list (context, a0);
97 return ret;
98 }
99
100 static krb5_error_code
101 any_get_name (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
102 krb5_keytab id,
103 char *name,
104 size_t namesize)
105 {
106 struct any_data *a = id->data;
107 strlcpy(name, a->name, namesize);
108 return 0;
109 }
110
111 static krb5_error_code
112 any_close (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
113 krb5_keytab id)
114 {
115 struct any_data *a = id->data;
116
117 free_list (context, a);
118 return 0;
119 }
120
121 struct any_cursor_extra_data {
122 struct any_data *a;
123 krb5_kt_cursor cursor;
124 };
125
126 static krb5_error_code
127 any_start_seq_get(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
128 krb5_keytab id,
129 krb5_kt_cursor *c)
130 {
131 struct any_data *a = id->data;
132 struct any_cursor_extra_data *ed;
133 krb5_error_code ret;
134
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;
139 }
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;
145 }
146 if (ed->a == NULL) {
147 free (c->data);
148 c->data = NULL;
149 krb5_clear_error_message (context);
150 return KRB5_KT_END;
151 }
152 return 0;
153 }
154
155 static krb5_error_code
156 any_next_entry (krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
157 krb5_keytab id,
158 krb5_keytab_entry *entry,
159 krb5_kt_cursor *cursor)
160 {
161 krb5_error_code ret, ret2;
162 struct any_cursor_extra_data *ed;
163
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;
171
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;
179 }
180 if (ed->a == NULL) {
181 krb5_clear_error_message (context);
182 return KRB5_KT_END;
183 }
184 } while (1);
185 }
186
187 static krb5_error_code
188 any_end_seq_get(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
189 krb5_keytab id,
190 krb5_kt_cursor *cursor)
191 {
192 krb5_error_code ret = 0;
193 struct any_cursor_extra_data *ed;
194
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;
201 }
202
203 static krb5_error_code
204 any_add_entry(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
205 krb5_keytab id,
206 krb5_keytab_entry *entry)
207 {
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;
217 }
218 a = a->next;
219 }
220 return 0;
221 }
222
223 static krb5_error_code
224 any_remove_entry(krb5_context context,
/* [<][>][^][v][top][bottom][index][help] */
225 krb5_keytab id,
226 krb5_keytab_entry *entry)
227 {
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;
242 }
243 }
244 a = a->next;
245 }
246 if(!found)
247 return KRB5_KT_NOTFOUND;
248 return 0;
249 }
250
251 const krb5_kt_ops krb5_any_ops = {
252 "ANY",
253 any_resolve,
254 any_get_name,
255 any_close,
256 NULL, /* get */
257 any_start_seq_get,
258 any_next_entry,
259 any_end_seq_get,
260 any_add_entry,
261 any_remove_entry
262 };