1b528cefcSMark Murray /* 28373020dSJacques Vidrine * Copyright (c) 1997 - 2002 Kungliga Tekniska H�gskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "krb5_locl.h" 35b528cefcSMark Murray 368373020dSJacques Vidrine RCSID("$Id: fcache.c,v 1.34 2002/04/18 14:01:29 joda Exp $"); 37b528cefcSMark Murray 38b528cefcSMark Murray typedef struct krb5_fcache{ 39b528cefcSMark Murray char *filename; 40b528cefcSMark Murray int version; 41b528cefcSMark Murray }krb5_fcache; 42b528cefcSMark Murray 43b528cefcSMark Murray struct fcc_cursor { 44b528cefcSMark Murray int fd; 45b528cefcSMark Murray krb5_storage *sp; 46b528cefcSMark Murray }; 47b528cefcSMark Murray 48b528cefcSMark Murray #define KRB5_FCC_FVNO_1 1 49b528cefcSMark Murray #define KRB5_FCC_FVNO_2 2 50b528cefcSMark Murray #define KRB5_FCC_FVNO_3 3 51b528cefcSMark Murray #define KRB5_FCC_FVNO_4 4 52b528cefcSMark Murray 53b528cefcSMark Murray #define FCC_TAG_DELTATIME 1 54b528cefcSMark Murray 55b528cefcSMark Murray #define FCACHE(X) ((krb5_fcache*)(X)->data.data) 56b528cefcSMark Murray 57b528cefcSMark Murray #define FILENAME(X) (FCACHE(X)->filename) 58b528cefcSMark Murray 59b528cefcSMark Murray #define FCC_CURSOR(C) ((struct fcc_cursor*)(C)) 60b528cefcSMark Murray 618373020dSJacques Vidrine static const char* 62b528cefcSMark Murray fcc_get_name(krb5_context context, 63b528cefcSMark Murray krb5_ccache id) 64b528cefcSMark Murray { 65b528cefcSMark Murray return FILENAME(id); 66b528cefcSMark Murray } 67b528cefcSMark Murray 68b528cefcSMark Murray static krb5_error_code 69b528cefcSMark Murray fcc_resolve(krb5_context context, krb5_ccache *id, const char *res) 70b528cefcSMark Murray { 71b528cefcSMark Murray krb5_fcache *f; 72b528cefcSMark Murray f = malloc(sizeof(*f)); 73adb0ddaeSAssar Westerlund if(f == NULL) { 74adb0ddaeSAssar Westerlund krb5_set_error_string(context, "malloc: out of memory"); 75b528cefcSMark Murray return KRB5_CC_NOMEM; 76adb0ddaeSAssar Westerlund } 77b528cefcSMark Murray f->filename = strdup(res); 78b528cefcSMark Murray if(f->filename == NULL){ 79b528cefcSMark Murray free(f); 80adb0ddaeSAssar Westerlund krb5_set_error_string(context, "malloc: out of memory"); 81b528cefcSMark Murray return KRB5_CC_NOMEM; 82b528cefcSMark Murray } 83b528cefcSMark Murray f->version = 0; 84b528cefcSMark Murray (*id)->data.data = f; 85b528cefcSMark Murray (*id)->data.length = sizeof(*f); 86b528cefcSMark Murray return 0; 87b528cefcSMark Murray } 88b528cefcSMark Murray 895e9cd1aeSAssar Westerlund /* 905e9cd1aeSAssar Westerlund * Try to scrub the contents of `filename' safely. 915e9cd1aeSAssar Westerlund */ 925e9cd1aeSAssar Westerlund 935e9cd1aeSAssar Westerlund static int 945e9cd1aeSAssar Westerlund scrub_file (int fd) 955e9cd1aeSAssar Westerlund { 965e9cd1aeSAssar Westerlund off_t pos; 975e9cd1aeSAssar Westerlund char buf[128]; 985e9cd1aeSAssar Westerlund 995e9cd1aeSAssar Westerlund pos = lseek(fd, 0, SEEK_END); 1005e9cd1aeSAssar Westerlund if (pos < 0) 1015e9cd1aeSAssar Westerlund return errno; 1025e9cd1aeSAssar Westerlund if (lseek(fd, 0, SEEK_SET) < 0) 1035e9cd1aeSAssar Westerlund return errno; 1045e9cd1aeSAssar Westerlund memset(buf, 0, sizeof(buf)); 1055e9cd1aeSAssar Westerlund while(pos > 0) { 1065e9cd1aeSAssar Westerlund ssize_t tmp = write(fd, buf, min(sizeof(buf), pos)); 1075e9cd1aeSAssar Westerlund 1085e9cd1aeSAssar Westerlund if (tmp < 0) 1095e9cd1aeSAssar Westerlund return errno; 1105e9cd1aeSAssar Westerlund pos -= tmp; 1115e9cd1aeSAssar Westerlund } 1125e9cd1aeSAssar Westerlund fsync (fd); 1135e9cd1aeSAssar Westerlund return 0; 1145e9cd1aeSAssar Westerlund } 1155e9cd1aeSAssar Westerlund 1165e9cd1aeSAssar Westerlund /* 1175e9cd1aeSAssar Westerlund * Erase `filename' if it exists, trying to remove the contents if 1185e9cd1aeSAssar Westerlund * it's `safe'. We always try to remove the file, it it exists. It's 1195e9cd1aeSAssar Westerlund * only overwritten if it's a regular file (not a symlink and not a 1205e9cd1aeSAssar Westerlund * hardlink) 1215e9cd1aeSAssar Westerlund */ 1225e9cd1aeSAssar Westerlund 123b528cefcSMark Murray static krb5_error_code 124b528cefcSMark Murray erase_file(const char *filename) 125b528cefcSMark Murray { 126b528cefcSMark Murray int fd; 1275e9cd1aeSAssar Westerlund struct stat sb1, sb2; 1285e9cd1aeSAssar Westerlund int ret; 1295e9cd1aeSAssar Westerlund 1305e9cd1aeSAssar Westerlund ret = lstat (filename, &sb1); 1315e9cd1aeSAssar Westerlund if (ret < 0) 1325e9cd1aeSAssar Westerlund return errno; 133b528cefcSMark Murray 134b528cefcSMark Murray fd = open(filename, O_RDWR | O_BINARY); 135b528cefcSMark Murray if(fd < 0) { 136b528cefcSMark Murray if(errno == ENOENT) 137b528cefcSMark Murray return 0; 138b528cefcSMark Murray else 139b528cefcSMark Murray return errno; 140b528cefcSMark Murray } 1415e9cd1aeSAssar Westerlund if (unlink(filename) < 0) { 142b528cefcSMark Murray close (fd); 1435e9cd1aeSAssar Westerlund return errno; 1445e9cd1aeSAssar Westerlund } 1455e9cd1aeSAssar Westerlund 1465e9cd1aeSAssar Westerlund ret = fstat (fd, &sb2); 1475e9cd1aeSAssar Westerlund if (ret < 0) { 1485e9cd1aeSAssar Westerlund close (fd); 1495e9cd1aeSAssar Westerlund return errno; 1505e9cd1aeSAssar Westerlund } 1515e9cd1aeSAssar Westerlund 1525e9cd1aeSAssar Westerlund /* check if someone was playing with symlinks */ 1535e9cd1aeSAssar Westerlund 1545e9cd1aeSAssar Westerlund if (sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) { 1555e9cd1aeSAssar Westerlund close (fd); 1565e9cd1aeSAssar Westerlund return EPERM; 1575e9cd1aeSAssar Westerlund } 1585e9cd1aeSAssar Westerlund 1595e9cd1aeSAssar Westerlund /* there are still hard links to this file */ 1605e9cd1aeSAssar Westerlund 1615e9cd1aeSAssar Westerlund if (sb2.st_nlink != 0) { 1625e9cd1aeSAssar Westerlund close (fd); 163b528cefcSMark Murray return 0; 164b528cefcSMark Murray } 165b528cefcSMark Murray 1665e9cd1aeSAssar Westerlund ret = scrub_file (fd); 1675e9cd1aeSAssar Westerlund close (fd); 1685e9cd1aeSAssar Westerlund return ret; 1695e9cd1aeSAssar Westerlund } 1705e9cd1aeSAssar Westerlund 171b528cefcSMark Murray static krb5_error_code 172b528cefcSMark Murray fcc_gen_new(krb5_context context, krb5_ccache *id) 173b528cefcSMark Murray { 174b528cefcSMark Murray krb5_fcache *f; 175b528cefcSMark Murray int fd; 176b528cefcSMark Murray char *file; 177adb0ddaeSAssar Westerlund 178b528cefcSMark Murray f = malloc(sizeof(*f)); 179adb0ddaeSAssar Westerlund if(f == NULL) { 180adb0ddaeSAssar Westerlund krb5_set_error_string(context, "malloc: out of memory"); 181b528cefcSMark Murray return KRB5_CC_NOMEM; 182adb0ddaeSAssar Westerlund } 1835e9cd1aeSAssar Westerlund asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT); 184b528cefcSMark Murray if(file == NULL) { 185b528cefcSMark Murray free(f); 186adb0ddaeSAssar Westerlund krb5_set_error_string(context, "malloc: out of memory"); 187b528cefcSMark Murray return KRB5_CC_NOMEM; 188b528cefcSMark Murray } 189b528cefcSMark Murray fd = mkstemp(file); 190b528cefcSMark Murray if(fd < 0) { 191b528cefcSMark Murray free(f); 192b528cefcSMark Murray free(file); 193adb0ddaeSAssar Westerlund krb5_set_error_string(context, "mkstemp %s", file); 194b528cefcSMark Murray return errno; 195b528cefcSMark Murray } 196b528cefcSMark Murray close(fd); 197b528cefcSMark Murray f->filename = file; 198b528cefcSMark Murray f->version = 0; 199b528cefcSMark Murray (*id)->data.data = f; 200b528cefcSMark Murray (*id)->data.length = sizeof(*f); 201b528cefcSMark Murray return 0; 202b528cefcSMark Murray } 203b528cefcSMark Murray 204b528cefcSMark Murray static void 205b528cefcSMark Murray storage_set_flags(krb5_context context, krb5_storage *sp, int vno) 206b528cefcSMark Murray { 207b528cefcSMark Murray int flags = 0; 208b528cefcSMark Murray switch(vno) { 209b528cefcSMark Murray case KRB5_FCC_FVNO_1: 210b528cefcSMark Murray flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS; 211b528cefcSMark Murray flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE; 212b528cefcSMark Murray flags |= KRB5_STORAGE_HOST_BYTEORDER; 213b528cefcSMark Murray break; 214b528cefcSMark Murray case KRB5_FCC_FVNO_2: 215b528cefcSMark Murray flags |= KRB5_STORAGE_HOST_BYTEORDER; 216b528cefcSMark Murray break; 217b528cefcSMark Murray case KRB5_FCC_FVNO_3: 218b528cefcSMark Murray flags |= KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE; 219b528cefcSMark Murray break; 220b528cefcSMark Murray case KRB5_FCC_FVNO_4: 221b528cefcSMark Murray break; 222b528cefcSMark Murray default: 223b528cefcSMark Murray krb5_abortx(context, 224b528cefcSMark Murray "storage_set_flags called with bad vno (%x)", vno); 225b528cefcSMark Murray } 226b528cefcSMark Murray krb5_storage_set_flags(sp, flags); 227b528cefcSMark Murray } 228b528cefcSMark Murray 229b528cefcSMark Murray static krb5_error_code 230b528cefcSMark Murray fcc_initialize(krb5_context context, 231b528cefcSMark Murray krb5_ccache id, 232b528cefcSMark Murray krb5_principal primary_principal) 233b528cefcSMark Murray { 234b528cefcSMark Murray krb5_fcache *f = FCACHE(id); 2355e9cd1aeSAssar Westerlund int ret = 0; 236b528cefcSMark Murray int fd; 237b528cefcSMark Murray char *filename = f->filename; 238b528cefcSMark Murray 2395e9cd1aeSAssar Westerlund unlink (filename); 240b528cefcSMark Murray 241b528cefcSMark Murray fd = open(filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); 242adb0ddaeSAssar Westerlund if(fd == -1) { 243adb0ddaeSAssar Westerlund ret = errno; 244adb0ddaeSAssar Westerlund krb5_set_error_string(context, "open(%s): %s", filename, 245adb0ddaeSAssar Westerlund strerror(ret)); 246adb0ddaeSAssar Westerlund return ret; 247adb0ddaeSAssar Westerlund } 248b528cefcSMark Murray { 249b528cefcSMark Murray krb5_storage *sp; 250b528cefcSMark Murray sp = krb5_storage_from_fd(fd); 2518373020dSJacques Vidrine krb5_storage_set_eof_code(sp, KRB5_CC_END); 252b528cefcSMark Murray if(context->fcache_vno != 0) 253b528cefcSMark Murray f->version = context->fcache_vno; 254b528cefcSMark Murray else 255b528cefcSMark Murray f->version = KRB5_FCC_FVNO_4; 2565e9cd1aeSAssar Westerlund ret |= krb5_store_int8(sp, 5); 2575e9cd1aeSAssar Westerlund ret |= krb5_store_int8(sp, f->version); 258b528cefcSMark Murray storage_set_flags(context, sp, f->version); 2595e9cd1aeSAssar Westerlund if(f->version == KRB5_FCC_FVNO_4 && ret == 0) { 260b528cefcSMark Murray /* V4 stuff */ 261b528cefcSMark Murray if (context->kdc_sec_offset) { 2625e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, 12); /* length */ 2635e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */ 2645e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, 8); /* length of data */ 2655e9cd1aeSAssar Westerlund ret |= krb5_store_int32 (sp, context->kdc_sec_offset); 2665e9cd1aeSAssar Westerlund ret |= krb5_store_int32 (sp, context->kdc_usec_offset); 267b528cefcSMark Murray } else { 2685e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, 0); 269b528cefcSMark Murray } 270b528cefcSMark Murray } 2715e9cd1aeSAssar Westerlund ret |= krb5_store_principal(sp, primary_principal); 272b528cefcSMark Murray krb5_storage_free(sp); 273b528cefcSMark Murray } 2745e9cd1aeSAssar Westerlund if(close(fd) < 0) 275adb0ddaeSAssar Westerlund if (ret == 0) { 2765e9cd1aeSAssar Westerlund ret = errno; 277adb0ddaeSAssar Westerlund krb5_set_error_string (context, "close %s: %s", filename, 278adb0ddaeSAssar Westerlund strerror(ret)); 279adb0ddaeSAssar Westerlund } 280b528cefcSMark Murray 2815e9cd1aeSAssar Westerlund return ret; 282b528cefcSMark Murray } 283b528cefcSMark Murray 284b528cefcSMark Murray static krb5_error_code 285b528cefcSMark Murray fcc_close(krb5_context context, 286b528cefcSMark Murray krb5_ccache id) 287b528cefcSMark Murray { 288b528cefcSMark Murray free (FILENAME(id)); 289b528cefcSMark Murray krb5_data_free(&id->data); 290b528cefcSMark Murray return 0; 291b528cefcSMark Murray } 292b528cefcSMark Murray 293b528cefcSMark Murray static krb5_error_code 294b528cefcSMark Murray fcc_destroy(krb5_context context, 295b528cefcSMark Murray krb5_ccache id) 296b528cefcSMark Murray { 297b528cefcSMark Murray char *f; 298b528cefcSMark Murray f = FILENAME(id); 299b528cefcSMark Murray 300b528cefcSMark Murray erase_file(f); 301b528cefcSMark Murray 302b528cefcSMark Murray return 0; 303b528cefcSMark Murray } 304b528cefcSMark Murray 305b528cefcSMark Murray static krb5_error_code 306b528cefcSMark Murray fcc_store_cred(krb5_context context, 307b528cefcSMark Murray krb5_ccache id, 308b528cefcSMark Murray krb5_creds *creds) 309b528cefcSMark Murray { 3105e9cd1aeSAssar Westerlund int ret; 311b528cefcSMark Murray int fd; 312b528cefcSMark Murray char *f; 313b528cefcSMark Murray 314b528cefcSMark Murray f = FILENAME(id); 315b528cefcSMark Murray 316b528cefcSMark Murray fd = open(f, O_WRONLY | O_APPEND | O_BINARY); 317adb0ddaeSAssar Westerlund if(fd < 0) { 318adb0ddaeSAssar Westerlund ret = errno; 319adb0ddaeSAssar Westerlund krb5_set_error_string (context, "open(%s): %s", f, strerror(ret)); 320adb0ddaeSAssar Westerlund return ret; 321adb0ddaeSAssar Westerlund } 322b528cefcSMark Murray { 323b528cefcSMark Murray krb5_storage *sp; 324b528cefcSMark Murray sp = krb5_storage_from_fd(fd); 3258373020dSJacques Vidrine krb5_storage_set_eof_code(sp, KRB5_CC_END); 326b528cefcSMark Murray storage_set_flags(context, sp, FCACHE(id)->version); 3275e9cd1aeSAssar Westerlund ret = krb5_store_creds(sp, creds); 328b528cefcSMark Murray krb5_storage_free(sp); 329b528cefcSMark Murray } 3305e9cd1aeSAssar Westerlund if (close(fd) < 0) 331adb0ddaeSAssar Westerlund if (ret == 0) { 3325e9cd1aeSAssar Westerlund ret = errno; 333adb0ddaeSAssar Westerlund krb5_set_error_string (context, "close %s: %s", f, strerror(ret)); 334adb0ddaeSAssar Westerlund } 3355e9cd1aeSAssar Westerlund return ret; 336b528cefcSMark Murray } 337b528cefcSMark Murray 338b528cefcSMark Murray static krb5_error_code 339b528cefcSMark Murray fcc_read_cred (krb5_context context, 340b528cefcSMark Murray krb5_fcache *fc, 341b528cefcSMark Murray krb5_storage *sp, 342b528cefcSMark Murray krb5_creds *creds) 343b528cefcSMark Murray { 344b528cefcSMark Murray krb5_error_code ret; 345b528cefcSMark Murray 346b528cefcSMark Murray storage_set_flags(context, sp, fc->version); 347b528cefcSMark Murray 348b528cefcSMark Murray ret = krb5_ret_creds(sp, creds); 349b528cefcSMark Murray return ret; 350b528cefcSMark Murray } 351b528cefcSMark Murray 352b528cefcSMark Murray static krb5_error_code 353b528cefcSMark Murray init_fcc (krb5_context context, 354b528cefcSMark Murray krb5_fcache *fcache, 355b528cefcSMark Murray krb5_storage **ret_sp, 356b528cefcSMark Murray int *ret_fd) 357b528cefcSMark Murray { 358b528cefcSMark Murray int fd; 359b528cefcSMark Murray int8_t pvno, tag; 360b528cefcSMark Murray krb5_storage *sp; 3615e9cd1aeSAssar Westerlund krb5_error_code ret; 362b528cefcSMark Murray 363b528cefcSMark Murray fd = open(fcache->filename, O_RDONLY | O_BINARY); 364adb0ddaeSAssar Westerlund if(fd < 0) { 365adb0ddaeSAssar Westerlund ret = errno; 366adb0ddaeSAssar Westerlund krb5_set_error_string(context, "open(%s): %s", fcache->filename, 367adb0ddaeSAssar Westerlund strerror(ret)); 368adb0ddaeSAssar Westerlund return ret; 369adb0ddaeSAssar Westerlund } 370b528cefcSMark Murray sp = krb5_storage_from_fd(fd); 3718373020dSJacques Vidrine krb5_storage_set_eof_code(sp, KRB5_CC_END); 3725e9cd1aeSAssar Westerlund ret = krb5_ret_int8(sp, &pvno); 3738373020dSJacques Vidrine if(ret == KRB5_CC_END) 3745e9cd1aeSAssar Westerlund return ENOENT; 3755e9cd1aeSAssar Westerlund if(ret) 3765e9cd1aeSAssar Westerlund return ret; 377b528cefcSMark Murray if(pvno != 5) { 378b528cefcSMark Murray krb5_storage_free(sp); 379b528cefcSMark Murray close(fd); 380b528cefcSMark Murray return KRB5_CCACHE_BADVNO; 381b528cefcSMark Murray } 382b528cefcSMark Murray krb5_ret_int8(sp, &tag); /* should not be host byte order */ 383b528cefcSMark Murray fcache->version = tag; 384b528cefcSMark Murray storage_set_flags(context, sp, fcache->version); 385b528cefcSMark Murray switch (tag) { 386b528cefcSMark Murray case KRB5_FCC_FVNO_4: { 387b528cefcSMark Murray int16_t length; 388b528cefcSMark Murray 389b528cefcSMark Murray krb5_ret_int16 (sp, &length); 390b528cefcSMark Murray while(length > 0) { 391b528cefcSMark Murray int16_t tag, data_len; 392b528cefcSMark Murray int i; 393b528cefcSMark Murray int8_t dummy; 394b528cefcSMark Murray 395b528cefcSMark Murray krb5_ret_int16 (sp, &tag); 396b528cefcSMark Murray krb5_ret_int16 (sp, &data_len); 397b528cefcSMark Murray switch (tag) { 398b528cefcSMark Murray case FCC_TAG_DELTATIME : 399b528cefcSMark Murray krb5_ret_int32 (sp, &context->kdc_sec_offset); 400b528cefcSMark Murray krb5_ret_int32 (sp, &context->kdc_usec_offset); 401b528cefcSMark Murray break; 402b528cefcSMark Murray default : 403b528cefcSMark Murray for (i = 0; i < data_len; ++i) 404b528cefcSMark Murray krb5_ret_int8 (sp, &dummy); 405b528cefcSMark Murray break; 406b528cefcSMark Murray } 407b528cefcSMark Murray length -= 4 + data_len; 408b528cefcSMark Murray } 409b528cefcSMark Murray break; 410b528cefcSMark Murray } 411b528cefcSMark Murray case KRB5_FCC_FVNO_3: 412b528cefcSMark Murray case KRB5_FCC_FVNO_2: 413b528cefcSMark Murray case KRB5_FCC_FVNO_1: 414b528cefcSMark Murray break; 415b528cefcSMark Murray default : 416b528cefcSMark Murray krb5_storage_free (sp); 417b528cefcSMark Murray close (fd); 418b528cefcSMark Murray return KRB5_CCACHE_BADVNO; 419b528cefcSMark Murray } 420b528cefcSMark Murray *ret_sp = sp; 421b528cefcSMark Murray *ret_fd = fd; 422b528cefcSMark Murray return 0; 423b528cefcSMark Murray } 424b528cefcSMark Murray 425b528cefcSMark Murray static krb5_error_code 426b528cefcSMark Murray fcc_get_principal(krb5_context context, 427b528cefcSMark Murray krb5_ccache id, 428b528cefcSMark Murray krb5_principal *principal) 429b528cefcSMark Murray { 430b528cefcSMark Murray krb5_error_code ret; 431b528cefcSMark Murray krb5_fcache *f = FCACHE(id); 432b528cefcSMark Murray int fd; 433b528cefcSMark Murray krb5_storage *sp; 434b528cefcSMark Murray 435b528cefcSMark Murray ret = init_fcc (context, f, &sp, &fd); 436b528cefcSMark Murray if (ret) 437b528cefcSMark Murray return ret; 4385e9cd1aeSAssar Westerlund ret = krb5_ret_principal(sp, principal); 439b528cefcSMark Murray krb5_storage_free(sp); 440b528cefcSMark Murray close(fd); 4415e9cd1aeSAssar Westerlund return ret; 442b528cefcSMark Murray } 443b528cefcSMark Murray 444b528cefcSMark Murray static krb5_error_code 445b528cefcSMark Murray fcc_get_first (krb5_context context, 446b528cefcSMark Murray krb5_ccache id, 447b528cefcSMark Murray krb5_cc_cursor *cursor) 448b528cefcSMark Murray { 449b528cefcSMark Murray krb5_error_code ret; 450b528cefcSMark Murray krb5_principal principal; 451b528cefcSMark Murray krb5_fcache *f = FCACHE(id); 452b528cefcSMark Murray 453b528cefcSMark Murray *cursor = malloc(sizeof(struct fcc_cursor)); 454b528cefcSMark Murray 455b528cefcSMark Murray ret = init_fcc (context, f, &FCC_CURSOR(*cursor)->sp, 456b528cefcSMark Murray &FCC_CURSOR(*cursor)->fd); 457b528cefcSMark Murray if (ret) 458b528cefcSMark Murray return ret; 459b528cefcSMark Murray krb5_ret_principal (FCC_CURSOR(*cursor)->sp, &principal); 460b528cefcSMark Murray krb5_free_principal (context, principal); 461b528cefcSMark Murray return 0; 462b528cefcSMark Murray } 463b528cefcSMark Murray 464b528cefcSMark Murray static krb5_error_code 465b528cefcSMark Murray fcc_get_next (krb5_context context, 466b528cefcSMark Murray krb5_ccache id, 467b528cefcSMark Murray krb5_cc_cursor *cursor, 468b528cefcSMark Murray krb5_creds *creds) 469b528cefcSMark Murray { 470b528cefcSMark Murray return fcc_read_cred (context, FCACHE(id), FCC_CURSOR(*cursor)->sp, creds); 471b528cefcSMark Murray } 472b528cefcSMark Murray 473b528cefcSMark Murray static krb5_error_code 474b528cefcSMark Murray fcc_end_get (krb5_context context, 475b528cefcSMark Murray krb5_ccache id, 476b528cefcSMark Murray krb5_cc_cursor *cursor) 477b528cefcSMark Murray { 478b528cefcSMark Murray krb5_storage_free(FCC_CURSOR(*cursor)->sp); 479b528cefcSMark Murray close (FCC_CURSOR(*cursor)->fd); 480b528cefcSMark Murray free(*cursor); 481b528cefcSMark Murray return 0; 482b528cefcSMark Murray } 483b528cefcSMark Murray 484b528cefcSMark Murray static krb5_error_code 485b528cefcSMark Murray fcc_remove_cred(krb5_context context, 486b528cefcSMark Murray krb5_ccache id, 487b528cefcSMark Murray krb5_flags which, 488b528cefcSMark Murray krb5_creds *cred) 489b528cefcSMark Murray { 490b528cefcSMark Murray return 0; /* XXX */ 491b528cefcSMark Murray } 492b528cefcSMark Murray 493b528cefcSMark Murray static krb5_error_code 494b528cefcSMark Murray fcc_set_flags(krb5_context context, 495b528cefcSMark Murray krb5_ccache id, 496b528cefcSMark Murray krb5_flags flags) 497b528cefcSMark Murray { 498b528cefcSMark Murray return 0; /* XXX */ 499b528cefcSMark Murray } 500b528cefcSMark Murray 501b528cefcSMark Murray static krb5_error_code 502b528cefcSMark Murray fcc_get_version(krb5_context context, 503b528cefcSMark Murray krb5_ccache id) 504b528cefcSMark Murray { 505b528cefcSMark Murray return FCACHE(id)->version; 506b528cefcSMark Murray } 507b528cefcSMark Murray 508b528cefcSMark Murray const krb5_cc_ops krb5_fcc_ops = { 509b528cefcSMark Murray "FILE", 510b528cefcSMark Murray fcc_get_name, 511b528cefcSMark Murray fcc_resolve, 512b528cefcSMark Murray fcc_gen_new, 513b528cefcSMark Murray fcc_initialize, 514b528cefcSMark Murray fcc_destroy, 515b528cefcSMark Murray fcc_close, 516b528cefcSMark Murray fcc_store_cred, 517b528cefcSMark Murray NULL, /* fcc_retrieve */ 518b528cefcSMark Murray fcc_get_principal, 519b528cefcSMark Murray fcc_get_first, 520b528cefcSMark Murray fcc_get_next, 521b528cefcSMark Murray fcc_end_get, 522b528cefcSMark Murray fcc_remove_cred, 523b528cefcSMark Murray fcc_set_flags, 524b528cefcSMark Murray fcc_get_version 525b528cefcSMark Murray }; 526