1 /* ccapi/lib/ccapi_ccache_iterator.c */
2 /*
3 * Copyright 2006 Massachusetts Institute of Technology.
4 * All Rights Reserved.
5 *
6 * Export of this software from the United States of America may
7 * require a specific license from the United States Government.
8 * It is the responsibility of any person or organization contemplating
9 * export to obtain such a license before exporting.
10 *
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of M.I.T. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. Furthermore if you modify this software you must label
19 * your software as modified software and not distribute it in such a
20 * fashion that it might be confused with the original M.I.T. software.
21 * M.I.T. makes no representations about the suitability of
22 * this software for any purpose. It is provided "as is" without express
23 * or implied warranty.
24 */
25
26 #include "ccapi_ccache_iterator.h"
27 #include "ccapi_ccache.h"
28 #include "ccapi_ipc.h"
29
30 /* ------------------------------------------------------------------------ */
31
32 typedef struct cci_ccache_iterator_d {
33 cc_ccache_iterator_f *functions;
34 #if TARGET_OS_MAC
35 cc_ccache_iterator_f *vector_functions;
36 #endif
37 cci_identifier_t identifier;
38 char *saved_ccache_name;
39 } *cci_ccache_iterator_t;
40
41 /* ------------------------------------------------------------------------ */
42
43 struct cci_ccache_iterator_d cci_ccache_iterator_initializer = {
44 NULL
45 VECTOR_FUNCTIONS_INITIALIZER,
46 NULL,
47 NULL
48 };
49
50 cc_ccache_iterator_f cci_ccache_iterator_f_initializer = {
51 ccapi_ccache_iterator_release,
52 ccapi_ccache_iterator_next,
53 ccapi_ccache_iterator_clone
54 };
55
56 /* ------------------------------------------------------------------------ */
57
cci_ccache_iterator_new(cc_ccache_iterator_t * out_ccache_iterator,cci_identifier_t in_identifier)58 cc_int32 cci_ccache_iterator_new (cc_ccache_iterator_t *out_ccache_iterator,
59 cci_identifier_t in_identifier)
60 {
61 cc_int32 err = ccNoError;
62 cci_ccache_iterator_t ccache_iterator = NULL;
63
64 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
65 if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
66
67 if (!err) {
68 ccache_iterator = malloc (sizeof (*ccache_iterator));
69 if (ccache_iterator) {
70 *ccache_iterator = cci_ccache_iterator_initializer;
71 } else {
72 err = cci_check_error (ccErrNoMem);
73 }
74 }
75
76 if (!err) {
77 ccache_iterator->functions = malloc (sizeof (*ccache_iterator->functions));
78 if (ccache_iterator->functions) {
79 *ccache_iterator->functions = cci_ccache_iterator_f_initializer;
80 } else {
81 err = cci_check_error (ccErrNoMem);
82 }
83 }
84
85 if (!err) {
86 err = cci_identifier_copy (&ccache_iterator->identifier, in_identifier);
87 }
88
89 if (!err) {
90 *out_ccache_iterator = (cc_ccache_iterator_t) ccache_iterator;
91 ccache_iterator = NULL; /* take ownership */
92 }
93
94 ccapi_ccache_iterator_release ((cc_ccache_iterator_t) ccache_iterator);
95
96 return cci_check_error (err);
97 }
98
99 /* ------------------------------------------------------------------------ */
100
cci_ccache_iterator_write(cc_ccache_iterator_t in_ccache_iterator,k5_ipc_stream in_stream)101 cc_int32 cci_ccache_iterator_write (cc_ccache_iterator_t in_ccache_iterator,
102 k5_ipc_stream in_stream)
103 {
104 cc_int32 err = ccNoError;
105 cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
106
107 if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
108 if (!in_stream ) { err = cci_check_error (ccErrBadParam); }
109
110 if (!err) {
111 err = cci_identifier_write (ccache_iterator->identifier, in_stream);
112 }
113
114 return cci_check_error (err);
115 }
116
117 /* ------------------------------------------------------------------------ */
118
ccapi_ccache_iterator_release(cc_ccache_iterator_t io_ccache_iterator)119 cc_int32 ccapi_ccache_iterator_release (cc_ccache_iterator_t io_ccache_iterator)
120 {
121 cc_int32 err = ccNoError;
122 cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator;
123
124 if (!io_ccache_iterator) { err = ccErrBadParam; }
125
126 if (!err) {
127 cc_uint32 initialized = 0;
128
129 err = cci_identifier_is_initialized (ccache_iterator->identifier,
130 &initialized);
131
132 if (!err && initialized) {
133 err = cci_ipc_send (cci_ccache_iterator_release_msg_id,
134 ccache_iterator->identifier,
135 NULL,
136 NULL);
137 if (err) {
138 cci_debug_printf ("%s: cci_ipc_send failed with error %d",
139 __FUNCTION__, err);
140 err = ccNoError;
141 }
142 }
143 }
144
145 if (!err) {
146 free ((char *) ccache_iterator->functions);
147 cci_identifier_release (ccache_iterator->identifier);
148 free (ccache_iterator->saved_ccache_name);
149 free (ccache_iterator);
150 }
151
152 return err;
153 }
154
155 /* ------------------------------------------------------------------------ */
156
ccapi_ccache_iterator_next(cc_ccache_iterator_t in_ccache_iterator,cc_ccache_t * out_ccache)157 cc_int32 ccapi_ccache_iterator_next (cc_ccache_iterator_t in_ccache_iterator,
158 cc_ccache_t *out_ccache)
159 {
160 cc_int32 err = ccNoError;
161 cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
162 k5_ipc_stream reply = NULL;
163 cci_identifier_t identifier = NULL;
164
165 if (!in_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
166 if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
167
168 if (!err) {
169 cc_uint32 initialized = 0;
170
171 err = cci_identifier_is_initialized (ccache_iterator->identifier,
172 &initialized);
173
174 if (!err && !initialized) {
175 /* server doesn't actually exist. Pretend we're empty. */
176 err = cci_check_error (ccIteratorEnd);
177 }
178 }
179
180 if (!err) {
181 err = cci_ipc_send (cci_ccache_iterator_next_msg_id,
182 ccache_iterator->identifier,
183 NULL,
184 &reply);
185 }
186
187 if (!err) {
188 err = cci_identifier_read (&identifier, reply);
189 }
190
191 if (!err) {
192 err = cci_ccache_new (out_ccache, identifier);
193 }
194
195 krb5int_ipc_stream_release (reply);
196 cci_identifier_release (identifier);
197
198 return cci_check_error (err);
199 }
200
201 /* ------------------------------------------------------------------------ */
202
ccapi_ccache_iterator_clone(cc_ccache_iterator_t in_ccache_iterator,cc_ccache_iterator_t * out_ccache_iterator)203 cc_int32 ccapi_ccache_iterator_clone (cc_ccache_iterator_t in_ccache_iterator,
204 cc_ccache_iterator_t *out_ccache_iterator)
205 {
206 cc_int32 err = ccNoError;
207 cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
208 k5_ipc_stream reply = NULL;
209 cc_uint32 initialized = 0;
210 cci_identifier_t identifier = NULL;
211
212 if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); }
213 if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
214
215 if (!err) {
216 err = cci_identifier_is_initialized (ccache_iterator->identifier,
217 &initialized);
218 }
219
220 if (!err) {
221 if (initialized) {
222 err = cci_ipc_send (cci_ccache_iterator_next_msg_id,
223 ccache_iterator->identifier,
224 NULL,
225 &reply);
226
227 if (!err) {
228 err = cci_identifier_read (&identifier, reply);
229 }
230
231 } else {
232 /* server doesn't actually exist. Make another dummy one. */
233 identifier = cci_identifier_uninitialized;
234 }
235 }
236
237 if (!err) {
238 err = cci_ccache_iterator_new (out_ccache_iterator, identifier);
239 }
240
241 cci_identifier_release (identifier);
242 krb5int_ipc_stream_release (reply);
243
244 return cci_check_error (err);
245 }
246
247 /* ------------------------------------------------------------------------ */
248
cci_ccache_iterator_get_saved_ccache_name(cc_ccache_iterator_t in_ccache_iterator,const char ** out_saved_ccache_name)249 cc_int32 cci_ccache_iterator_get_saved_ccache_name (cc_ccache_iterator_t in_ccache_iterator,
250 const char **out_saved_ccache_name)
251 {
252 cc_int32 err = ccNoError;
253 cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) in_ccache_iterator;
254
255 if (!in_ccache_iterator ) { err = cci_check_error (ccErrBadParam); }
256 if (!out_saved_ccache_name) { err = cci_check_error (ccErrBadParam); }
257
258 if (!err) {
259 *out_saved_ccache_name = ccache_iterator->saved_ccache_name;
260 }
261
262 return cci_check_error (err);
263 }
264
265 /* ------------------------------------------------------------------------ */
266
cci_ccache_iterator_set_saved_ccache_name(cc_ccache_iterator_t io_ccache_iterator,const char * in_saved_ccache_name)267 cc_int32 cci_ccache_iterator_set_saved_ccache_name (cc_ccache_iterator_t io_ccache_iterator,
268 const char *in_saved_ccache_name)
269 {
270 cc_int32 err = ccNoError;
271 cci_ccache_iterator_t ccache_iterator = (cci_ccache_iterator_t) io_ccache_iterator;
272 char *new_saved_ccache_name = NULL;
273
274 if (!io_ccache_iterator) { err = cci_check_error (ccErrBadParam); }
275
276 if (!err && in_saved_ccache_name) {
277 new_saved_ccache_name = strdup (in_saved_ccache_name);
278 if (!new_saved_ccache_name) { err = ccErrNoMem; }
279 }
280
281 if (!err) {
282 free (ccache_iterator->saved_ccache_name);
283
284 ccache_iterator->saved_ccache_name = new_saved_ccache_name;
285 new_saved_ccache_name = NULL; /* take ownership */
286 }
287
288 free (new_saved_ccache_name);
289
290 return cci_check_error (err);
291 }
292