xref: /freebsd/crypto/krb5/src/ccapi/lib/ccapi_ccache_iterator.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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