2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2N/A * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * Copyright 1990,1991,1992,1993,1994,2000,2004,2007 Massachusetts Institute of Technology. 2N/A * All Rights Reserved. 2N/A * Original stdio support copyright 1995 by Cygnus Support. 2N/A * Export of this software from the United States of America may 2N/A * require a specific license from the United States Government. 2N/A * It is the responsibility of any person or organization contemplating 2N/A * export to obtain such a license before exporting. 2N/A * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 2N/A * distribute this software and its documentation for any purpose and 2N/A * without fee is hereby granted, provided that the above copyright 2N/A * notice appear in all copies and that both that copyright notice and 2N/A * this permission notice appear in supporting documentation, and that 2N/A * the name of M.I.T. not be used in advertising or publicity pertaining 2N/A * to distribution of the software without specific, written prior 2N/A * permission. Furthermore if you modify this software you must label 2N/A * your software as modified software and not distribute it in such a 2N/A * fashion that it might be confused with the original M.I.T. software. 2N/A * M.I.T. makes no representations about the suitability of 2N/A * this software for any purpose. It is provided "as is" without express 2N/A * or implied warranty. 2N/A * implementation of file-based credentials cache 2N/A If OPENCLOSE is defined, each of the functions opens and closes the 2N/A file whenever it needs to access it. Otherwise, the file is opened 2N/A once in initialize and closed once is close. 2N/A This library depends on UNIX-like file descriptors, and UNIX-like 2N/A behavior from the functions: open, close, read, write, lseek. 2N/A The quasi-BNF grammar for a credentials cache: 2N/A principal list-of-credentials 2N/A times (ticket_times) 2N/A ticket_flags (flags) 2N/A second_ticket (data) 2N/A number of components (int32) 2N/A string of length bytes 2N/A Make sure that each time a function returns KRB5_NOMEM, everything 2N/A allocated earlier in the function and stack tree is freed. 2N/A/* Solaris Kerberos */ 2N/A/* How long to block if flock fails with EAGAIN */ 2N/A * FCC version 2 contains type information for principals. FCC 2N/A * version 1 does not. 2N/A * FCC version 3 contains keyblock encryption type information, and is 2N/A * architecture independent. Previous versions are not. 2N/A * The code will accept version 1, 2, and 3 ccaches, and depending 2N/A * what KRB5_FCC_DEFAULT_FVNO is set to, it will create version 1, 2, 2N/A * The default credentials cache should be type 3 for now (see 2N/A/* Credential file header tags. 2N/A * The header tags are constructed as: 2N/A * krb5_octet data[len] 2N/A * This format allows for older versions of the fcc processing code to skip 2N/A * past unrecognized tag formats. 2N/A/* macros to make checking flags easier */ 2N/A /* Lock this one before reading or modifying the data stored here 2N/A that can be changed. (Filename is fixed after 2N/A int mode;
/* needed for locking code */ 2N/A /* Buffer data on reading, for performance. 2N/A We used to have a stdio option, but we get more precise control 2N/A by using the POSIX I/O functions. */ 2N/A /* If we read some extra data in advance, and then want to know or 2N/A use our "current" position, we need to back up a little. */ 2N/A/* Iterator over file caches. */ 2N/A/* An off_t can be arbitrarily complex */ 2N/A * Reads len bytes from the cache id, storing them in buf. 2N/A * Must be called with mutex locked. 2N/A * KRB5_CC_END - there were not len bytes available 2N/A * system errors (read) 2N/A /* Fill buffer from current file position. */ 2N/A /* Don't do arithmetic on void pointers. */ 2N/A * FOR ALL OF THE FOLLOWING FUNCTIONS: 2N/A * id is open and set to read at the appropriate place in the file 2N/A * Fills in the second argument with data of the appropriate type from 2N/A * the file. In some cases, the functions have to allocate space for 2N/A * variable length fields; therefore, krb5_destroy_<type> must be 2N/A * called for each filled in structure. 2N/A * system errors (read errors) 2N/A /* Read principal type */ 2N/A /* Read the number of components */ 2N/A * DCE includes the principal's realm in the count; the new format 2N/A /* Read the number of components */ 2N/A /* Make *addrs able to hold length pointers to krb5_address structs 2N/A * Add one extra for a null-terminated list 2N/A /* This works because the old etype is the same as the new enctype. */ 2N/A /* keyblock->enctype = ui2; */ 2N/A /* Overflow check. */ 2N/A /* Solaris Kerberos */ 2N/A /* Length field is "unsigned int", which may be smaller than 32 2N/A /* Read the number of components */ 2N/A /* Make *a able to hold length pointers to krb5_authdata structs 2N/A * Add one extra for a null-terminated list 2N/A /* Value could have gotten truncated if int is smaller than 32 2N/A * Writes len bytes from buf into the file cred cache id. 2N/A * FOR ALL OF THE FOLLOWING FUNCTIONS: 2N/A * ((krb5_fcc_data *) id->data)->file is open and at the right position. 2N/A * Stores an encoded version of the second argument in the 2N/A * DCE-compatible format means that the length count 2N/A * includes the realm. (It also doesn't include the 2N/A * principal type information.) 2N/A /* Count the number of components */ 2N/A/* Solaris Kerberos */ 2N/A * If we are opening in NOUNLINK mode, we have to check that the 2N/A * existing file, if any, is not a symlink. If it is, we try to 2N/A * delete and re-create it. 2N/A /* If the file got created after the open we must retry */ 2N/A * We failed since the file existed with wrong permissions. 2N/A * Let's try to unlink it and if that succeeds retry. 2N/A /* If we still don't have a valid fd, we stop trying */ 2N/A * If the file was not created now with a O_CREAT | O_EXCL open, 2N/A * we have opened an existing file. We should check if the file 2N/A * owner is us, if not, unlink and retry. If unlink fails we log 2N/A * the error and return. 2N/A /* Check if this is the same file we lstat'd earlier */ 2N/A * Check if the cc filename uid matches owner of file. 2N/A * else skip this check. 2N/A /* make sure we have some non-null char after '_' */ 2N/A /* make sure the uid part is all digits */ 2N/A /* Don't know what state it's in; shut down and start anew. */ 2N/A /* Solaris Kerberos */ 2N/A * If we are opening in NOUNLINK mode, check whether we are opening a 2N/A * symlink or a file owned by some other user and take preventive action. 2N/A /* Solaris Kerberos wait some time before retrying */ 2N/A /* write the version number */ 2N/A * If this file was not created, we have to flush existing data. 2N/A * This will happen only if we are doing an ERASE_NOUNLINK open. 2N/A /* V4 of the credentials cache format allows for header tags */ 2N/A /* Write header length */ 2N/A /* Write time offset tag */ 2N/A /* verify a valid version number is there */ 2N/A * contents are destroyed. 2N/A * This is not needed and can cause problems with ktkt_warnd(1M) 2N/A * because it does tricks with getuid and if we enable this fchmod 2N/A * we get EPERM [file_owner] failures on fchmod. 2N/A * Drop the ref count; if it hits zero, remove the entry from the 2N/A * fcc_set list and free it. 2N/A * Closes the file cache, invalidates the id, and frees any resources 2N/A * associated with the cache. 2N/A * Destroys the contents of id. 2N/A/* "disgusting bit of UNIX trivia" - that's how the writers of NFS describe 2N/A** the ability of UNIX to still write to a file which has been unlinked. 2N/A** Naturally, the PC can't do this. As a result, we have to delete the file 2N/A** after we wipe it clean but that throws off all the error handling code. 2N/A** So we have do the work ourselves. 2N/A size = 0;
/* Nothing to wipe clean */ 2N/A /* Don't jump to cleanup--we still want to delete the file. */ 2N/A size -= i;
/* We've read this much */ 2N/A#
else /* MSDOS_FILESYSTEM */ 2N/A /* XXX This may not be legal XXX */ 2N/A#
endif /* MSDOS_FILESYSTEM */ 2N/A * residual is a legal path name, and a null-terminated string 2N/A * creates a file-based cred cache that will reside in the file 2N/A * residual. The cache is not opened, but the filename is reserved. 2N/A * A filled in krb5_ccache structure "id". 2N/A * KRB5_CC_NOMEM - there was insufficient memory to allocate the 2N/A * krb5_ccache. id is undefined. 2N/A /* data->version,mode filled in for real later */ 2N/A /* other routines will get errors on open, and callers must expect them, 2N/A * Prepares for a sequential search of the credentials cache. 2N/A * Returns and krb5_cc_cursor to be used with krb5_fcc_next_cred and 2N/A * krb5_fcc_end_seq_get. 2N/A * If the cache is modified between the time of this call and the time 2N/A * of the final krb5_fcc_end_seq_get, the results are undefined. 2N/A /* Make sure we start reading right after the primary principal */ 2N/A * cursor is a krb5_cc_cursor originally obtained from 2N/A * krb5_fcc_start_seq_get. 2N/A * Fills in creds with the "next" credentals structure from the cache 2N/A * id. The actual order the creds are returned in is arbitrary. 2N/A * Space is allocated for the variable length fields in the 2N/A * credentials structure, so the object returned must be passed to 2N/A * krb5_destroy_credential. 2N/A * The cursor is updated for the next call to krb5_fcc_next_cred. 2N/A * cursor is a krb5_cc_cursor originally obtained from 2N/A * krb5_fcc_start_seq_get. 2N/A * Finishes sequential processing of the file credentials ccache id, 2N/A * and invalidates the cursor (it must never be used after this call). 2N/A /* We don't do anything with the file cache itself, so 2N/A no need to lock anything. */ 2N/A /* don't close; it may be left open by the caller, 2N/A and if not, fcc_start_seq_get and/or fcc_next_cred will do the 2N/A MAYBE_CLOSE(context, id, kret); */ 2N/A * Creates a new file cred cache whose name is guaranteed to be 2N/A * unique. The name begins with the string TKT_ROOT (from fcc.h). 2N/A * The cache is not opened, but the new filename is reserved. 2N/A * The filled in krb5_ccache id. 2N/A * KRB5_CC_NOMEM - there was insufficient memory to allocate the 2N/A * krb5_ccache. id is undefined. 2N/A * system errors (from open) 2N/A /* Set master lock */ 2N/A /* Allocate memory */ 2N/A * The file is initially closed at the end of this call... 2N/A /* data->version,mode filled in for real later */ 2N/A /* Ignore user's umask, set mode = 0600 */ 2N/A /* For version 4 we save a length for the rest of the header */ 2N/A will get as to state confused */ 2N/A * id is a file credential cache 2N/A * The name of the file cred cache id. 2N/A * Retrieves the primary principal from id, as set with 2N/A * krb5_fcc_initialize. The principal is returned is allocated 2N/A * storage that must be freed by the caller via krb5_free_principal. 2N/A /* make sure we're beyond the header */ 2N/A * stores creds in the file cred cache 2N/A * storage failure errors 2N/A /* Make sure we are writing to the end of the file */ 2N/A /* Make sure we are writing to the end of the file */ 2N/A * Non-functional stub implementation for krb5_fcc_remove 2N/A * KRB5_CC_NOSUPP - not implemented 2N/A * id is a cred cache returned by krb5_fcc_resolve or 2N/A * krb5_fcc_generate_new, but has not been opened by krb5_fcc_initialize. 2N/A * Sets the operational flags of id to flags. 2N/A /* XXX This should check for illegal combinations, if any.. */ 2N/A /* asking to turn on OPENCLOSE mode */ 2N/A /* XXX Is this test necessary? */ 2N/A /* asking to turn off OPENCLOSE mode, meaning it must be 2N/A left open. We open if it's not yet open */ 2N/A * id is a cred cache returned by krb5_fcc_resolve or 2N/A * krb5_fcc_generate_new, but has not been opened by krb5_fcc_initialize. 2N/A * id (mutex only; temporary) 2N/A * Returns the operational flags of id. 2N/A * Returns the timestamp of id's file modification date. 2N/A * If an error occurs, change_time is set to 0. 2N/A case ELOOP:
/* Bad symlink is like no file. */ 2N/A "Credentials cache I/O operation failed (%s)"),
2N/A * krb5_change_cache should be called after the cache changes. 2N/A * A notification message is is posted out to all top level 2N/A * windows so that they may recheck the cache based on the 2N/A * changes made. We register a unique message type with which 2N/A * we'll communicate to all other processes.