1 /* 2 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/krb5/rcache/ser_rc.c 10 * 11 * Copyright 1995 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. 18 * 19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. 32 * 33 */ 34 35 /* 36 * ser_rcdfl.c - Serialize replay cache context. 37 */ 38 #include <k5-int.h> 39 40 /* 41 * Routines to deal with externalizing krb5_rcache. 42 * krb5_rcache_size(); 43 * krb5_rcache_externalize(); 44 * krb5_rcache_internalize(); 45 */ 46 static krb5_error_code krb5_rcache_size 47 KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); 48 static krb5_error_code krb5_rcache_externalize 49 KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); 50 static krb5_error_code krb5_rcache_internalize 51 KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); 52 53 /* 54 * Serialization entry for this type. 55 */ 56 static const krb5_ser_entry krb5_rcache_ser_entry = { 57 KV5M_RCACHE, /* Type */ 58 krb5_rcache_size, /* Sizer routine */ 59 krb5_rcache_externalize, /* Externalize routine */ 60 krb5_rcache_internalize /* Internalize routine */ 61 }; 62 63 /* 64 * krb5_rcache_size() - Determine the size required to externalize 65 * this krb5_rcache variant. 66 */ 67 static krb5_error_code 68 krb5_rcache_size(kcontext, arg, sizep) 69 krb5_context kcontext; 70 krb5_pointer arg; 71 size_t *sizep; 72 { 73 krb5_error_code kret; 74 krb5_rcache rcache; 75 size_t required; 76 77 kret = EINVAL; 78 if ((rcache = (krb5_rcache) arg) != NULL) { 79 /* 80 * Saving FILE: variants of krb5_rcache requires at minimum: 81 * krb5_int32 for KV5M_RCACHE 82 * krb5_int32 for length of rcache name. 83 * krb5_int32 for KV5M_RCACHE 84 */ 85 required = sizeof(krb5_int32) * 3; 86 if (rcache->ops && rcache->ops->type) 87 required += (strlen(rcache->ops->type)+1); 88 89 /* 90 * The rcache name is formed as follows: 91 * <type>:<name> 92 */ 93 required += strlen(krb5_rc_get_name(kcontext, rcache)); 94 95 kret = 0; 96 *sizep += required; 97 } 98 return(kret); 99 } 100 101 /* 102 * krb5_rcache_externalize() - Externalize the krb5_rcache. 103 */ 104 static krb5_error_code 105 krb5_rcache_externalize(kcontext, arg, buffer, lenremain) 106 krb5_context kcontext; 107 krb5_pointer arg; 108 krb5_octet **buffer; 109 size_t *lenremain; 110 { 111 krb5_error_code kret; 112 krb5_rcache rcache; 113 size_t required; 114 krb5_octet *bp; 115 size_t remain; 116 char *rcname; 117 size_t namelen; 118 char *fnamep; 119 120 required = 0; 121 bp = *buffer; 122 remain = *lenremain; 123 kret = EINVAL; 124 if ((rcache = (krb5_rcache) arg) != NULL) { 125 kret = ENOMEM; 126 if (!krb5_rcache_size(kcontext, arg, &required) && 127 (required <= remain)) { 128 /* Our identifier */ 129 (void) krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); 130 131 /* Calculate the length of the name */ 132 namelen = (rcache->ops && rcache->ops->type) ? 133 strlen(rcache->ops->type)+1 : 0; 134 fnamep = krb5_rc_get_name(kcontext, rcache); 135 namelen += (strlen(fnamep)+1); 136 137 if ((rcname = (char *) malloc(namelen))) { 138 /* Format the rcache name. */ 139 if (rcache->ops && rcache->ops->type) 140 sprintf(rcname, "%s:%s", rcache->ops->type, fnamep); 141 else 142 strcpy(rcname, fnamep); 143 144 /* Put the length of the file name */ 145 (void) krb5_ser_pack_int32((krb5_int32) strlen(rcname), 146 &bp, &remain); 147 148 /* Put the name */ 149 (void) krb5_ser_pack_bytes((krb5_octet *) rcname, 150 strlen(rcname), 151 &bp, &remain); 152 153 /* Put the trailer */ 154 (void) krb5_ser_pack_int32(KV5M_RCACHE, &bp, &remain); 155 kret = 0; 156 *buffer = bp; 157 *lenremain = remain; 158 free(rcname); 159 } 160 } 161 } 162 return(kret); 163 } 164 165 /* 166 * krb5_rcache_internalize() - Internalize the krb5_rcache. 167 */ 168 static krb5_error_code 169 krb5_rcache_internalize(kcontext, argp, buffer, lenremain) 170 krb5_context kcontext; 171 krb5_pointer *argp; 172 krb5_octet **buffer; 173 size_t *lenremain; 174 { 175 krb5_error_code kret; 176 krb5_rcache rcache; 177 krb5_int32 ibuf; 178 krb5_octet *bp; 179 size_t remain; 180 char *rcname; 181 182 bp = *buffer; 183 remain = *lenremain; 184 kret = EINVAL; 185 /* Read our magic number */ 186 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 187 ibuf = 0; 188 if (ibuf == KV5M_RCACHE) { 189 kret = ENOMEM; 190 191 /* Get the length of the rcache name */ 192 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 193 194 if (!kret && 195 (rcname = (char *) malloc((size_t) (ibuf+1))) && 196 !(kret = krb5_ser_unpack_bytes((krb5_octet *) rcname, 197 (size_t) ibuf, 198 &bp, &remain))) { 199 rcname[ibuf] = '\0'; 200 if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname))) { 201 (void) krb5_rc_close(kcontext, rcache); 202 (void) krb5_rc_recover(kcontext, rcache); 203 if (!kret && 204 !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && 205 (ibuf == KV5M_RCACHE)) { 206 *buffer = bp; 207 *lenremain = remain; 208 *argp = (krb5_pointer) rcache; 209 } 210 else 211 (void)krb5_rc_close(kcontext, rcache); 212 } 213 free(rcname); 214 } 215 } 216 return(kret); 217 } 218 219 /* 220 * Register the rcache serializer. 221 */ 222 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 223 krb5_ser_rcache_init(kcontext) 224 krb5_context kcontext; 225 { 226 return(krb5_register_serializer(kcontext, &krb5_rcache_ser_entry)); 227 } 228