1 /* ccapi/server/ccs_ccache.c */
2 /*
3 * Copyright 2006, 2007 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 "ccs_common.h"
27 #include "ccs_os_notify.h"
28
29 struct ccs_ccache_d {
30 cci_identifier_t identifier;
31 ccs_lock_state_t lock_state;
32 cc_uint32 creds_version;
33 char *name;
34 char *v5_principal;
35 cc_time_t last_default_time;
36 cc_time_t last_changed_time;
37 cc_uint32 kdc_time_offset_v5_valid;
38 cc_time_t kdc_time_offset_v5;
39 ccs_credentials_list_t credentials;
40 ccs_callback_array_t change_callbacks;
41 };
42
43 struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, NULL, NULL };
44
45 /* ------------------------------------------------------------------------ */
46
ccs_ccache_new(ccs_ccache_t * out_ccache,cc_uint32 in_creds_version,const char * in_name,const char * in_principal,ccs_ccache_list_t io_ccache_list)47 cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache,
48 cc_uint32 in_creds_version,
49 const char *in_name,
50 const char *in_principal,
51 ccs_ccache_list_t io_ccache_list)
52 {
53 cc_int32 err = ccNoError;
54 ccs_ccache_t ccache = NULL;
55
56 if (!out_ccache ) { err = cci_check_error (ccErrBadParam); }
57 if (!in_name ) { err = cci_check_error (ccErrBadParam); }
58 if (!in_principal) { err = cci_check_error (ccErrBadParam); }
59
60 if (!err) {
61 ccache = malloc (sizeof (*ccache));
62 if (ccache) {
63 *ccache = ccs_ccache_initializer;
64 } else {
65 err = cci_check_error (ccErrNoMem);
66 }
67 }
68
69 if (!err) {
70 err = ccs_server_new_identifier (&ccache->identifier);
71 }
72
73 if (!err) {
74 err = ccs_lock_state_new (&ccache->lock_state,
75 ccErrInvalidCCache,
76 ccErrCCacheLocked,
77 ccErrCCacheUnlocked);
78 }
79
80 if (!err) {
81 ccache->name = strdup (in_name);
82 if (!ccache->name) { err = cci_check_error (ccErrNoMem); }
83 }
84
85 if (!err) {
86 ccache->creds_version = in_creds_version;
87
88 if (ccache->creds_version == cc_credentials_v5) {
89 ccache->v5_principal = strdup (in_principal);
90 if (!ccache->v5_principal) { err = cci_check_error (ccErrNoMem); }
91
92 } else {
93 err = cci_check_error (ccErrBadCredentialsVersion);
94 }
95 }
96
97 if (!err) {
98 err = ccs_credentials_list_new (&ccache->credentials);
99 }
100
101 if (!err) {
102 err = ccs_callback_array_new (&ccache->change_callbacks);
103 }
104
105 if (!err) {
106 cc_uint64 now = time (NULL);
107 cc_uint64 count = 0;
108
109 err = ccs_ccache_list_count (io_ccache_list, &count);
110
111 if (!err) {
112 /* first cache is default */
113 ccache->last_default_time = (count == 0) ? now : 0;
114 cci_debug_printf ("%s ccache->last_default_time is %d.",
115 __FUNCTION__, ccache->last_default_time);
116 ccache->last_changed_time = now;
117 }
118 }
119
120 if (!err) {
121 /* Add self to the list of ccaches */
122 err = ccs_ccache_list_add (io_ccache_list, ccache);
123 }
124
125 if (!err) {
126 *out_ccache = ccache;
127 ccache = NULL;
128 }
129
130 ccs_ccache_release (ccache);
131
132 return cci_check_error (err);
133 }
134
135 /* ------------------------------------------------------------------------ */
136
ccs_ccache_reset(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,cc_uint32 in_creds_version,const char * in_principal)137 cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache,
138 ccs_cache_collection_t io_cache_collection,
139 cc_uint32 in_creds_version,
140 const char *in_principal)
141 {
142 cc_int32 err = ccNoError;
143 char *v5_principal = NULL;
144 ccs_credentials_list_t credentials = NULL;
145
146 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
147 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
148 if (!in_principal ) { err = cci_check_error (ccErrBadParam); }
149
150 if (!err) {
151 io_ccache->creds_version = in_creds_version;
152
153 if (io_ccache->creds_version == cc_credentials_v5) {
154 v5_principal = strdup (in_principal);
155 if (!v5_principal) { err = cci_check_error (ccErrNoMem); }
156
157 } else {
158 err = cci_check_error (ccErrBadCredentialsVersion);
159 }
160 }
161
162 if (!err) {
163 err = ccs_credentials_list_new (&credentials);
164 }
165
166 if (!err) {
167 io_ccache->kdc_time_offset_v5 = 0;
168 io_ccache->kdc_time_offset_v5_valid = 0;
169
170 if (io_ccache->v5_principal) { free (io_ccache->v5_principal); }
171 io_ccache->v5_principal = v5_principal;
172 v5_principal = NULL; /* take ownership */
173
174 ccs_credentials_list_release (io_ccache->credentials);
175 io_ccache->credentials = credentials;
176 credentials = NULL; /* take ownership */
177
178 err = ccs_ccache_changed (io_ccache, io_cache_collection);
179 }
180
181 free (v5_principal);
182 ccs_credentials_list_release (credentials);
183
184 return cci_check_error (err);
185 }
186
187 /* ------------------------------------------------------------------------ */
188
ccs_ccache_swap_contents(ccs_ccache_t io_source_ccache,ccs_ccache_t io_destination_ccache,ccs_cache_collection_t io_cache_collection)189 cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache,
190 ccs_ccache_t io_destination_ccache,
191 ccs_cache_collection_t io_cache_collection)
192 {
193 cc_int32 err = ccNoError;
194
195 if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); }
196 if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }
197
198 if (!err) {
199 struct ccs_ccache_d temp_ccache = *io_destination_ccache;
200
201 /* swap everything */
202 *io_destination_ccache = *io_source_ccache;
203 *io_source_ccache = temp_ccache;
204
205 /* swap back the name and identifier */
206 io_source_ccache->identifier = io_destination_ccache->identifier;
207 io_destination_ccache->identifier = temp_ccache.identifier;
208
209 io_source_ccache->name = io_destination_ccache->name;
210 io_destination_ccache->name = temp_ccache.name;
211 }
212
213 if (!err) {
214 err = ccs_ccache_changed (io_source_ccache, io_cache_collection);
215 }
216
217 if (!err) {
218 err = ccs_ccache_changed (io_destination_ccache, io_cache_collection);
219 }
220
221 return cci_check_error (err);
222 }
223
224 /* ------------------------------------------------------------------------ */
225
ccs_ccache_release(ccs_ccache_t io_ccache)226 cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache)
227 {
228 cc_int32 err = ccNoError;
229
230 if (!err && io_ccache) {
231 cci_identifier_release (io_ccache->identifier);
232 ccs_lock_state_release (io_ccache->lock_state);
233 free (io_ccache->name);
234 free (io_ccache->v5_principal);
235 ccs_credentials_list_release (io_ccache->credentials);
236 ccs_callback_array_release (io_ccache->change_callbacks);
237 free (io_ccache);
238 }
239
240 return cci_check_error (err);
241 }
242
243 #ifdef TARGET_OS_MAC
244 #pragma mark -
245 #endif
246
247 /* ------------------------------------------------------------------------ */
248
ccs_ccache_compare_identifier(ccs_ccache_t in_ccache,cci_identifier_t in_identifier,cc_uint32 * out_equal)249 cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache,
250 cci_identifier_t in_identifier,
251 cc_uint32 *out_equal)
252 {
253 cc_int32 err = ccNoError;
254
255 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
256 if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
257 if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
258
259 if (!err) {
260 err = cci_identifier_compare (in_ccache->identifier,
261 in_identifier,
262 out_equal);
263 }
264
265 return cci_check_error (err);
266 }
267
268 /* ------------------------------------------------------------------------ */
269
ccs_ccache_compare_name(ccs_ccache_t in_ccache,const char * in_name,cc_uint32 * out_equal)270 cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache,
271 const char *in_name,
272 cc_uint32 *out_equal)
273 {
274 cc_int32 err = ccNoError;
275
276 if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
277 if (!in_name ) { err = cci_check_error (ccErrBadParam); }
278 if (!out_equal) { err = cci_check_error (ccErrBadParam); }
279
280 if (!err) {
281 *out_equal = (strcmp (in_ccache->name, in_name) == 0);
282 }
283
284 return cci_check_error (err);
285 }
286
287 #ifdef TARGET_OS_MAC
288 #pragma mark -
289 #endif
290
291 /* ------------------------------------------------------------------------ */
292
ccs_ccache_changed(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection)293 cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache,
294 ccs_cache_collection_t io_cache_collection)
295 {
296 cc_int32 err = ccNoError;
297 k5_ipc_stream reply_data = NULL;
298
299 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
300 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
301
302 if (!err) {
303 cc_time_t now = time (NULL);
304
305 if (io_ccache->last_changed_time < now) {
306 io_ccache->last_changed_time = now;
307 } else {
308 io_ccache->last_changed_time++;
309 }
310 }
311
312 if (!err) {
313 err = ccs_cache_collection_changed (io_cache_collection);
314 }
315
316 if (!err) {
317 err = krb5int_ipc_stream_new (&reply_data);
318 }
319
320 if (!err) {
321 err = krb5int_ipc_stream_write_time (reply_data, io_ccache->last_changed_time);
322 }
323
324 if (!err) {
325 /* Loop over callbacks sending messages to them */
326 cc_uint64 i;
327 cc_uint64 count = ccs_callback_array_count (io_ccache->change_callbacks);
328
329 for (i = 0; !err && i < count; i++) {
330 ccs_callback_t callback = ccs_callback_array_object_at_index (io_ccache->change_callbacks, i);
331
332 err = ccs_callback_reply_to_client (callback, reply_data);
333
334 if (!err) {
335 cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
336 err = ccs_callback_array_remove (io_ccache->change_callbacks, i);
337 break;
338 }
339 }
340 }
341
342 if (!err) {
343 err = ccs_os_notify_ccache_changed (io_cache_collection,
344 io_ccache->name);
345 }
346
347 krb5int_ipc_stream_release (reply_data);
348
349 return cci_check_error (err);
350 }
351
352 /* ------------------------------------------------------------------------ */
353
ccs_ccache_invalidate_change_callback(ccs_callback_owner_t io_ccache,ccs_callback_t in_callback)354 static cc_int32 ccs_ccache_invalidate_change_callback (ccs_callback_owner_t io_ccache,
355 ccs_callback_t in_callback)
356 {
357 cc_int32 err = ccNoError;
358
359 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
360 if (!in_callback) { err = cci_check_error (ccErrBadParam); }
361
362 if (!err) {
363 /* Remove callback */
364 ccs_ccache_t ccache = (ccs_ccache_t) io_ccache;
365 cc_uint64 i;
366 cc_uint64 count = ccs_callback_array_count (ccache->change_callbacks);
367
368 for (i = 0; !err && i < count; i++) {
369 ccs_callback_t callback = ccs_callback_array_object_at_index (ccache->change_callbacks, i);
370
371 if (callback == in_callback) {
372 cci_debug_printf ("%s: Removing callback reference %p.", __FUNCTION__, callback);
373 err = ccs_callback_array_remove (ccache->change_callbacks, i);
374 break;
375 }
376 }
377 }
378
379 return cci_check_error (err);
380 }
381
382 /* ------------------------------------------------------------------------ */
383
ccs_ccache_notify_default_state_changed(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,cc_uint32 in_new_default_state)384 cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache,
385 ccs_cache_collection_t io_cache_collection,
386 cc_uint32 in_new_default_state)
387 {
388 cc_int32 err = ccNoError;
389
390 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
391 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
392
393 if (!err && in_new_default_state) {
394 cc_time_t now = time (NULL);
395
396 if (io_ccache->last_default_time < now) {
397 io_ccache->last_default_time = now;
398 } else {
399 io_ccache->last_default_time++;
400 }
401 }
402
403 if (!err) {
404 err = ccs_ccache_changed (io_ccache, io_cache_collection);
405 }
406
407 return cci_check_error (err);
408 }
409
410 #ifdef TARGET_OS_MAC
411 #pragma mark -
412 #endif
413
414 /* ------------------------------------------------------------------------ */
415
ccs_ccache_find_credentials_iterator(ccs_ccache_t in_ccache,cci_identifier_t in_identifier,ccs_credentials_iterator_t * out_credentials_iterator)416 cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache,
417 cci_identifier_t in_identifier,
418 ccs_credentials_iterator_t *out_credentials_iterator)
419 {
420 cc_int32 err = ccNoError;
421
422 if (!in_ccache ) { err = cci_check_error (ccErrBadParam); }
423 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); }
424 if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
425
426 if (!err) {
427 err = ccs_credentials_list_find_iterator (in_ccache->credentials,
428 in_identifier,
429 out_credentials_iterator);
430 }
431
432 // Don't report ccErrInvalidCredentials to the log file. Non-fatal.
433 return (err == ccErrInvalidCredentials) ? err : cci_check_error (err);
434 }
435
436 #ifdef TARGET_OS_MAC
437 #pragma mark -
438 #endif
439
440 /* ------------------------------------------------------------------------ */
441
ccs_ccache_write(ccs_ccache_t in_ccache,k5_ipc_stream io_stream)442 cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache,
443 k5_ipc_stream io_stream)
444 {
445 cc_int32 err = ccNoError;
446
447 if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
448 if (!io_stream) { err = cci_check_error (ccErrBadParam); }
449
450 if (!err) {
451 err = cci_identifier_write (in_ccache->identifier, io_stream);
452 }
453
454 return cci_check_error (err);
455 }
456
457
458 /* ------------------------------------------------------------------------ */
459
ccs_ccache_write_name(ccs_ccache_t in_ccache,k5_ipc_stream io_stream)460 cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache,
461 k5_ipc_stream io_stream)
462 {
463 cc_int32 err = ccNoError;
464
465 if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
466 if (!io_stream) { err = cci_check_error (ccErrBadParam); }
467
468 if (!err) {
469 err = krb5int_ipc_stream_write_string (io_stream, in_ccache->name);
470 }
471
472 return cci_check_error (err);
473 }
474
475 #ifdef TARGET_OS_MAC
476 #pragma mark -
477 #pragma mark -- IPC Messages --
478 #endif
479
480 /* ------------------------------------------------------------------------ */
481
ccs_ccache_destroy(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)482 static cc_int32 ccs_ccache_destroy (ccs_ccache_t io_ccache,
483 ccs_cache_collection_t io_cache_collection,
484 k5_ipc_stream in_request_data,
485 k5_ipc_stream io_reply_data)
486 {
487 cc_int32 err = ccNoError;
488
489 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
490 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
491 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
492 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
493
494 if (!err) {
495 err = ccs_cache_collection_destroy_ccache (io_cache_collection,
496 io_ccache->identifier);
497 }
498
499 if (!err) {
500 /* ccache has been destroyed so just mark the cache collection */
501 err = ccs_cache_collection_changed (io_cache_collection);
502 }
503
504 return cci_check_error (err);
505 }
506
507 /* ------------------------------------------------------------------------ */
508
ccs_ccache_set_default(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)509 static cc_int32 ccs_ccache_set_default (ccs_ccache_t io_ccache,
510 ccs_cache_collection_t io_cache_collection,
511 k5_ipc_stream in_request_data,
512 k5_ipc_stream io_reply_data)
513 {
514 cc_int32 err = ccNoError;
515
516 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
517 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
518 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
519 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
520
521 if (!err) {
522 err = ccs_cache_collection_set_default_ccache (io_cache_collection,
523 io_ccache->identifier);
524 }
525
526 return cci_check_error (err);
527 }
528
529 /* ------------------------------------------------------------------------ */
530
ccs_ccache_get_credentials_version(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)531 static cc_int32 ccs_ccache_get_credentials_version (ccs_ccache_t io_ccache,
532 ccs_cache_collection_t io_cache_collection,
533 k5_ipc_stream in_request_data,
534 k5_ipc_stream io_reply_data)
535 {
536 cc_int32 err = ccNoError;
537
538 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
539 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
540 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
541 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
542
543 if (!err) {
544 err = krb5int_ipc_stream_write_uint32 (io_reply_data, io_ccache->creds_version);
545 }
546
547 return cci_check_error (err);
548 }
549
550 /* ------------------------------------------------------------------------ */
551
ccs_ccache_get_name(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)552 static cc_int32 ccs_ccache_get_name (ccs_ccache_t io_ccache,
553 ccs_cache_collection_t io_cache_collection,
554 k5_ipc_stream in_request_data,
555 k5_ipc_stream io_reply_data)
556 {
557 cc_int32 err = ccNoError;
558
559 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
560 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
561 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
562 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
563
564 if (!err) {
565 err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->name);
566 }
567
568 return cci_check_error (err);
569 }
570
571 /* ------------------------------------------------------------------------ */
572
ccs_ccache_get_principal(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)573 static cc_int32 ccs_ccache_get_principal (ccs_ccache_t io_ccache,
574 ccs_cache_collection_t io_cache_collection,
575 k5_ipc_stream in_request_data,
576 k5_ipc_stream io_reply_data)
577 {
578 cc_int32 err = ccNoError;
579 cc_uint32 version = 0;
580
581 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
582 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
583 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
584 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
585
586 if (!err) {
587 err = krb5int_ipc_stream_read_uint32 (in_request_data, &version);
588 }
589
590 if (!err) {
591 if (version == cc_credentials_v5) {
592 err = krb5int_ipc_stream_write_string (io_reply_data, io_ccache->v5_principal);
593
594 } else {
595 err = cci_check_error (ccErrBadCredentialsVersion);
596 }
597 }
598
599 return cci_check_error (err);
600 }
601
602 /* ------------------------------------------------------------------------ */
603
ccs_ccache_set_principal(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)604 static cc_int32 ccs_ccache_set_principal (ccs_ccache_t io_ccache,
605 ccs_cache_collection_t io_cache_collection,
606 k5_ipc_stream in_request_data,
607 k5_ipc_stream io_reply_data)
608 {
609 cc_int32 err = ccNoError;
610 cc_uint32 version = 0;
611 char *principal = NULL;
612
613 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
614 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
615 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
616 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
617
618 if (!err) {
619 err = krb5int_ipc_stream_read_uint32 (in_request_data, &version);
620 }
621
622 if (!err) {
623 err = krb5int_ipc_stream_read_string (in_request_data, &principal);
624 }
625
626 if (!err) {
627 /* reset KDC time offsets because they are per-KDC */
628 if (version == cc_credentials_v5) {
629 io_ccache->kdc_time_offset_v5 = 0;
630 io_ccache->kdc_time_offset_v5_valid = 0;
631
632 if (io_ccache->v5_principal) { free (io_ccache->v5_principal); }
633 io_ccache->v5_principal = principal;
634 principal = NULL; /* take ownership */
635
636 } else {
637 err = cci_check_error (ccErrBadCredentialsVersion);
638 }
639 }
640
641 if (!err) {
642 io_ccache->creds_version |= version;
643
644 err = ccs_ccache_changed (io_ccache, io_cache_collection);
645 }
646
647 krb5int_ipc_stream_free_string (principal);
648
649 return cci_check_error (err);
650 }
651
652 /* ------------------------------------------------------------------------ */
653
ccs_ccache_store_credentials(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)654 static cc_int32 ccs_ccache_store_credentials (ccs_ccache_t io_ccache,
655 ccs_cache_collection_t io_cache_collection,
656 k5_ipc_stream in_request_data,
657 k5_ipc_stream io_reply_data)
658 {
659 cc_int32 err = ccNoError;
660 ccs_credentials_t credentials = NULL;
661
662 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
663 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
664 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
665 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
666
667 if (!err) {
668 err = ccs_credentials_new (&credentials, in_request_data,
669 io_ccache->creds_version,
670 io_ccache->credentials);
671 }
672
673 if (!err) {
674 err = ccs_ccache_changed (io_ccache, io_cache_collection);
675 }
676
677
678 return cci_check_error (err);
679 }
680
681 /* ------------------------------------------------------------------------ */
682
ccs_ccache_remove_credentials(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)683 static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t io_ccache,
684 ccs_cache_collection_t io_cache_collection,
685 k5_ipc_stream in_request_data,
686 k5_ipc_stream io_reply_data)
687 {
688 cc_int32 err = ccNoError;
689 cci_identifier_t credentials_identifier = NULL;
690
691 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
692 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
693 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
694 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
695
696 if (!err) {
697 err = cci_identifier_read (&credentials_identifier, in_request_data);
698 }
699
700 if (!err) {
701 err = ccs_credentials_list_remove (io_ccache->credentials, credentials_identifier);
702 }
703
704 if (!err) {
705 err = ccs_ccache_changed (io_ccache, io_cache_collection);
706 }
707
708 cci_identifier_release (credentials_identifier);
709
710 return cci_check_error (err);
711 }
712
713 /* ------------------------------------------------------------------------ */
714
ccs_ccache_new_credentials_iterator(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,ccs_pipe_t in_client_pipe,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)715 static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache,
716 ccs_cache_collection_t io_cache_collection,
717 ccs_pipe_t in_client_pipe,
718 k5_ipc_stream in_request_data,
719 k5_ipc_stream io_reply_data)
720 {
721 cc_int32 err = ccNoError;
722 ccs_credentials_iterator_t credentials_iterator = NULL;
723
724 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
725 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
726 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
727 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
728
729 if (!err) {
730 err = ccs_credentials_list_new_iterator (io_ccache->credentials,
731 in_client_pipe,
732 &credentials_iterator);
733 }
734
735 if (!err) {
736 err = ccs_credentials_list_iterator_write (credentials_iterator, io_reply_data);
737 }
738
739 return cci_check_error (err);
740 }
741
742 /* ------------------------------------------------------------------------ */
743
ccs_ccache_move(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)744 static cc_int32 ccs_ccache_move (ccs_ccache_t io_ccache,
745 ccs_cache_collection_t io_cache_collection,
746 k5_ipc_stream in_request_data,
747 k5_ipc_stream io_reply_data)
748 {
749 cc_int32 err = ccNoError;
750 cci_identifier_t source_identifier = NULL;
751
752 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
753 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
754 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
755 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
756
757 if (!err) {
758 /* Note: message is sent as the destination ccache to avoid */
759 /* extra work on the server when deleting it the source ccache. */
760 err = cci_identifier_read (&source_identifier, in_request_data);
761 }
762
763 if (!err) {
764 err = ccs_ccache_collection_move_ccache (io_cache_collection,
765 source_identifier,
766 io_ccache);
767 }
768
769 if (!err) {
770 err = ccs_ccache_changed (io_ccache, io_cache_collection);
771 }
772
773 cci_identifier_release (source_identifier);
774
775 return cci_check_error (err);
776 }
777
778 /* ------------------------------------------------------------------------ */
779
ccs_ccache_lock(ccs_pipe_t in_client_pipe,ccs_pipe_t in_reply_pipe,ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,cc_uint32 * out_will_block,k5_ipc_stream io_reply_data)780 static cc_int32 ccs_ccache_lock (ccs_pipe_t in_client_pipe,
781 ccs_pipe_t in_reply_pipe,
782 ccs_ccache_t io_ccache,
783 ccs_cache_collection_t io_cache_collection,
784 k5_ipc_stream in_request_data,
785 cc_uint32 *out_will_block,
786 k5_ipc_stream io_reply_data)
787 {
788 cc_int32 err = ccNoError;
789 cc_uint32 lock_type;
790 cc_uint32 block;
791
792 if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
793 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
794 if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
795 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
796 if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
797 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
798
799 if (!err) {
800 err = krb5int_ipc_stream_read_uint32 (in_request_data, &lock_type);
801 }
802
803 if (!err) {
804 err = krb5int_ipc_stream_read_uint32 (in_request_data, &block);
805 }
806
807 if (!err) {
808 err = ccs_lock_state_add (io_ccache->lock_state,
809 in_client_pipe, in_reply_pipe,
810 lock_type, block, out_will_block);
811 }
812
813 return cci_check_error (err);
814 }
815
816 /* ------------------------------------------------------------------------ */
817
ccs_ccache_unlock(ccs_pipe_t in_client_pipe,ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)818 static cc_int32 ccs_ccache_unlock (ccs_pipe_t in_client_pipe,
819 ccs_ccache_t io_ccache,
820 ccs_cache_collection_t io_cache_collection,
821 k5_ipc_stream in_request_data,
822 k5_ipc_stream io_reply_data)
823 {
824 cc_int32 err = ccNoError;
825
826 if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
827 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
828 if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
829 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
830 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
831
832 if (!err) {
833 err = ccs_lock_state_remove (io_ccache->lock_state, in_client_pipe);
834 }
835
836 return cci_check_error (err);
837 }
838
839 /* ------------------------------------------------------------------------ */
840
ccs_ccache_get_last_default_time(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)841 static cc_int32 ccs_ccache_get_last_default_time (ccs_ccache_t io_ccache,
842 ccs_cache_collection_t io_cache_collection,
843 k5_ipc_stream in_request_data,
844 k5_ipc_stream io_reply_data)
845 {
846 cc_int32 err = ccNoError;
847
848 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
849 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
850 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
851 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
852
853 if (!err && io_ccache->last_default_time == 0) {
854 err = cci_check_error (ccErrNeverDefault);
855 }
856
857 if (!err) {
858 err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_default_time);
859 }
860
861 return cci_check_error (err);
862 }
863
864 /* ------------------------------------------------------------------------ */
865
ccs_ccache_get_change_time(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)866 static cc_int32 ccs_ccache_get_change_time (ccs_ccache_t io_ccache,
867 ccs_cache_collection_t io_cache_collection,
868 k5_ipc_stream in_request_data,
869 k5_ipc_stream io_reply_data)
870 {
871 cc_int32 err = ccNoError;
872
873 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
874 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
875 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
876 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
877
878 if (!err) {
879 err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time);
880 }
881
882 return cci_check_error (err);
883 }
884
885 /* ------------------------------------------------------------------------ */
886
ccs_ccache_wait_for_change(ccs_pipe_t in_client_pipe,ccs_pipe_t in_reply_pipe,ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data,cc_uint32 * out_will_block)887 static cc_int32 ccs_ccache_wait_for_change (ccs_pipe_t in_client_pipe,
888 ccs_pipe_t in_reply_pipe,
889 ccs_ccache_t io_ccache,
890 ccs_cache_collection_t io_cache_collection,
891 k5_ipc_stream in_request_data,
892 k5_ipc_stream io_reply_data,
893 cc_uint32 *out_will_block)
894 {
895 cc_int32 err = ccNoError;
896 cc_time_t last_wait_for_change_time = 0;
897 cc_uint32 will_block = 0;
898
899 if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
900 if (!ccs_pipe_valid (in_reply_pipe )) { err = cci_check_error (ccErrBadParam); }
901 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
902 if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
903 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
904 if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
905
906 if (!err) {
907 err = krb5int_ipc_stream_read_time (in_request_data, &last_wait_for_change_time);
908 }
909
910 if (!err) {
911 if (last_wait_for_change_time < io_ccache->last_changed_time) {
912 cci_debug_printf ("%s returning immediately", __FUNCTION__);
913 err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->last_changed_time);
914
915 } else {
916 ccs_callback_t callback = NULL;
917
918 err = ccs_callback_new (&callback,
919 ccErrInvalidCCache,
920 in_client_pipe,
921 in_reply_pipe,
922 (ccs_callback_owner_t) io_ccache,
923 ccs_ccache_invalidate_change_callback);
924
925 if (!err) {
926 err = ccs_callback_array_insert (io_ccache->change_callbacks, callback,
927 ccs_callback_array_count (io_ccache->change_callbacks));
928 if (!err) { callback = NULL; /* take ownership */ }
929
930 cci_debug_printf ("%s blocking", __FUNCTION__);
931 will_block = 1;
932 }
933
934 ccs_callback_release (callback);
935 }
936 }
937
938 if (!err) {
939 *out_will_block = will_block;
940 }
941
942 return cci_check_error (err);
943 }
944
945 /* ------------------------------------------------------------------------ */
946
ccs_ccache_get_kdc_time_offset(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)947 static cc_int32 ccs_ccache_get_kdc_time_offset (ccs_ccache_t io_ccache,
948 ccs_cache_collection_t io_cache_collection,
949 k5_ipc_stream in_request_data,
950 k5_ipc_stream io_reply_data)
951 {
952 cc_int32 err = ccNoError;
953 cc_uint32 cred_vers = 0;
954
955 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
956 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
957 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
958 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
959
960 if (!err) {
961 err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
962 }
963
964 if (!err) {
965 if (cred_vers == cc_credentials_v5) {
966 if (io_ccache->kdc_time_offset_v5_valid) {
967 err = krb5int_ipc_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v5);
968 } else {
969 err = cci_check_error (ccErrTimeOffsetNotSet);
970 }
971
972 } else {
973 err = cci_check_error (ccErrBadCredentialsVersion);
974 }
975 }
976
977 return cci_check_error (err);
978 }
979
980 /* ------------------------------------------------------------------------ */
981
ccs_ccache_set_kdc_time_offset(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)982 static cc_int32 ccs_ccache_set_kdc_time_offset (ccs_ccache_t io_ccache,
983 ccs_cache_collection_t io_cache_collection,
984 k5_ipc_stream in_request_data,
985 k5_ipc_stream io_reply_data)
986 {
987 cc_int32 err = ccNoError;
988 cc_uint32 cred_vers = 0;
989
990 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
991 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
992 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
993 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
994
995 if (!err) {
996 err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
997 }
998
999 if (!err) {
1000 if (cred_vers == cc_credentials_v5) {
1001 err = krb5int_ipc_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v5);
1002
1003 if (!err) {
1004 io_ccache->kdc_time_offset_v5_valid = 1;
1005 }
1006 } else {
1007 err = cci_check_error (ccErrBadCredentialsVersion);
1008 }
1009 }
1010
1011 if (!err) {
1012 err = ccs_ccache_changed (io_ccache, io_cache_collection);
1013 }
1014
1015 return cci_check_error (err);
1016 }
1017
1018 /* ------------------------------------------------------------------------ */
1019
ccs_ccache_clear_kdc_time_offset(ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,k5_ipc_stream in_request_data,k5_ipc_stream io_reply_data)1020 static cc_int32 ccs_ccache_clear_kdc_time_offset (ccs_ccache_t io_ccache,
1021 ccs_cache_collection_t io_cache_collection,
1022 k5_ipc_stream in_request_data,
1023 k5_ipc_stream io_reply_data)
1024 {
1025 cc_int32 err = ccNoError;
1026 cc_uint32 cred_vers = 0;
1027
1028 if (!io_ccache ) { err = cci_check_error (ccErrBadParam); }
1029 if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); }
1030 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
1031 if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); }
1032
1033 if (!err) {
1034 err = krb5int_ipc_stream_read_uint32 (in_request_data, &cred_vers);
1035 }
1036
1037 if (!err) {
1038 if (cred_vers == cc_credentials_v5) {
1039 io_ccache->kdc_time_offset_v5 = 0;
1040 io_ccache->kdc_time_offset_v5_valid = 0;
1041
1042 } else {
1043 err = cci_check_error (ccErrBadCredentialsVersion);
1044 }
1045 }
1046
1047 if (!err) {
1048 err = ccs_ccache_changed (io_ccache, io_cache_collection);
1049 }
1050
1051 return cci_check_error (err);
1052 }
1053
1054 #ifdef TARGET_OS_MAC
1055 #pragma mark -
1056 #endif
1057
1058 /* ------------------------------------------------------------------------ */
1059
ccs_ccache_handle_message(ccs_pipe_t in_client_pipe,ccs_pipe_t in_reply_pipe,ccs_ccache_t io_ccache,ccs_cache_collection_t io_cache_collection,enum cci_msg_id_t in_request_name,k5_ipc_stream in_request_data,cc_uint32 * out_will_block,k5_ipc_stream * out_reply_data)1060 cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe,
1061 ccs_pipe_t in_reply_pipe,
1062 ccs_ccache_t io_ccache,
1063 ccs_cache_collection_t io_cache_collection,
1064 enum cci_msg_id_t in_request_name,
1065 k5_ipc_stream in_request_data,
1066 cc_uint32 *out_will_block,
1067 k5_ipc_stream *out_reply_data)
1068 {
1069 cc_int32 err = ccNoError;
1070 cc_uint32 will_block = 0;
1071 k5_ipc_stream reply_data = NULL;
1072
1073 if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); }
1074 if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); }
1075 if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); }
1076 if (!in_request_data ) { err = cci_check_error (ccErrBadParam); }
1077 if (!out_will_block ) { err = cci_check_error (ccErrBadParam); }
1078 if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); }
1079
1080 if (!err) {
1081 err = krb5int_ipc_stream_new (&reply_data);
1082 }
1083
1084 if (!err) {
1085 if (in_request_name == cci_ccache_destroy_msg_id) {
1086 err = ccs_ccache_destroy (io_ccache, io_cache_collection,
1087 in_request_data, reply_data);
1088
1089 } else if (in_request_name == cci_ccache_set_default_msg_id) {
1090 err = ccs_ccache_set_default (io_ccache, io_cache_collection,
1091 in_request_data, reply_data);
1092
1093 } else if (in_request_name == cci_ccache_get_credentials_version_msg_id) {
1094 err = ccs_ccache_get_credentials_version (io_ccache, io_cache_collection,
1095 in_request_data, reply_data);
1096
1097 } else if (in_request_name == cci_ccache_get_name_msg_id) {
1098 err = ccs_ccache_get_name (io_ccache, io_cache_collection,
1099 in_request_data, reply_data);
1100
1101 } else if (in_request_name == cci_ccache_get_principal_msg_id) {
1102 err = ccs_ccache_get_principal (io_ccache, io_cache_collection,
1103 in_request_data, reply_data);
1104
1105 } else if (in_request_name == cci_ccache_set_principal_msg_id) {
1106 err = ccs_ccache_set_principal (io_ccache, io_cache_collection,
1107 in_request_data, reply_data);
1108
1109 } else if (in_request_name == cci_ccache_store_credentials_msg_id) {
1110 err = ccs_ccache_store_credentials (io_ccache, io_cache_collection,
1111 in_request_data, reply_data);
1112
1113 } else if (in_request_name == cci_ccache_remove_credentials_msg_id) {
1114 err = ccs_ccache_remove_credentials (io_ccache, io_cache_collection,
1115 in_request_data, reply_data);
1116
1117 } else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) {
1118 err = ccs_ccache_new_credentials_iterator (io_ccache,
1119 io_cache_collection,
1120 in_client_pipe,
1121 in_request_data,
1122 reply_data);
1123
1124 } else if (in_request_name == cci_ccache_move_msg_id) {
1125 err = ccs_ccache_move (io_ccache, io_cache_collection,
1126 in_request_data, reply_data);
1127
1128 } else if (in_request_name == cci_ccache_lock_msg_id) {
1129 err = ccs_ccache_lock (in_client_pipe, in_reply_pipe,
1130 io_ccache, io_cache_collection,
1131 in_request_data,
1132 &will_block, reply_data);
1133
1134 } else if (in_request_name == cci_ccache_unlock_msg_id) {
1135 err = ccs_ccache_unlock (in_client_pipe,
1136 io_ccache, io_cache_collection,
1137 in_request_data, reply_data);
1138
1139 } else if (in_request_name == cci_ccache_get_last_default_time_msg_id) {
1140 err = ccs_ccache_get_last_default_time (io_ccache, io_cache_collection,
1141 in_request_data, reply_data);
1142
1143 } else if (in_request_name == cci_ccache_get_change_time_msg_id) {
1144 err = ccs_ccache_get_change_time (io_ccache, io_cache_collection,
1145 in_request_data, reply_data);
1146
1147 } else if (in_request_name == cci_ccache_wait_for_change_msg_id) {
1148 err = ccs_ccache_wait_for_change (in_client_pipe, in_reply_pipe,
1149 io_ccache, io_cache_collection,
1150 in_request_data, reply_data,
1151 &will_block);
1152
1153 } else if (in_request_name == cci_ccache_get_kdc_time_offset_msg_id) {
1154 err = ccs_ccache_get_kdc_time_offset (io_ccache, io_cache_collection,
1155 in_request_data, reply_data);
1156
1157 } else if (in_request_name == cci_ccache_set_kdc_time_offset_msg_id) {
1158 err = ccs_ccache_set_kdc_time_offset (io_ccache, io_cache_collection,
1159 in_request_data, reply_data);
1160
1161 } else if (in_request_name == cci_ccache_clear_kdc_time_offset_msg_id) {
1162 err = ccs_ccache_clear_kdc_time_offset (io_ccache, io_cache_collection,
1163 in_request_data, reply_data);
1164
1165 } else {
1166 err = ccErrBadInternalMessage;
1167 }
1168 }
1169
1170 if (!err) {
1171 *out_will_block = will_block;
1172 if (!will_block) {
1173 *out_reply_data = reply_data;
1174 reply_data = NULL; /* take ownership */
1175 } else {
1176 *out_reply_data = NULL;
1177 }
1178 }
1179
1180 krb5int_ipc_stream_release (reply_data);
1181
1182 return cci_check_error (err);
1183 }
1184