xref: /freebsd/crypto/krb5/src/ccapi/common/cci_cred_union.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* ccapi/common/cci_cred_union.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 "cci_common.h"
27 
28 /* ------------------------------------------------------------------------ */
29 
cci_cc_data_contents_release(cc_data * io_ccdata)30 static cc_uint32 cci_cc_data_contents_release (cc_data *io_ccdata)
31 {
32     cc_int32 err = ccNoError;
33 
34     if (!io_ccdata && io_ccdata->data) { err = ccErrBadParam; }
35 
36     if (!err) {
37         if (io_ccdata->length) {
38             memset (io_ccdata->data, 0, io_ccdata->length);
39         }
40         free (io_ccdata->data);
41     }
42 
43     return err;
44 }
45 
46 /* ------------------------------------------------------------------------ */
47 
cci_cc_data_release(cc_data * io_ccdata)48 static cc_uint32 cci_cc_data_release (cc_data *io_ccdata)
49 {
50     cc_int32 err = ccNoError;
51 
52     if (!io_ccdata) { err = ccErrBadParam; }
53 
54     if (!err) {
55         cci_cc_data_contents_release (io_ccdata);
56         free (io_ccdata);
57     }
58 
59     return err;
60 }
61 
62 /* ------------------------------------------------------------------------ */
63 
cci_cc_data_read(cc_data * io_ccdata,k5_ipc_stream io_stream)64 static cc_uint32 cci_cc_data_read (cc_data      *io_ccdata,
65                                    k5_ipc_stream io_stream)
66 {
67     cc_int32 err = ccNoError;
68     cc_uint32 type = 0;
69     cc_uint32 length = 0;
70     char *data = NULL;
71 
72     if (!io_stream) { err = cci_check_error (ccErrBadParam); }
73     if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }
74 
75     if (!err) {
76         err = krb5int_ipc_stream_read_uint32 (io_stream, &type);
77     }
78 
79     if (!err) {
80         err = krb5int_ipc_stream_read_uint32 (io_stream, &length);
81     }
82 
83     if (!err && length > 0) {
84         data = malloc (length);
85         if (!data) { err = cci_check_error (ccErrNoMem); }
86 
87         if (!err) {
88             err = krb5int_ipc_stream_read (io_stream, data, length);
89         }
90     }
91 
92     if (!err) {
93         io_ccdata->type = type;
94         io_ccdata->length = length;
95         io_ccdata->data = data;
96         data = NULL;
97     }
98 
99     free (data);
100 
101     return cci_check_error (err);
102 }
103 
104 /* ------------------------------------------------------------------------ */
105 
cci_cc_data_write(cc_data * in_ccdata,k5_ipc_stream io_stream)106 static cc_uint32 cci_cc_data_write (cc_data      *in_ccdata,
107                                     k5_ipc_stream io_stream)
108 {
109     cc_int32 err = ccNoError;
110 
111     if (!io_stream) { err = cci_check_error (ccErrBadParam); }
112     if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }
113 
114     if (!err) {
115         err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->type);
116     }
117 
118     if (!err) {
119         err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->length);
120     }
121 
122     if (!err && in_ccdata->length > 0) {
123         err = krb5int_ipc_stream_write (io_stream, in_ccdata->data, in_ccdata->length);
124     }
125 
126     return cci_check_error (err);
127 }
128 
129 #ifdef TARGET_OS_MAC
130 #pragma mark -
131 #endif
132 
133 /* ------------------------------------------------------------------------ */
134 
cci_cc_data_array_release(cc_data ** io_ccdata_array)135 static cc_uint32 cci_cc_data_array_release (cc_data **io_ccdata_array)
136 {
137     cc_int32 err = ccNoError;
138 
139     if (!io_ccdata_array) { err = ccErrBadParam; }
140 
141     if (!err) {
142         cc_uint32 i;
143 
144         for (i = 0; io_ccdata_array && io_ccdata_array[i]; i++) {
145             cci_cc_data_release (io_ccdata_array[i]);
146         }
147         free (io_ccdata_array);
148     }
149 
150     return err;
151 }
152 
153 /* ------------------------------------------------------------------------ */
154 
cci_cc_data_array_read(cc_data *** io_ccdata_array,k5_ipc_stream io_stream)155 static cc_uint32 cci_cc_data_array_read (cc_data      ***io_ccdata_array,
156                                          k5_ipc_stream    io_stream)
157 {
158     cc_int32 err = ccNoError;
159     cc_uint32 count = 0;
160     cc_data **array = NULL;
161     cc_uint32 i;
162 
163     if (!io_stream      ) { err = cci_check_error (ccErrBadParam); }
164     if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }
165 
166     if (!err) {
167         err = krb5int_ipc_stream_read_uint32 (io_stream, &count);
168     }
169 
170     if (!err && count > 0) {
171         array = malloc ((count + 1) * sizeof (*array));
172         if (array) {
173             for (i = 0; i <= count; i++) { array[i] = NULL; }
174         } else {
175             err = cci_check_error (ccErrNoMem);
176         }
177     }
178 
179     if (!err) {
180         for (i = 0; !err && i < count; i++) {
181             array[i] = malloc (sizeof (cc_data));
182             if (!array[i]) { err = cci_check_error (ccErrNoMem); }
183 
184             if (!err) {
185                 err = cci_cc_data_read (array[i], io_stream);
186             }
187         }
188     }
189 
190     if (!err) {
191         *io_ccdata_array = array;
192         array = NULL;
193     }
194 
195     cci_cc_data_array_release (array);
196 
197     return cci_check_error (err);
198 }
199 
200 /* ------------------------------------------------------------------------ */
201 
cci_cc_data_array_write(cc_data ** in_ccdata_array,k5_ipc_stream io_stream)202 static cc_uint32 cci_cc_data_array_write (cc_data      **in_ccdata_array,
203                                           k5_ipc_stream   io_stream)
204 {
205     cc_int32 err = ccNoError;
206     cc_uint32 count = 0;
207 
208     if (!io_stream) { err = cci_check_error (ccErrBadParam); }
209     /* in_ccdata_array may be NULL */
210 
211     if (!err) {
212         for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);
213 
214         err = krb5int_ipc_stream_write_uint32 (io_stream, count);
215     }
216 
217     if (!err) {
218         cc_uint32 i;
219 
220         for (i = 0; !err && i < count; i++) {
221             err = cci_cc_data_write (in_ccdata_array[i], io_stream);
222         }
223     }
224 
225     return cci_check_error (err);
226 }
227 
228 #ifdef TARGET_OS_MAC
229 #pragma mark -
230 #endif
231 
232 /* ------------------------------------------------------------------------ */
233 
234 cc_credentials_v5_t cci_credentials_v5_initializer = {
235     NULL,
236     NULL,
237     { 0, 0, NULL },
238     0, 0, 0, 0, 0, 0,
239     NULL,
240     { 0, 0, NULL },
241     { 0, 0, NULL },
242     NULL
243 };
244 
245 /* ------------------------------------------------------------------------ */
246 
cci_credentials_v5_release(cc_credentials_v5_t * io_v5creds)247 static cc_uint32 cci_credentials_v5_release (cc_credentials_v5_t *io_v5creds)
248 {
249     cc_int32 err = ccNoError;
250 
251     if (!io_v5creds) { err = ccErrBadParam; }
252 
253     if (!err) {
254         free (io_v5creds->client);
255         free (io_v5creds->server);
256         cci_cc_data_contents_release (&io_v5creds->keyblock);
257         cci_cc_data_array_release (io_v5creds->addresses);
258         cci_cc_data_contents_release (&io_v5creds->ticket);
259         cci_cc_data_contents_release (&io_v5creds->second_ticket);
260         cci_cc_data_array_release (io_v5creds->authdata);
261         free (io_v5creds);
262     }
263 
264     return err;
265 }
266 
267 /* ------------------------------------------------------------------------ */
268 
cci_credentials_v5_read(cc_credentials_v5_t ** out_v5creds,k5_ipc_stream io_stream)269 static cc_uint32 cci_credentials_v5_read (cc_credentials_v5_t **out_v5creds,
270                                           k5_ipc_stream          io_stream)
271 {
272     cc_int32 err = ccNoError;
273     cc_credentials_v5_t *v5creds = NULL;
274 
275     if (!io_stream  ) { err = cci_check_error (ccErrBadParam); }
276     if (!out_v5creds) { err = cci_check_error (ccErrBadParam); }
277 
278     if (!err) {
279         v5creds = malloc (sizeof (*v5creds));
280         if (v5creds) {
281             *v5creds = cci_credentials_v5_initializer;
282         } else {
283             err = cci_check_error (ccErrNoMem);
284         }
285     }
286 
287     if (!err) {
288         err = krb5int_ipc_stream_read_string (io_stream, &v5creds->client);
289     }
290 
291     if (!err) {
292         err = krb5int_ipc_stream_read_string (io_stream, &v5creds->server);
293     }
294 
295     if (!err) {
296         err = cci_cc_data_read (&v5creds->keyblock, io_stream);
297     }
298 
299     if (!err) {
300         err = krb5int_ipc_stream_read_time (io_stream, &v5creds->authtime);
301     }
302 
303     if (!err) {
304         err = krb5int_ipc_stream_read_time (io_stream, &v5creds->starttime);
305     }
306 
307     if (!err) {
308         err = krb5int_ipc_stream_read_time (io_stream, &v5creds->endtime);
309     }
310 
311     if (!err) {
312         err = krb5int_ipc_stream_read_time (io_stream, &v5creds->renew_till);
313     }
314 
315     if (!err) {
316         err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->is_skey);
317     }
318 
319     if (!err) {
320         err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->ticket_flags);
321     }
322 
323     if (!err) {
324         err = cci_cc_data_array_read (&v5creds->addresses, io_stream);
325     }
326 
327     if (!err) {
328         err = cci_cc_data_read (&v5creds->ticket, io_stream);
329     }
330 
331     if (!err) {
332         err = cci_cc_data_read (&v5creds->second_ticket, io_stream);
333     }
334 
335     if (!err) {
336         err = cci_cc_data_array_read (&v5creds->authdata, io_stream);
337     }
338 
339     if (!err) {
340         *out_v5creds = v5creds;
341         v5creds = NULL;
342     }
343 
344     cci_credentials_v5_release (v5creds);
345 
346     return cci_check_error (err);
347 }
348 
349 /* ------------------------------------------------------------------------ */
350 
cci_credentials_v5_write(cc_credentials_v5_t * in_v5creds,k5_ipc_stream io_stream)351 static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds,
352                                            k5_ipc_stream         io_stream)
353 {
354     cc_int32 err = ccNoError;
355 
356     if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
357     if (!in_v5creds) { err = cci_check_error (ccErrBadParam); }
358 
359     if (!err) {
360         err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->client);
361     }
362 
363     if (!err) {
364         err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->server);
365     }
366 
367     if (!err) {
368         err = cci_cc_data_write (&in_v5creds->keyblock, io_stream);
369     }
370 
371     if (!err) {
372         err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->authtime);
373     }
374 
375     if (!err) {
376         err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->starttime);
377     }
378 
379     if (!err) {
380         err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->endtime);
381     }
382 
383     if (!err) {
384         err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->renew_till);
385     }
386 
387     if (!err) {
388         err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->is_skey);
389     }
390 
391     if (!err) {
392         err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->ticket_flags);
393     }
394 
395     if (!err) {
396         err = cci_cc_data_array_write (in_v5creds->addresses, io_stream);
397     }
398 
399     if (!err) {
400         err = cci_cc_data_write (&in_v5creds->ticket, io_stream);
401     }
402 
403     if (!err) {
404         err = cci_cc_data_write (&in_v5creds->second_ticket, io_stream);
405     }
406 
407     if (!err) {
408         err = cci_cc_data_array_write (in_v5creds->authdata, io_stream);
409     }
410 
411 
412     return cci_check_error (err);
413 }
414 
415 #ifdef TARGET_OS_MAC
416 #pragma mark -
417 #endif
418 
419 /* ------------------------------------------------------------------------ */
420 
cci_credentials_union_release(cc_credentials_union * io_cred_union)421 cc_uint32 cci_credentials_union_release (cc_credentials_union *io_cred_union)
422 {
423     cc_int32 err = ccNoError;
424 
425     if (!io_cred_union) { err = ccErrBadParam; }
426 
427     if (!err) {
428         if (io_cred_union->version == cc_credentials_v5) {
429             cci_credentials_v5_release (io_cred_union->credentials.credentials_v5);
430         }
431         free (io_cred_union);
432     }
433 
434     return err;
435 }
436 
437 /* ------------------------------------------------------------------------ */
438 
cci_credentials_union_read(cc_credentials_union ** out_credentials_union,k5_ipc_stream io_stream)439 cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union,
440                                       k5_ipc_stream           io_stream)
441 {
442     cc_int32 err = ccNoError;
443     cc_credentials_union *credentials_union = NULL;
444 
445     if (!io_stream            ) { err = cci_check_error (ccErrBadParam); }
446     if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }
447 
448     if (!err) {
449         credentials_union = calloc (1, sizeof (*credentials_union));
450         if (!credentials_union) { err = cci_check_error (ccErrNoMem); }
451     }
452 
453     if (!err) {
454         err = krb5int_ipc_stream_read_uint32 (io_stream, &credentials_union->version);
455     }
456 
457     if (!err) {
458         if (credentials_union->version == cc_credentials_v5) {
459             err = cci_credentials_v5_read (&credentials_union->credentials.credentials_v5,
460                                            io_stream);
461 
462 
463         } else {
464             err = ccErrBadCredentialsVersion;
465         }
466     }
467 
468     if (!err) {
469         *out_credentials_union = credentials_union;
470         credentials_union = NULL;
471     }
472 
473     if (credentials_union) { cci_credentials_union_release (credentials_union); }
474 
475     return cci_check_error (err);
476 }
477 
478 /* ------------------------------------------------------------------------ */
479 
cci_credentials_union_write(const cc_credentials_union * in_credentials_union,k5_ipc_stream io_stream)480 cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union,
481                                        k5_ipc_stream                io_stream)
482 {
483     cc_int32 err = ccNoError;
484 
485     if (!io_stream           ) { err = cci_check_error (ccErrBadParam); }
486     if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
487 
488     if (!err) {
489         err = krb5int_ipc_stream_write_uint32 (io_stream, in_credentials_union->version);
490     }
491 
492     if (!err) {
493         if (in_credentials_union->version == cc_credentials_v5) {
494             err = cci_credentials_v5_write (in_credentials_union->credentials.credentials_v5,
495                                             io_stream);
496 
497         } else {
498             err = ccErrBadCredentialsVersion;
499         }
500     }
501 
502     return cci_check_error (err);
503 }
504 
505 #ifdef TARGET_OS_MAC
506 #pragma mark -
507 #pragma mark -- CCAPI v2 Compat --
508 #endif
509 
510 /* ------------------------------------------------------------------------ */
511 
512 cc_credentials_v5_compat cci_credentials_v5_compat_initializer = {
513     NULL,
514     NULL,
515     { 0, 0, NULL },
516     0, 0, 0, 0, 0, 0,
517     NULL,
518     { 0, 0, NULL },
519     { 0, 0, NULL },
520     NULL
521 };
522 
523 /* ------------------------------------------------------------------------ */
524 
cci_cred_union_release(cred_union * io_cred_union)525 cc_uint32 cci_cred_union_release (cred_union *io_cred_union)
526 {
527     cc_int32 err = ccNoError;
528 
529     if (!io_cred_union) { err = ccErrBadParam; }
530 
531     if (!err) {
532         if (io_cred_union->cred_type == CC_CRED_V5) {
533             free (io_cred_union->cred.pV5Cred->client);
534             free (io_cred_union->cred.pV5Cred->server);
535             cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->keyblock);
536             cci_cc_data_array_release (io_cred_union->cred.pV5Cred->addresses);
537             cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->ticket);
538             cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->second_ticket);
539             cci_cc_data_array_release (io_cred_union->cred.pV5Cred->authdata);
540             free (io_cred_union->cred.pV5Cred);
541         }
542         free (io_cred_union);
543     }
544 
545     return err;
546 }
547 
548 /* ------------------------------------------------------------------------ */
549 
cci_cc_data_copy_contents(cc_data * io_ccdata,cc_data * in_ccdata)550 static cc_uint32 cci_cc_data_copy_contents (cc_data      *io_ccdata,
551                                             cc_data      *in_ccdata)
552 {
553     cc_int32 err = ccNoError;
554     char *data = NULL;
555 
556     if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }
557     if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }
558 
559     if (!err && in_ccdata->length > 0) {
560         data = malloc (in_ccdata->length);
561         if (data) {
562             memcpy (data, in_ccdata->data, in_ccdata->length);
563         } else {
564             err = cci_check_error (ccErrNoMem);
565         }
566     }
567 
568     if (!err) {
569         io_ccdata->type = in_ccdata->type;
570         io_ccdata->length = in_ccdata->length;
571         io_ccdata->data = data;
572         data = NULL;
573     }
574 
575     free (data);
576 
577     return cci_check_error (err);
578 }
579 
580 /* ------------------------------------------------------------------------ */
581 
cci_cc_data_array_copy(cc_data *** io_ccdata_array,cc_data ** in_ccdata_array)582 static cc_uint32 cci_cc_data_array_copy (cc_data      ***io_ccdata_array,
583                                          cc_data       **in_ccdata_array)
584 {
585     cc_int32 err = ccNoError;
586     cc_uint32 count = 0;
587     cc_data **array = NULL;
588     cc_uint32 i;
589 
590     if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }
591 
592     if (!err) {
593         for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);
594     }
595 
596     if (!err && count > 0) {
597         array = malloc ((count + 1) * sizeof (*array));
598         if (array) {
599             for (i = 0; i <= count; i++) { array[i] = NULL; }
600         } else {
601             err = cci_check_error (ccErrNoMem);
602         }
603     }
604 
605     if (!err) {
606         for (i = 0; !err && i < count; i++) {
607             array[i] = malloc (sizeof (cc_data));
608             if (!array[i]) { err = cci_check_error (ccErrNoMem); }
609 
610             if (!err) {
611                 err = cci_cc_data_copy_contents (array[i], in_ccdata_array[i]);
612             }
613         }
614     }
615 
616     if (!err) {
617         *io_ccdata_array = array;
618         array = NULL;
619     }
620 
621     cci_cc_data_array_release (array);
622 
623     return cci_check_error (err);
624 }
625 
626 /* ------------------------------------------------------------------------ */
627 
cci_credentials_union_to_cred_union(const cc_credentials_union * in_credentials_union,cred_union ** out_cred_union)628 cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union  *in_credentials_union,
629                                                cred_union                 **out_cred_union)
630 {
631     cc_int32 err = ccNoError;
632     cred_union *compat_cred_union = NULL;
633 
634     if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
635     if (!out_cred_union      ) { err = cci_check_error (ccErrBadParam); }
636 
637     if (!err) {
638         compat_cred_union = calloc (1, sizeof (*compat_cred_union));
639         if (!compat_cred_union) { err = cci_check_error (ccErrNoMem); }
640     }
641 
642     if (!err) {
643         if (in_credentials_union->version == cc_credentials_v5) {
644             cc_credentials_v5_t *v5creds = in_credentials_union->credentials.credentials_v5;
645             cc_credentials_v5_compat *compat_v5creds = NULL;
646 
647             compat_v5creds = malloc (sizeof (*compat_v5creds));
648             if (compat_v5creds) {
649                 *compat_v5creds = cci_credentials_v5_compat_initializer;
650             } else {
651                 err = cci_check_error (ccErrNoMem);
652             }
653 
654             if (!err) {
655                 if (!v5creds->client) {
656                     err = cci_check_error (ccErrBadParam);
657                 } else {
658                     compat_v5creds->client = strdup (v5creds->client);
659                     if (!compat_v5creds->client) { err = cci_check_error (ccErrNoMem); }
660                 }
661             }
662 
663             if (!err) {
664                 if (!v5creds->server) {
665                     err = cci_check_error (ccErrBadParam);
666                 } else {
667                     compat_v5creds->server = strdup (v5creds->server);
668                     if (!compat_v5creds->server) { err = cci_check_error (ccErrNoMem); }
669                 }
670             }
671 
672             if (!err) {
673                 err = cci_cc_data_copy_contents (&compat_v5creds->keyblock, &v5creds->keyblock);
674             }
675 
676             if (!err) {
677                 err = cci_cc_data_array_copy (&compat_v5creds->addresses, v5creds->addresses);
678             }
679 
680             if (!err) {
681                 err = cci_cc_data_copy_contents (&compat_v5creds->ticket, &v5creds->ticket);
682             }
683 
684             if (!err) {
685                 err = cci_cc_data_copy_contents (&compat_v5creds->second_ticket, &v5creds->second_ticket);
686             }
687 
688             if (!err) {
689                 err = cci_cc_data_array_copy (&compat_v5creds->authdata, v5creds->authdata);
690             }
691 
692             if (!err) {
693                 compat_cred_union->cred_type = CC_CRED_V5;
694                 compat_cred_union->cred.pV5Cred = compat_v5creds;
695 
696                 compat_v5creds->keyblock      = v5creds->keyblock;
697                 compat_v5creds->authtime      = v5creds->authtime;
698                 compat_v5creds->starttime     = v5creds->starttime;
699                 compat_v5creds->endtime       = v5creds->endtime;
700                 compat_v5creds->renew_till    = v5creds->renew_till;
701                 compat_v5creds->is_skey       = v5creds->is_skey;
702                 compat_v5creds->ticket_flags  = v5creds->ticket_flags;
703             }
704         } else {
705             err = cci_check_error (ccErrBadCredentialsVersion);
706         }
707     }
708 
709     if (!err) {
710         *out_cred_union = compat_cred_union;
711         compat_cred_union = NULL;
712     }
713 
714     if (compat_cred_union) { cci_cred_union_release (compat_cred_union); }
715 
716     return cci_check_error (err);
717 }
718 
719 /* ------------------------------------------------------------------------ */
720 
cci_cred_union_to_credentials_union(const cred_union * in_cred_union,cc_credentials_union ** out_credentials_union)721 cc_uint32 cci_cred_union_to_credentials_union (const cred_union      *in_cred_union,
722                                                cc_credentials_union **out_credentials_union)
723 {
724     cc_int32 err = ccNoError;
725     cc_credentials_union *creds_union = NULL;
726 
727     if (!in_cred_union        ) { err = cci_check_error (ccErrBadParam); }
728     if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }
729 
730     if (!err) {
731         creds_union = calloc (1, sizeof (*creds_union));
732         if (!creds_union) { err = cci_check_error (ccErrNoMem); }
733     }
734 
735     if (!err) {
736         if (in_cred_union->cred_type == CC_CRED_V5) {
737             cc_credentials_v5_compat *compat_v5creds = in_cred_union->cred.pV5Cred;
738             cc_credentials_v5_t *v5creds = NULL;
739 
740             if (!err) {
741                 v5creds = malloc (sizeof (*v5creds));
742                 if (v5creds) {
743                     *v5creds = cci_credentials_v5_initializer;
744                 } else {
745                     err = cci_check_error (ccErrNoMem);
746                 }
747             }
748 
749             if (!err) {
750                 if (!compat_v5creds->client) {
751                     err = cci_check_error (ccErrBadParam);
752                 } else {
753                     v5creds->client = strdup (compat_v5creds->client);
754                     if (!v5creds->client) { err = cci_check_error (ccErrNoMem); }
755                 }
756             }
757 
758             if (!err) {
759                 if (!compat_v5creds->server) {
760                     err = cci_check_error (ccErrBadParam);
761                 } else {
762                     v5creds->server = strdup (compat_v5creds->server);
763                     if (!v5creds->server) { err = cci_check_error (ccErrNoMem); }
764                 }
765             }
766 
767             if (!err) {
768                 err = cci_cc_data_copy_contents (&v5creds->keyblock, &compat_v5creds->keyblock);
769             }
770 
771             if (!err) {
772                 err = cci_cc_data_array_copy (&v5creds->addresses, compat_v5creds->addresses);
773             }
774 
775             if (!err) {
776                 err = cci_cc_data_copy_contents (&v5creds->ticket, &compat_v5creds->ticket);
777             }
778 
779             if (!err) {
780                 err = cci_cc_data_copy_contents (&v5creds->second_ticket, &compat_v5creds->second_ticket);
781             }
782 
783             if (!err) {
784                 err = cci_cc_data_array_copy (&v5creds->authdata, compat_v5creds->authdata);
785             }
786 
787             if (!err) {
788                 creds_union->version = cc_credentials_v5;
789                 creds_union->credentials.credentials_v5 = v5creds;
790 
791                 v5creds->authtime      = compat_v5creds->authtime;
792                 v5creds->starttime     = compat_v5creds->starttime;
793                 v5creds->endtime       = compat_v5creds->endtime;
794                 v5creds->renew_till    = compat_v5creds->renew_till;
795                 v5creds->is_skey       = compat_v5creds->is_skey;
796                 v5creds->ticket_flags  = compat_v5creds->ticket_flags;
797             }
798 
799         } else {
800             err = cci_check_error (ccErrBadCredentialsVersion);
801         }
802     }
803 
804     if (!err) {
805         *out_credentials_union = creds_union;
806         creds_union = NULL;
807     }
808 
809     if (creds_union) { cci_credentials_union_release (creds_union); }
810 
811     return cci_check_error (err);
812 }
813 
814 /* ------------------------------------------------------------------------ */
815 
cci_cred_union_compare_to_credentials_union(const cred_union * in_cred_union_compat,const cc_credentials_union * in_credentials_union,cc_uint32 * out_equal)816 cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union           *in_cred_union_compat,
817                                                        const cc_credentials_union *in_credentials_union,
818                                                        cc_uint32                  *out_equal)
819 {
820     cc_int32 err = ccNoError;
821     cc_uint32 equal = 0;
822 
823     if (!in_cred_union_compat) { err = cci_check_error (ccErrBadParam); }
824     if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
825     if (!out_equal           ) { err = cci_check_error (ccErrBadParam); }
826 
827     if (!err) {
828         if (in_cred_union_compat->cred_type == CC_CRED_V5 &&
829                    in_credentials_union->version == cc_credentials_v5) {
830             cc_credentials_v5_compat *old_creds_v5 = in_cred_union_compat->cred.pV5Cred;
831             cc_credentials_v5_t *new_creds_v5 = in_credentials_union->credentials.credentials_v5;
832 
833             /* Really should use krb5_parse_name and krb5_principal_compare */
834             if (old_creds_v5 && new_creds_v5 &&
835                 !strcmp (old_creds_v5->client, new_creds_v5->client) &&
836                 !strcmp (old_creds_v5->server, new_creds_v5->server) &&
837                 (old_creds_v5->starttime == new_creds_v5->starttime)) {
838                 equal = 1;
839             }
840         }
841     }
842 
843     if (!err) {
844         *out_equal = equal;
845     }
846 
847     return cci_check_error (err);
848 }
849