17c478bd9Sstevel@tonic-gate /* 2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate 77c478bd9Sstevel@tonic-gate /* 87c478bd9Sstevel@tonic-gate * lib/krb5/rcache/ser_rc.c 97c478bd9Sstevel@tonic-gate * 107c478bd9Sstevel@tonic-gate * Copyright 1995 by the Massachusetts Institute of Technology. 117c478bd9Sstevel@tonic-gate * All Rights Reserved. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 177c478bd9Sstevel@tonic-gate * 187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 307c478bd9Sstevel@tonic-gate * or implied warranty. 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * ser_rcdfl.c - Serialize replay cache context. 367c478bd9Sstevel@tonic-gate */ 37*159d09a2SMark Phalan #include "k5-int.h" 38505d05c7Sgtb #include "rc-int.h" 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * Routines to deal with externalizing krb5_rcache. 427c478bd9Sstevel@tonic-gate * krb5_rcache_size(); 437c478bd9Sstevel@tonic-gate * krb5_rcache_externalize(); 447c478bd9Sstevel@tonic-gate * krb5_rcache_internalize(); 457c478bd9Sstevel@tonic-gate */ 467c478bd9Sstevel@tonic-gate static krb5_error_code krb5_rcache_size 47505d05c7Sgtb (krb5_context, krb5_pointer, size_t *); 487c478bd9Sstevel@tonic-gate static krb5_error_code krb5_rcache_externalize 49505d05c7Sgtb (krb5_context, krb5_pointer, krb5_octet **, size_t *); 507c478bd9Sstevel@tonic-gate static krb5_error_code krb5_rcache_internalize 51505d05c7Sgtb (krb5_context,krb5_pointer *, krb5_octet **, size_t *); 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* 547c478bd9Sstevel@tonic-gate * Serialization entry for this type. 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate static const krb5_ser_entry krb5_rcache_ser_entry = { 577c478bd9Sstevel@tonic-gate KV5M_RCACHE, /* Type */ 587c478bd9Sstevel@tonic-gate krb5_rcache_size, /* Sizer routine */ 597c478bd9Sstevel@tonic-gate krb5_rcache_externalize, /* Externalize routine */ 607c478bd9Sstevel@tonic-gate krb5_rcache_internalize /* Internalize routine */ 617c478bd9Sstevel@tonic-gate }; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* 647c478bd9Sstevel@tonic-gate * krb5_rcache_size() - Determine the size required to externalize 657c478bd9Sstevel@tonic-gate * this krb5_rcache variant. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate static krb5_error_code 68505d05c7Sgtb krb5_rcache_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) 697c478bd9Sstevel@tonic-gate { 707c478bd9Sstevel@tonic-gate krb5_error_code kret; 717c478bd9Sstevel@tonic-gate krb5_rcache rcache; 727c478bd9Sstevel@tonic-gate size_t required; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate kret = EINVAL; 75*159d09a2SMark Phalan /* Solaris Kerberos */ 767c478bd9Sstevel@tonic-gate if ((rcache = (krb5_rcache) arg) != NULL) { 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * Saving FILE: variants of krb5_rcache requires at minimum: 797c478bd9Sstevel@tonic-gate * krb5_int32 for KV5M_RCACHE 807c478bd9Sstevel@tonic-gate * krb5_int32 for length of rcache name. 817c478bd9Sstevel@tonic-gate * krb5_int32 for KV5M_RCACHE 827c478bd9Sstevel@tonic-gate */ 837c478bd9Sstevel@tonic-gate required = sizeof(krb5_int32) * 3; 847c478bd9Sstevel@tonic-gate if (rcache->ops && rcache->ops->type) 857c478bd9Sstevel@tonic-gate required += (strlen(rcache->ops->type)+1); 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate /* 887c478bd9Sstevel@tonic-gate * The rcache name is formed as follows: 897c478bd9Sstevel@tonic-gate * <type>:<name> 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate required += strlen(krb5_rc_get_name(kcontext, rcache)); 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate kret = 0; 947c478bd9Sstevel@tonic-gate *sizep += required; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate return(kret); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * krb5_rcache_externalize() - Externalize the krb5_rcache. 1017c478bd9Sstevel@tonic-gate */ 1027c478bd9Sstevel@tonic-gate static krb5_error_code 103505d05c7Sgtb krb5_rcache_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **buffer, size_t *lenremain) 1047c478bd9Sstevel@tonic-gate { 1057c478bd9Sstevel@tonic-gate krb5_error_code kret; 1067c478bd9Sstevel@tonic-gate krb5_rcache rcache; 1077c478bd9Sstevel@tonic-gate size_t required; 1087c478bd9Sstevel@tonic-gate krb5_octet *bp; 1097c478bd9Sstevel@tonic-gate size_t remain; 1107c478bd9Sstevel@tonic-gate char *rcname; 1117c478bd9Sstevel@tonic-gate size_t namelen; 1127c478bd9Sstevel@tonic-gate char *fnamep; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate required = 0; 1157c478bd9Sstevel@tonic-gate bp = *buffer; 1167c478bd9Sstevel@tonic-gate remain = *lenremain; 1177c478bd9Sstevel@tonic-gate kret = EINVAL; 118*159d09a2SMark Phalan /* Solaris Kerberos */ 1197c478bd9Sstevel@tonic-gate if ((rcache = (krb5_rcache) arg) != NULL) { 1207c478bd9Sstevel@tonic-gate kret = ENOMEM; 1217c478bd9Sstevel@tonic-gate if (!krb5_rcache_size(kcontext, arg, &required) && 1227c478bd9Sstevel@tonic-gate (required <= remain)) { 1237c478bd9Sstevel@tonic-gate /* Our identifier */ 1247c478bd9Sstevel@tonic-gate (void) krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /* Calculate the length of the name */ 1277c478bd9Sstevel@tonic-gate namelen = (rcache->ops && rcache->ops->type) ? 1287c478bd9Sstevel@tonic-gate strlen(rcache->ops->type)+1 : 0; 1297c478bd9Sstevel@tonic-gate fnamep = krb5_rc_get_name(kcontext, rcache); 1307c478bd9Sstevel@tonic-gate namelen += (strlen(fnamep)+1); 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate if ((rcname = (char *) malloc(namelen))) { 1337c478bd9Sstevel@tonic-gate /* Format the rcache name. */ 1347c478bd9Sstevel@tonic-gate if (rcache->ops && rcache->ops->type) 1357c478bd9Sstevel@tonic-gate sprintf(rcname, "%s:%s", rcache->ops->type, fnamep); 1367c478bd9Sstevel@tonic-gate else 1377c478bd9Sstevel@tonic-gate strcpy(rcname, fnamep); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* Put the length of the file name */ 1407c478bd9Sstevel@tonic-gate (void) krb5_ser_pack_int32((krb5_int32) strlen(rcname), 1417c478bd9Sstevel@tonic-gate &bp, &remain); 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate /* Put the name */ 1447c478bd9Sstevel@tonic-gate (void) krb5_ser_pack_bytes((krb5_octet *) rcname, 1457c478bd9Sstevel@tonic-gate strlen(rcname), 1467c478bd9Sstevel@tonic-gate &bp, &remain); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate /* Put the trailer */ 1497c478bd9Sstevel@tonic-gate (void) krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); 1507c478bd9Sstevel@tonic-gate kret = 0; 1517c478bd9Sstevel@tonic-gate *buffer = bp; 1527c478bd9Sstevel@tonic-gate *lenremain = remain; 1537c478bd9Sstevel@tonic-gate free(rcname); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate return(kret); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate /* 1617c478bd9Sstevel@tonic-gate * krb5_rcache_internalize() - Internalize the krb5_rcache. 1627c478bd9Sstevel@tonic-gate */ 1637c478bd9Sstevel@tonic-gate static krb5_error_code 164505d05c7Sgtb krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) 1657c478bd9Sstevel@tonic-gate { 1667c478bd9Sstevel@tonic-gate krb5_error_code kret; 1677c478bd9Sstevel@tonic-gate krb5_rcache rcache; 1687c478bd9Sstevel@tonic-gate krb5_int32 ibuf; 1697c478bd9Sstevel@tonic-gate krb5_octet *bp; 1707c478bd9Sstevel@tonic-gate size_t remain; 1717c478bd9Sstevel@tonic-gate char *rcname; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate bp = *buffer; 1747c478bd9Sstevel@tonic-gate remain = *lenremain; 1757c478bd9Sstevel@tonic-gate kret = EINVAL; 1767c478bd9Sstevel@tonic-gate /* Read our magic number */ 1777c478bd9Sstevel@tonic-gate if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 1787c478bd9Sstevel@tonic-gate ibuf = 0; 1797c478bd9Sstevel@tonic-gate if (ibuf == KV5M_RCACHE) { 1807c478bd9Sstevel@tonic-gate kret = ENOMEM; 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate /* Get the length of the rcache name */ 1837c478bd9Sstevel@tonic-gate kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if (!kret && 1867c478bd9Sstevel@tonic-gate (rcname = (char *) malloc((size_t) (ibuf+1))) && 1877c478bd9Sstevel@tonic-gate !(kret = krb5_ser_unpack_bytes((krb5_octet *) rcname, 1887c478bd9Sstevel@tonic-gate (size_t) ibuf, 1897c478bd9Sstevel@tonic-gate &bp, &remain))) { 1907c478bd9Sstevel@tonic-gate rcname[ibuf] = '\0'; 1917c478bd9Sstevel@tonic-gate if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname))) { 1927c478bd9Sstevel@tonic-gate (void) krb5_rc_recover(kcontext, rcache); 193*159d09a2SMark Phalan if (!kret && 1947c478bd9Sstevel@tonic-gate !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && 1957c478bd9Sstevel@tonic-gate (ibuf == KV5M_RCACHE)) { 1967c478bd9Sstevel@tonic-gate *buffer = bp; 1977c478bd9Sstevel@tonic-gate *lenremain = remain; 1987c478bd9Sstevel@tonic-gate *argp = (krb5_pointer) rcache; 1997c478bd9Sstevel@tonic-gate } 200*159d09a2SMark Phalan else /* Solaris Kerberos */ 2017c478bd9Sstevel@tonic-gate (void)krb5_rc_close(kcontext, rcache); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate free(rcname); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate return(kret); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * Register the rcache serializer. 2117c478bd9Sstevel@tonic-gate */ 212505d05c7Sgtb krb5_error_code KRB5_CALLCONV 213505d05c7Sgtb krb5_ser_rcache_init(krb5_context kcontext) 2147c478bd9Sstevel@tonic-gate { 2157c478bd9Sstevel@tonic-gate return(krb5_register_serializer(kcontext, &krb5_rcache_ser_entry)); 2167c478bd9Sstevel@tonic-gate } 217