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 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 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 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 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 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 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 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