1 /* ccapi/lib/ccapi_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 "ccapi_ccache.h"
27 
28 #include "ccapi_string.h"
29 #include "ccapi_credentials.h"
30 #include "ccapi_credentials_iterator.h"
31 #include "ccapi_ipc.h"
32 
33 /* ------------------------------------------------------------------------ */
34 
35 typedef struct cci_ccache_d {
36     cc_ccache_f *functions;
37 #if TARGET_OS_MAC
38     cc_ccache_f *vector_functions;
39 #endif
40     cci_identifier_t identifier;
41     cc_time_t last_wait_for_change_time;
42     cc_uint32 compat_version;
43 } *cci_ccache_t;
44 
45 /* ------------------------------------------------------------------------ */
46 
47 struct cci_ccache_d cci_ccache_initializer = {
48     NULL
49     VECTOR_FUNCTIONS_INITIALIZER,
50     NULL,
51     0
52 };
53 
54 cc_ccache_f cci_ccache_f_initializer = {
55     ccapi_ccache_release,
56     ccapi_ccache_destroy,
57     ccapi_ccache_set_default,
58     ccapi_ccache_get_credentials_version,
59     ccapi_ccache_get_name,
60     ccapi_ccache_get_principal,
61     ccapi_ccache_set_principal,
62     ccapi_ccache_store_credentials,
63     ccapi_ccache_remove_credentials,
64     ccapi_ccache_new_credentials_iterator,
65     ccapi_ccache_move,
66     ccapi_ccache_lock,
67     ccapi_ccache_unlock,
68     ccapi_ccache_get_last_default_time,
69     ccapi_ccache_get_change_time,
70     ccapi_ccache_compare,
71     ccapi_ccache_get_kdc_time_offset,
72     ccapi_ccache_set_kdc_time_offset,
73     ccapi_ccache_clear_kdc_time_offset,
74     ccapi_ccache_wait_for_change
75 };
76 
77 /* ------------------------------------------------------------------------ */
78 
cci_ccache_new(cc_ccache_t * out_ccache,cci_identifier_t in_identifier)79 cc_int32 cci_ccache_new (cc_ccache_t      *out_ccache,
80                          cci_identifier_t  in_identifier)
81 {
82     cc_int32 err = ccNoError;
83     cci_ccache_t ccache = NULL;
84 
85     if (!out_ccache   ) { err = cci_check_error (ccErrBadParam); }
86     if (!in_identifier) { err = cci_check_error (ccErrBadParam); }
87 
88     if (!err) {
89         ccache = malloc (sizeof (*ccache));
90         if (ccache) {
91             *ccache = cci_ccache_initializer;
92         } else {
93             err = cci_check_error (ccErrNoMem);
94         }
95     }
96 
97     if (!err) {
98         ccache->functions = malloc (sizeof (*ccache->functions));
99         if (ccache->functions) {
100             *ccache->functions = cci_ccache_f_initializer;
101         } else {
102             err = cci_check_error (ccErrNoMem);
103         }
104     }
105 
106     if (!err) {
107         err = cci_identifier_copy (&ccache->identifier, in_identifier);
108     }
109 
110     if (!err) {
111         *out_ccache = (cc_ccache_t) ccache;
112         ccache = NULL; /* take ownership */
113     }
114 
115     ccapi_ccache_release ((cc_ccache_t) ccache);
116 
117     return cci_check_error (err);
118 }
119 
120 /* ------------------------------------------------------------------------ */
121 
cci_ccache_write(cc_ccache_t in_ccache,k5_ipc_stream in_stream)122 cc_int32 cci_ccache_write (cc_ccache_t  in_ccache,
123                            k5_ipc_stream in_stream)
124 {
125     cc_int32 err = ccNoError;
126     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
127 
128     if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
129     if (!in_stream) { err = cci_check_error (ccErrBadParam); }
130 
131     if (!err) {
132         err = cci_identifier_write (ccache->identifier, in_stream);
133     }
134 
135     return cci_check_error (err);
136 }
137 
138 #ifdef TARGET_OS_MAC
139 #pragma mark -
140 #endif
141 
142 /* ------------------------------------------------------------------------ */
143 
ccapi_ccache_release(cc_ccache_t io_ccache)144 cc_int32 ccapi_ccache_release (cc_ccache_t io_ccache)
145 {
146     cc_int32 err = ccNoError;
147     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
148 
149     if (!io_ccache) { err = ccErrBadParam; }
150 
151     if (!err) {
152         cci_identifier_release (ccache->identifier);
153 
154         free ((char *) ccache->functions);
155         free (ccache);
156     }
157 
158     return err;
159 }
160 
161 /* ------------------------------------------------------------------------ */
162 
ccapi_ccache_destroy(cc_ccache_t io_ccache)163 cc_int32 ccapi_ccache_destroy (cc_ccache_t io_ccache)
164 {
165     cc_int32 err = ccNoError;
166     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
167 
168     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
169 
170     if (!err) {
171         err =  cci_ipc_send (cci_ccache_destroy_msg_id,
172                              ccache->identifier,
173                              NULL,
174                              NULL);
175     }
176 
177     if (!err) {
178         err = ccapi_ccache_release (io_ccache);
179     }
180 
181     return cci_check_error (err);
182 }
183 
184 /* ------------------------------------------------------------------------ */
185 
ccapi_ccache_set_default(cc_ccache_t io_ccache)186 cc_int32 ccapi_ccache_set_default (cc_ccache_t io_ccache)
187 {
188     cc_int32 err = ccNoError;
189     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
190 
191     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
192 
193     if (!err) {
194         err =  cci_ipc_send (cci_ccache_set_default_msg_id,
195                              ccache->identifier,
196                              NULL,
197                              NULL);
198     }
199 
200     return cci_check_error (err);
201 }
202 
203 /* ------------------------------------------------------------------------ */
204 
ccapi_ccache_get_credentials_version(cc_ccache_t in_ccache,cc_uint32 * out_credentials_version)205 cc_int32 ccapi_ccache_get_credentials_version (cc_ccache_t  in_ccache,
206                                                cc_uint32   *out_credentials_version)
207 {
208     cc_int32 err = ccNoError;
209     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
210     k5_ipc_stream reply = NULL;
211 
212     if (!in_ccache              ) { err = cci_check_error (ccErrBadParam); }
213     if (!out_credentials_version) { err = cci_check_error (ccErrBadParam); }
214 
215     if (!err) {
216         err =  cci_ipc_send (cci_ccache_get_credentials_version_msg_id,
217                              ccache->identifier,
218                              NULL,
219                              &reply);
220     }
221 
222     if (!err) {
223         err = krb5int_ipc_stream_read_uint32 (reply, out_credentials_version);
224     }
225 
226     krb5int_ipc_stream_release (reply);
227 
228     return cci_check_error (err);
229 }
230 
231 /* ------------------------------------------------------------------------ */
232 
ccapi_ccache_get_name(cc_ccache_t in_ccache,cc_string_t * out_name)233 cc_int32 ccapi_ccache_get_name (cc_ccache_t  in_ccache,
234                                 cc_string_t *out_name)
235 {
236     cc_int32 err = ccNoError;
237     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
238     k5_ipc_stream reply = NULL;
239     char *name = NULL;
240 
241     if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
242     if (!out_name ) { err = cci_check_error (ccErrBadParam); }
243 
244     if (!err) {
245         err =  cci_ipc_send (cci_ccache_get_name_msg_id,
246                              ccache->identifier,
247                              NULL,
248                              &reply);
249     }
250 
251     if (!err) {
252         err = krb5int_ipc_stream_read_string (reply, &name);
253     }
254 
255     if (!err) {
256         err = cci_string_new (out_name, name);
257     }
258 
259     krb5int_ipc_stream_release (reply);
260     krb5int_ipc_stream_free_string (name);
261 
262     return cci_check_error (err);
263 }
264 
265 /* ------------------------------------------------------------------------ */
266 
ccapi_ccache_get_principal(cc_ccache_t in_ccache,cc_uint32 in_credentials_version,cc_string_t * out_principal)267 cc_int32 ccapi_ccache_get_principal (cc_ccache_t  in_ccache,
268                                      cc_uint32    in_credentials_version,
269                                      cc_string_t *out_principal)
270 {
271     cc_int32 err = ccNoError;
272     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
273     k5_ipc_stream request = NULL;
274     k5_ipc_stream reply = NULL;
275     char *principal = NULL;
276 
277     if (!in_ccache    ) { err = cci_check_error (ccErrBadParam); }
278     if (!out_principal) { err = cci_check_error (ccErrBadParam); }
279 
280     if (!err) {
281         err = krb5int_ipc_stream_new (&request);
282     }
283 
284     if (!err) {
285         err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
286     }
287 
288     if (!err) {
289         err =  cci_ipc_send (cci_ccache_get_principal_msg_id,
290                              ccache->identifier,
291                              request,
292                              &reply);
293     }
294 
295     if (!err) {
296         err = krb5int_ipc_stream_read_string (reply, &principal);
297     }
298 
299     if (!err) {
300         err = cci_string_new (out_principal, principal);
301     }
302 
303     krb5int_ipc_stream_release (request);
304     krb5int_ipc_stream_release (reply);
305     krb5int_ipc_stream_free_string (principal);
306 
307     return cci_check_error (err);
308 }
309 
310 /* ------------------------------------------------------------------------ */
311 
ccapi_ccache_set_principal(cc_ccache_t io_ccache,cc_uint32 in_credentials_version,const char * in_principal)312 cc_int32 ccapi_ccache_set_principal (cc_ccache_t  io_ccache,
313                                      cc_uint32    in_credentials_version,
314                                      const char  *in_principal)
315 {
316     cc_int32 err = ccNoError;
317     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
318     k5_ipc_stream request = NULL;
319 
320     if (!io_ccache   ) { err = cci_check_error (ccErrBadParam); }
321     if (!in_principal) { err = cci_check_error (ccErrBadParam); }
322 
323     if (!err) {
324         err = krb5int_ipc_stream_new (&request);
325     }
326 
327     if (!err) {
328         err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
329     }
330 
331     if (!err) {
332         err = krb5int_ipc_stream_write_string (request, in_principal);
333     }
334 
335     if (!err) {
336         err =  cci_ipc_send (cci_ccache_set_principal_msg_id,
337                              ccache->identifier,
338                              request,
339                              NULL);
340     }
341 
342     krb5int_ipc_stream_release (request);
343 
344     return cci_check_error (err);
345 }
346 
347 /* ------------------------------------------------------------------------ */
348 
ccapi_ccache_store_credentials(cc_ccache_t io_ccache,const cc_credentials_union * in_credentials_union)349 cc_int32 ccapi_ccache_store_credentials (cc_ccache_t                 io_ccache,
350                                          const cc_credentials_union *in_credentials_union)
351 {
352     cc_int32 err = ccNoError;
353     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
354     k5_ipc_stream request = NULL;
355 
356     if (!io_ccache           ) { err = cci_check_error (ccErrBadParam); }
357     if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
358 
359     if (!err) {
360         err = krb5int_ipc_stream_new (&request);
361     }
362 
363     if (!err) {
364         err = cci_credentials_union_write (in_credentials_union, request);
365     }
366 
367     if (!err) {
368         err =  cci_ipc_send (cci_ccache_store_credentials_msg_id,
369                              ccache->identifier,
370                              request,
371                              NULL);
372     }
373 
374     krb5int_ipc_stream_release (request);
375 
376     return cci_check_error (err);
377 }
378 
379 /* ------------------------------------------------------------------------ */
380 
ccapi_ccache_remove_credentials(cc_ccache_t io_ccache,cc_credentials_t in_credentials)381 cc_int32 ccapi_ccache_remove_credentials (cc_ccache_t      io_ccache,
382                                           cc_credentials_t in_credentials)
383 {
384     cc_int32 err = ccNoError;
385     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
386     k5_ipc_stream request = NULL;
387 
388     if (!io_ccache     ) { err = cci_check_error (ccErrBadParam); }
389     if (!in_credentials) { err = cci_check_error (ccErrBadParam); }
390 
391     if (!err) {
392         err = krb5int_ipc_stream_new (&request);
393     }
394 
395     if (!err) {
396         err = cci_credentials_write (in_credentials, request);
397     }
398 
399     if (!err) {
400         err =  cci_ipc_send (cci_ccache_remove_credentials_msg_id,
401                              ccache->identifier,
402                              request,
403                              NULL);
404     }
405 
406     krb5int_ipc_stream_release (request);
407 
408     return cci_check_error (err);
409 }
410 
411 /* ------------------------------------------------------------------------ */
412 
ccapi_ccache_new_credentials_iterator(cc_ccache_t in_ccache,cc_credentials_iterator_t * out_credentials_iterator)413 cc_int32 ccapi_ccache_new_credentials_iterator (cc_ccache_t                in_ccache,
414                                                 cc_credentials_iterator_t *out_credentials_iterator)
415 {
416     cc_int32 err = ccNoError;
417     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
418     k5_ipc_stream reply = NULL;
419     cci_identifier_t identifier = NULL;
420 
421     if (!in_ccache               ) { err = cci_check_error (ccErrBadParam); }
422     if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); }
423 
424     if (!err) {
425         err =  cci_ipc_send (cci_ccache_new_credentials_iterator_msg_id,
426                              ccache->identifier,
427                              NULL,
428                              &reply);
429     }
430 
431     if (!err) {
432         err =  cci_identifier_read (&identifier, reply);
433     }
434 
435     if (!err) {
436         err = cci_credentials_iterator_new (out_credentials_iterator, identifier);
437     }
438 
439     krb5int_ipc_stream_release (reply);
440     cci_identifier_release (identifier);
441 
442     return cci_check_error (err);
443 }
444 
445 /* ------------------------------------------------------------------------ */
446 /* Note: message is sent as the destination to avoid extra work on the      */
447 /* server when deleting it the source ccache.                               */
448 
ccapi_ccache_move(cc_ccache_t io_source_ccache,cc_ccache_t io_destination_ccache)449 cc_int32 ccapi_ccache_move (cc_ccache_t io_source_ccache,
450                             cc_ccache_t io_destination_ccache)
451 {
452     cc_int32 err = ccNoError;
453     cci_ccache_t source_ccache = (cci_ccache_t) io_source_ccache;
454     cci_ccache_t destination_ccache = (cci_ccache_t) io_destination_ccache;
455     k5_ipc_stream request = NULL;
456 
457     if (!io_source_ccache     ) { err = cci_check_error (ccErrBadParam); }
458     if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); }
459 
460     if (!err) {
461         err = krb5int_ipc_stream_new (&request);
462     }
463 
464     if (!err) {
465         err = cci_identifier_write (source_ccache->identifier, request);
466     }
467 
468     if (!err) {
469         err =  cci_ipc_send (cci_ccache_move_msg_id,
470                              destination_ccache->identifier,
471                              request,
472                              NULL);
473     }
474 
475     krb5int_ipc_stream_release (request);
476 
477     return cci_check_error (err);
478 }
479 
480 /* ------------------------------------------------------------------------ */
481 
ccapi_ccache_lock(cc_ccache_t io_ccache,cc_uint32 in_lock_type,cc_uint32 in_block)482 cc_int32 ccapi_ccache_lock (cc_ccache_t io_ccache,
483                             cc_uint32   in_lock_type,
484                             cc_uint32   in_block)
485 {
486     cc_int32 err = ccNoError;
487     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
488     k5_ipc_stream request = NULL;
489 
490     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
491 
492     if (!err) {
493         err = krb5int_ipc_stream_new (&request);
494     }
495 
496     if (!err) {
497         err = krb5int_ipc_stream_write_uint32 (request, in_lock_type);
498     }
499 
500     if (!err) {
501         err = krb5int_ipc_stream_write_uint32 (request, in_block);
502     }
503 
504     if (!err) {
505         err =  cci_ipc_send (cci_ccache_lock_msg_id,
506                              ccache->identifier,
507                              request,
508                              NULL);
509     }
510 
511     krb5int_ipc_stream_release (request);
512 
513     return cci_check_error (err);
514 }
515 
516 /* ------------------------------------------------------------------------ */
517 
ccapi_ccache_unlock(cc_ccache_t io_ccache)518 cc_int32 ccapi_ccache_unlock (cc_ccache_t io_ccache)
519 {
520     cc_int32 err = ccNoError;
521     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
522 
523     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
524 
525     if (!err) {
526         err =  cci_ipc_send (cci_ccache_unlock_msg_id,
527                              ccache->identifier,
528                              NULL,
529                              NULL);
530     }
531 
532     return cci_check_error (err);
533 }
534 
535 /* ------------------------------------------------------------------------ */
536 
ccapi_ccache_get_last_default_time(cc_ccache_t in_ccache,cc_time_t * out_last_default_time)537 cc_int32 ccapi_ccache_get_last_default_time (cc_ccache_t  in_ccache,
538                                              cc_time_t   *out_last_default_time)
539 {
540     cc_int32 err = ccNoError;
541     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
542     k5_ipc_stream reply = NULL;
543 
544     if (!in_ccache            ) { err = cci_check_error (ccErrBadParam); }
545     if (!out_last_default_time) { err = cci_check_error (ccErrBadParam); }
546 
547     if (!err) {
548         err =  cci_ipc_send (cci_ccache_get_last_default_time_msg_id,
549                              ccache->identifier,
550                              NULL,
551                              &reply);
552     }
553 
554     if (!err) {
555         err = krb5int_ipc_stream_read_time (reply, out_last_default_time);
556     }
557 
558     krb5int_ipc_stream_release (reply);
559 
560     return cci_check_error (err);
561 }
562 
563 /* ------------------------------------------------------------------------ */
564 
ccapi_ccache_get_change_time(cc_ccache_t in_ccache,cc_time_t * out_change_time)565 cc_int32 ccapi_ccache_get_change_time (cc_ccache_t  in_ccache,
566                                        cc_time_t   *out_change_time)
567 {
568     cc_int32 err = ccNoError;
569     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
570     k5_ipc_stream reply = NULL;
571 
572     if (!in_ccache      ) { err = cci_check_error (ccErrBadParam); }
573     if (!out_change_time) { err = cci_check_error (ccErrBadParam); }
574 
575     if (!err) {
576         err =  cci_ipc_send (cci_ccache_get_change_time_msg_id,
577                              ccache->identifier,
578                              NULL,
579                              &reply);
580     }
581 
582     if (!err) {
583         err = krb5int_ipc_stream_read_time (reply, out_change_time);
584     }
585 
586     krb5int_ipc_stream_release (reply);
587 
588     return cci_check_error (err);
589 }
590 
591 /* ------------------------------------------------------------------------ */
592 
ccapi_ccache_wait_for_change(cc_ccache_t in_ccache)593 cc_int32 ccapi_ccache_wait_for_change (cc_ccache_t  in_ccache)
594 {
595     cc_int32 err = ccNoError;
596     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
597     k5_ipc_stream request = NULL;
598     k5_ipc_stream reply = NULL;
599 
600     if (!in_ccache) { err = cci_check_error (ccErrBadParam); }
601 
602     if (!err) {
603         err = krb5int_ipc_stream_new (&request);
604     }
605 
606     if (!err) {
607         err = krb5int_ipc_stream_write_time (request, ccache->last_wait_for_change_time);
608     }
609 
610     if (!err) {
611         err =  cci_ipc_send (cci_ccache_wait_for_change_msg_id,
612                              ccache->identifier,
613                              request,
614 			     &reply);
615     }
616 
617     if (!err) {
618         err = krb5int_ipc_stream_read_time (reply, &ccache->last_wait_for_change_time);
619     }
620 
621     krb5int_ipc_stream_release (request);
622     krb5int_ipc_stream_release (reply);
623 
624     return cci_check_error (err);
625 }
626 
627 /* ------------------------------------------------------------------------ */
628 
ccapi_ccache_compare(cc_ccache_t in_ccache,cc_ccache_t in_compare_to_ccache,cc_uint32 * out_equal)629 cc_int32 ccapi_ccache_compare (cc_ccache_t  in_ccache,
630                                cc_ccache_t  in_compare_to_ccache,
631                                cc_uint32   *out_equal)
632 {
633     cc_int32 err = ccNoError;
634     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
635     cci_ccache_t compare_to_ccache = (cci_ccache_t) in_compare_to_ccache;
636 
637     if (!in_ccache           ) { err = cci_check_error (ccErrBadParam); }
638     if (!in_compare_to_ccache) { err = cci_check_error (ccErrBadParam); }
639     if (!out_equal           ) { err = cci_check_error (ccErrBadParam); }
640 
641     if (!err) {
642         err = cci_identifier_compare (ccache->identifier,
643                                       compare_to_ccache->identifier,
644                                       out_equal);
645     }
646 
647     return cci_check_error (err);
648 }
649 
650 /* ------------------------------------------------------------------------ */
651 
ccapi_ccache_get_kdc_time_offset(cc_ccache_t in_ccache,cc_uint32 in_credentials_version,cc_time_t * out_time_offset)652 cc_int32 ccapi_ccache_get_kdc_time_offset (cc_ccache_t  in_ccache,
653                                            cc_uint32    in_credentials_version,
654                                            cc_time_t   *out_time_offset)
655 {
656     cc_int32 err = ccNoError;
657     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
658     k5_ipc_stream request = NULL;
659     k5_ipc_stream reply = NULL;
660 
661     if (!in_ccache      ) { err = cci_check_error (ccErrBadParam); }
662     if (!out_time_offset) { err = cci_check_error (ccErrBadParam); }
663 
664     if (!err) {
665         err = krb5int_ipc_stream_new (&request);
666     }
667 
668     if (!err) {
669         err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
670     }
671 
672     if (!err) {
673         err =  cci_ipc_send (cci_ccache_get_kdc_time_offset_msg_id,
674                              ccache->identifier,
675                              request,
676                              &reply);
677     }
678 
679     if (!err) {
680         err = krb5int_ipc_stream_read_time (reply, out_time_offset);
681     }
682 
683     krb5int_ipc_stream_release (request);
684     krb5int_ipc_stream_release (reply);
685 
686     return cci_check_error (err);
687 }
688 
689 /* ------------------------------------------------------------------------ */
690 
ccapi_ccache_set_kdc_time_offset(cc_ccache_t io_ccache,cc_uint32 in_credentials_version,cc_time_t in_time_offset)691 cc_int32 ccapi_ccache_set_kdc_time_offset (cc_ccache_t io_ccache,
692                                            cc_uint32   in_credentials_version,
693                                            cc_time_t   in_time_offset)
694 {
695     cc_int32 err = ccNoError;
696     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
697     k5_ipc_stream request = NULL;
698 
699     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
700 
701     if (!err) {
702         err = krb5int_ipc_stream_new (&request);
703     }
704 
705     if (!err) {
706         err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
707     }
708 
709     if (!err) {
710         err = krb5int_ipc_stream_write_time (request, in_time_offset);
711     }
712 
713     if (!err) {
714         err =  cci_ipc_send (cci_ccache_set_kdc_time_offset_msg_id,
715                              ccache->identifier,
716                              request,
717                              NULL);
718     }
719 
720     krb5int_ipc_stream_release (request);
721 
722     return cci_check_error (err);
723 }
724 
725 /* ------------------------------------------------------------------------ */
726 
ccapi_ccache_clear_kdc_time_offset(cc_ccache_t io_ccache,cc_uint32 in_credentials_version)727 cc_int32 ccapi_ccache_clear_kdc_time_offset (cc_ccache_t io_ccache,
728                                              cc_uint32   in_credentials_version)
729 {
730     cc_int32 err = ccNoError;
731     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
732     k5_ipc_stream request = NULL;
733 
734     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
735 
736     if (!err) {
737         err = krb5int_ipc_stream_new (&request);
738     }
739 
740     if (!err) {
741         err = krb5int_ipc_stream_write_uint32 (request, in_credentials_version);
742     }
743 
744     if (!err) {
745         err =  cci_ipc_send (cci_ccache_clear_kdc_time_offset_msg_id,
746                              ccache->identifier,
747                              request,
748                              NULL);
749     }
750 
751     krb5int_ipc_stream_release (request);
752 
753     return cci_check_error (err);
754 }
755 
756 #ifdef TARGET_OS_MAC
757 #pragma mark -
758 #endif
759 
760 /* ------------------------------------------------------------------------ */
761 
cci_ccache_get_compat_version(cc_ccache_t in_ccache,cc_uint32 * out_compat_version)762 cc_int32 cci_ccache_get_compat_version (cc_ccache_t  in_ccache,
763                                         cc_uint32   *out_compat_version)
764 {
765     cc_int32 err = ccNoError;
766     cci_ccache_t ccache = (cci_ccache_t) in_ccache;
767 
768     if (!in_ccache         ) { err = cci_check_error (ccErrBadParam); }
769     if (!out_compat_version) { err = cci_check_error (ccErrBadParam); }
770 
771     if (!err) {
772         *out_compat_version = ccache->compat_version;
773     }
774 
775     return cci_check_error (err);
776 }
777 
778 /* ------------------------------------------------------------------------ */
779 
cci_ccache_set_compat_version(cc_ccache_t io_ccache,cc_uint32 in_compat_version)780 cc_int32 cci_ccache_set_compat_version (cc_ccache_t io_ccache,
781                                         cc_uint32   in_compat_version)
782 {
783     cc_int32 err = ccNoError;
784     cci_ccache_t ccache = (cci_ccache_t) io_ccache;
785 
786     if (!io_ccache) { err = cci_check_error (ccErrBadParam); }
787 
788     if (!err) {
789         ccache->compat_version = in_compat_version;
790     }
791 
792     return cci_check_error (err);
793 }
794