1b528cefcSMark Murray /* 2adb0ddaeSAssar Westerlund * Copyright (c) 1997 - 2001 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 36adb0ddaeSAssar Westerlund RCSID("$Id: fcache.c,v 1.33 2001/05/14 06:14:46 assar 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 61b528cefcSMark Murray static 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); 251b528cefcSMark Murray if(context->fcache_vno != 0) 252b528cefcSMark Murray f->version = context->fcache_vno; 253b528cefcSMark Murray else 254b528cefcSMark Murray f->version = KRB5_FCC_FVNO_4; 2555e9cd1aeSAssar Westerlund ret |= krb5_store_int8(sp, 5); 2565e9cd1aeSAssar Westerlund ret |= krb5_store_int8(sp, f->version); 257b528cefcSMark Murray storage_set_flags(context, sp, f->version); 2585e9cd1aeSAssar Westerlund if(f->version == KRB5_FCC_FVNO_4 && ret == 0) { 259b528cefcSMark Murray /* V4 stuff */ 260b528cefcSMark Murray if (context->kdc_sec_offset) { 2615e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, 12); /* length */ 2625e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */ 2635e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, 8); /* length of data */ 2645e9cd1aeSAssar Westerlund ret |= krb5_store_int32 (sp, context->kdc_sec_offset); 2655e9cd1aeSAssar Westerlund ret |= krb5_store_int32 (sp, context->kdc_usec_offset); 266b528cefcSMark Murray } else { 2675e9cd1aeSAssar Westerlund ret |= krb5_store_int16 (sp, 0); 268b528cefcSMark Murray } 269b528cefcSMark Murray } 2705e9cd1aeSAssar Westerlund ret |= krb5_store_principal(sp, primary_principal); 271b528cefcSMark Murray krb5_storage_free(sp); 272b528cefcSMark Murray } 2735e9cd1aeSAssar Westerlund if(close(fd) < 0) 274adb0ddaeSAssar Westerlund if (ret == 0) { 2755e9cd1aeSAssar Westerlund ret = errno; 276adb0ddaeSAssar Westerlund krb5_set_error_string (context, "close %s: %s", filename, 277adb0ddaeSAssar Westerlund strerror(ret)); 278adb0ddaeSAssar Westerlund } 279b528cefcSMark Murray 2805e9cd1aeSAssar Westerlund return ret; 281b528cefcSMark Murray } 282b528cefcSMark Murray 283b528cefcSMark Murray static krb5_error_code 284b528cefcSMark Murray fcc_close(krb5_context context, 285b528cefcSMark Murray krb5_ccache id) 286b528cefcSMark Murray { 287b528cefcSMark Murray free (FILENAME(id)); 288b528cefcSMark Murray krb5_data_free(&id->data); 289b528cefcSMark Murray return 0; 290b528cefcSMark Murray } 291b528cefcSMark Murray 292b528cefcSMark Murray static krb5_error_code 293b528cefcSMark Murray fcc_destroy(krb5_context context, 294b528cefcSMark Murray krb5_ccache id) 295b528cefcSMark Murray { 296b528cefcSMark Murray char *f; 297b528cefcSMark Murray f = FILENAME(id); 298b528cefcSMark Murray 299b528cefcSMark Murray erase_file(f); 300b528cefcSMark Murray 301b528cefcSMark Murray return 0; 302b528cefcSMark Murray } 303b528cefcSMark Murray 304b528cefcSMark Murray static krb5_error_code 305b528cefcSMark Murray fcc_store_cred(krb5_context context, 306b528cefcSMark Murray krb5_ccache id, 307b528cefcSMark Murray krb5_creds *creds) 308b528cefcSMark Murray { 3095e9cd1aeSAssar Westerlund int ret; 310b528cefcSMark Murray int fd; 311b528cefcSMark Murray char *f; 312b528cefcSMark Murray 313b528cefcSMark Murray f = FILENAME(id); 314b528cefcSMark Murray 315b528cefcSMark Murray fd = open(f, O_WRONLY | O_APPEND | O_BINARY); 316adb0ddaeSAssar Westerlund if(fd < 0) { 317adb0ddaeSAssar Westerlund ret = errno; 318adb0ddaeSAssar Westerlund krb5_set_error_string (context, "open(%s): %s", f, strerror(ret)); 319adb0ddaeSAssar Westerlund return ret; 320adb0ddaeSAssar Westerlund } 321b528cefcSMark Murray { 322b528cefcSMark Murray krb5_storage *sp; 323b528cefcSMark Murray sp = krb5_storage_from_fd(fd); 324b528cefcSMark Murray storage_set_flags(context, sp, FCACHE(id)->version); 3255e9cd1aeSAssar Westerlund ret = krb5_store_creds(sp, creds); 326b528cefcSMark Murray krb5_storage_free(sp); 327b528cefcSMark Murray } 3285e9cd1aeSAssar Westerlund if (close(fd) < 0) 329adb0ddaeSAssar Westerlund if (ret == 0) { 3305e9cd1aeSAssar Westerlund ret = errno; 331adb0ddaeSAssar Westerlund krb5_set_error_string (context, "close %s: %s", f, strerror(ret)); 332adb0ddaeSAssar Westerlund } 3335e9cd1aeSAssar Westerlund return ret; 334b528cefcSMark Murray } 335b528cefcSMark Murray 336b528cefcSMark Murray static krb5_error_code 337b528cefcSMark Murray fcc_read_cred (krb5_context context, 338b528cefcSMark Murray krb5_fcache *fc, 339b528cefcSMark Murray krb5_storage *sp, 340b528cefcSMark Murray krb5_creds *creds) 341b528cefcSMark Murray { 342b528cefcSMark Murray krb5_error_code ret; 343b528cefcSMark Murray 344b528cefcSMark Murray storage_set_flags(context, sp, fc->version); 345b528cefcSMark Murray 346b528cefcSMark Murray ret = krb5_ret_creds(sp, creds); 347b528cefcSMark Murray return ret; 348b528cefcSMark Murray } 349b528cefcSMark Murray 350b528cefcSMark Murray static krb5_error_code 351b528cefcSMark Murray init_fcc (krb5_context context, 352b528cefcSMark Murray krb5_fcache *fcache, 353b528cefcSMark Murray krb5_storage **ret_sp, 354b528cefcSMark Murray int *ret_fd) 355b528cefcSMark Murray { 356b528cefcSMark Murray int fd; 357b528cefcSMark Murray int8_t pvno, tag; 358b528cefcSMark Murray krb5_storage *sp; 3595e9cd1aeSAssar Westerlund krb5_error_code ret; 360b528cefcSMark Murray 361b528cefcSMark Murray fd = open(fcache->filename, O_RDONLY | O_BINARY); 362adb0ddaeSAssar Westerlund if(fd < 0) { 363adb0ddaeSAssar Westerlund ret = errno; 364adb0ddaeSAssar Westerlund krb5_set_error_string(context, "open(%s): %s", fcache->filename, 365adb0ddaeSAssar Westerlund strerror(ret)); 366adb0ddaeSAssar Westerlund return ret; 367adb0ddaeSAssar Westerlund } 368b528cefcSMark Murray sp = krb5_storage_from_fd(fd); 3695e9cd1aeSAssar Westerlund ret = krb5_ret_int8(sp, &pvno); 370adb0ddaeSAssar Westerlund if(ret == KRB5_CC_END) { 371adb0ddaeSAssar Westerlund 3725e9cd1aeSAssar Westerlund return ENOENT; 373adb0ddaeSAssar Westerlund } 3745e9cd1aeSAssar Westerlund if(ret) 3755e9cd1aeSAssar Westerlund return ret; 376b528cefcSMark Murray if(pvno != 5) { 377b528cefcSMark Murray krb5_storage_free(sp); 378b528cefcSMark Murray close(fd); 379b528cefcSMark Murray return KRB5_CCACHE_BADVNO; 380b528cefcSMark Murray } 381b528cefcSMark Murray krb5_ret_int8(sp, &tag); /* should not be host byte order */ 382b528cefcSMark Murray fcache->version = tag; 383b528cefcSMark Murray storage_set_flags(context, sp, fcache->version); 384b528cefcSMark Murray switch (tag) { 385b528cefcSMark Murray case KRB5_FCC_FVNO_4: { 386b528cefcSMark Murray int16_t length; 387b528cefcSMark Murray 388b528cefcSMark Murray krb5_ret_int16 (sp, &length); 389b528cefcSMark Murray while(length > 0) { 390b528cefcSMark Murray int16_t tag, data_len; 391b528cefcSMark Murray int i; 392b528cefcSMark Murray int8_t dummy; 393b528cefcSMark Murray 394b528cefcSMark Murray krb5_ret_int16 (sp, &tag); 395b528cefcSMark Murray krb5_ret_int16 (sp, &data_len); 396b528cefcSMark Murray switch (tag) { 397b528cefcSMark Murray case FCC_TAG_DELTATIME : 398b528cefcSMark Murray krb5_ret_int32 (sp, &context->kdc_sec_offset); 399b528cefcSMark Murray krb5_ret_int32 (sp, &context->kdc_usec_offset); 400b528cefcSMark Murray break; 401b528cefcSMark Murray default : 402b528cefcSMark Murray for (i = 0; i < data_len; ++i) 403b528cefcSMark Murray krb5_ret_int8 (sp, &dummy); 404b528cefcSMark Murray break; 405b528cefcSMark Murray } 406b528cefcSMark Murray length -= 4 + data_len; 407b528cefcSMark Murray } 408b528cefcSMark Murray break; 409b528cefcSMark Murray } 410b528cefcSMark Murray case KRB5_FCC_FVNO_3: 411b528cefcSMark Murray case KRB5_FCC_FVNO_2: 412b528cefcSMark Murray case KRB5_FCC_FVNO_1: 413b528cefcSMark Murray break; 414b528cefcSMark Murray default : 415b528cefcSMark Murray krb5_storage_free (sp); 416b528cefcSMark Murray close (fd); 417b528cefcSMark Murray return KRB5_CCACHE_BADVNO; 418b528cefcSMark Murray } 419b528cefcSMark Murray *ret_sp = sp; 420b528cefcSMark Murray *ret_fd = fd; 421b528cefcSMark Murray return 0; 422b528cefcSMark Murray } 423b528cefcSMark Murray 424b528cefcSMark Murray static krb5_error_code 425b528cefcSMark Murray fcc_get_principal(krb5_context context, 426b528cefcSMark Murray krb5_ccache id, 427b528cefcSMark Murray krb5_principal *principal) 428b528cefcSMark Murray { 429b528cefcSMark Murray krb5_error_code ret; 430b528cefcSMark Murray krb5_fcache *f = FCACHE(id); 431b528cefcSMark Murray int fd; 432b528cefcSMark Murray krb5_storage *sp; 433b528cefcSMark Murray 434b528cefcSMark Murray ret = init_fcc (context, f, &sp, &fd); 435b528cefcSMark Murray if (ret) 436b528cefcSMark Murray return ret; 4375e9cd1aeSAssar Westerlund ret = krb5_ret_principal(sp, principal); 438b528cefcSMark Murray krb5_storage_free(sp); 439b528cefcSMark Murray close(fd); 4405e9cd1aeSAssar Westerlund return ret; 441b528cefcSMark Murray } 442b528cefcSMark Murray 443b528cefcSMark Murray static krb5_error_code 444b528cefcSMark Murray fcc_get_first (krb5_context context, 445b528cefcSMark Murray krb5_ccache id, 446b528cefcSMark Murray krb5_cc_cursor *cursor) 447b528cefcSMark Murray { 448b528cefcSMark Murray krb5_error_code ret; 449b528cefcSMark Murray krb5_principal principal; 450b528cefcSMark Murray krb5_fcache *f = FCACHE(id); 451b528cefcSMark Murray 452b528cefcSMark Murray *cursor = malloc(sizeof(struct fcc_cursor)); 453b528cefcSMark Murray 454b528cefcSMark Murray ret = init_fcc (context, f, &FCC_CURSOR(*cursor)->sp, 455b528cefcSMark Murray &FCC_CURSOR(*cursor)->fd); 456b528cefcSMark Murray if (ret) 457b528cefcSMark Murray return ret; 458b528cefcSMark Murray krb5_ret_principal (FCC_CURSOR(*cursor)->sp, &principal); 459b528cefcSMark Murray krb5_free_principal (context, principal); 460b528cefcSMark Murray return 0; 461b528cefcSMark Murray } 462b528cefcSMark Murray 463b528cefcSMark Murray static krb5_error_code 464b528cefcSMark Murray fcc_get_next (krb5_context context, 465b528cefcSMark Murray krb5_ccache id, 466b528cefcSMark Murray krb5_cc_cursor *cursor, 467b528cefcSMark Murray krb5_creds *creds) 468b528cefcSMark Murray { 469b528cefcSMark Murray return fcc_read_cred (context, FCACHE(id), FCC_CURSOR(*cursor)->sp, creds); 470b528cefcSMark Murray } 471b528cefcSMark Murray 472b528cefcSMark Murray static krb5_error_code 473b528cefcSMark Murray fcc_end_get (krb5_context context, 474b528cefcSMark Murray krb5_ccache id, 475b528cefcSMark Murray krb5_cc_cursor *cursor) 476b528cefcSMark Murray { 477b528cefcSMark Murray krb5_storage_free(FCC_CURSOR(*cursor)->sp); 478b528cefcSMark Murray close (FCC_CURSOR(*cursor)->fd); 479b528cefcSMark Murray free(*cursor); 480b528cefcSMark Murray return 0; 481b528cefcSMark Murray } 482b528cefcSMark Murray 483b528cefcSMark Murray static krb5_error_code 484b528cefcSMark Murray fcc_remove_cred(krb5_context context, 485b528cefcSMark Murray krb5_ccache id, 486b528cefcSMark Murray krb5_flags which, 487b528cefcSMark Murray krb5_creds *cred) 488b528cefcSMark Murray { 489b528cefcSMark Murray return 0; /* XXX */ 490b528cefcSMark Murray } 491b528cefcSMark Murray 492b528cefcSMark Murray static krb5_error_code 493b528cefcSMark Murray fcc_set_flags(krb5_context context, 494b528cefcSMark Murray krb5_ccache id, 495b528cefcSMark Murray krb5_flags flags) 496b528cefcSMark Murray { 497b528cefcSMark Murray return 0; /* XXX */ 498b528cefcSMark Murray } 499b528cefcSMark Murray 500b528cefcSMark Murray static krb5_error_code 501b528cefcSMark Murray fcc_get_version(krb5_context context, 502b528cefcSMark Murray krb5_ccache id) 503b528cefcSMark Murray { 504b528cefcSMark Murray return FCACHE(id)->version; 505b528cefcSMark Murray } 506b528cefcSMark Murray 507b528cefcSMark Murray const krb5_cc_ops krb5_fcc_ops = { 508b528cefcSMark Murray "FILE", 509b528cefcSMark Murray fcc_get_name, 510b528cefcSMark Murray fcc_resolve, 511b528cefcSMark Murray fcc_gen_new, 512b528cefcSMark Murray fcc_initialize, 513b528cefcSMark Murray fcc_destroy, 514b528cefcSMark Murray fcc_close, 515b528cefcSMark Murray fcc_store_cred, 516b528cefcSMark Murray NULL, /* fcc_retrieve */ 517b528cefcSMark Murray fcc_get_principal, 518b528cefcSMark Murray fcc_get_first, 519b528cefcSMark Murray fcc_get_next, 520b528cefcSMark Murray fcc_end_get, 521b528cefcSMark Murray fcc_remove_cred, 522b528cefcSMark Murray fcc_set_flags, 523b528cefcSMark Murray fcc_get_version 524b528cefcSMark Murray }; 525