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