/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
*/
/*
*
* Copyright 1990,1991,2000,2004,2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*
* implementation of memory-based credentials cache
*/
#include "cc-int.h"
#include <errno.h>
static const char * KRB5_CALLCONV krb5_mcc_get_name
krb5_creds *creds );
krb5_creds *mcreds ,
krb5_creds *creds );
(krb5_context, krb5_cc_ptcursor *);
(krb5_context, krb5_cc_ptcursor *);
extern const krb5_cc_ops krb5_mcc_ops;
extern krb5_error_code krb5_change_cache (void);
#define KRB5_OK 0
/* Individual credentials within a cache, in a linked list. */
typedef struct _krb5_mcc_link {
/* Per-cache data header. */
typedef struct _krb5_mcc_data {
char *name;
/* List of memory caches. */
typedef struct krb5_mcc_list_node {
/* Iterator over memory caches. */
struct krb5_mcc_ptcursor_data {
};
static void update_mcc_change_time(krb5_mcc_data *);
/*
* Modifies:
* id
*
* Effects:
* contents are destroyed.
*
* Errors:
* system errors
*/
{
krb5_mcc_data *d;
if (ret)
return ret;
&d->prin);
return ret;
}
/*
* Modifies:
* id
*
* Effects:
* Invalidates the id, and frees any resources associated with accessing
* the cache.
*/
{
return KRB5_OK;
}
static void
{
krb5_mcc_data *d;
}
}
/*
* Effects:
* Destroys the contents of id. id is invalid after call.
*
* Errors:
* system errors (locks related)
*/
{
krb5_mcc_data *d;
if (err)
return err;
break;
}
}
if (err)
return err;
k5_cc_mutex_destroy(&d->lock);
free(d);
return KRB5_OK;
}
/*
* Requires:
* residual is a legal path name, and a null-terminated string
*
* Modifies:
* id
*
* Effects:
* creates or accesses a memory-based cred cache that is referenced by
* residual.
*
* Returns:
* A filled in krb5_ccache structure "id".
*
* Errors:
* KRB5_CC_NOMEM - there was insufficient memory to allocate the
* krb5_ccache. id is undefined.
* system errors (mutex locks related)
*/
{
krb5_mcc_data *d;
if (err)
return err;
break;
if (ptr)
else {
if (err) {
return err;
}
}
return KRB5_CC_NOMEM;
return KRB5_OK;
}
/*
* Effects:
* Prepares for a sequential search of the credentials cache.
* Returns a krb5_cc_cursor to be used with krb5_mcc_next_cred and
* krb5_mcc_end_seq_get.
*
* If the cache is modified between the time of this call and the time
* of the final krb5_mcc_end_seq_get, the results are undefined.
*
* Errors:
* KRB5_CC_NOMEM
* system errors
*/
{
krb5_mcc_data *d;
if (err)
return err;
return KRB5_OK;
}
/*
* Requires:
* cursor is a krb5_cc_cursor originally obtained from
* krb5_mcc_start_seq_get.
*
* Modifes:
* cursor, creds
*
* Effects:
* Fills in creds with the "next" credentals structure from the cache
* id. The actual order the creds are returned in is arbitrary.
* Space is allocated for the variable length fields in the
* credentials structure, so the object returned must be passed to
* krb5_destroy_credential.
*
* The cursor is updated for the next call to krb5_mcc_next_cred.
*
* Errors:
* system errors
*/
{
/* Once the node in the linked list is created, it's never
modified, so we don't need to worry about locking here. (Note
that we don't support _remove_cred.) */
return KRB5_CC_END;
if (retval)
return retval;
}
return KRB5_OK;
}
/*
* Requires:
* cursor is a krb5_cc_cursor originally obtained from
* krb5_mcc_start_seq_get.
*
* Modifies:
* id, cursor
*
* Effects:
* Finishes sequential processing of the memory credentials ccache id,
* and invalidates the cursor (it must never be used after this call).
*/
/* ARGSUSED */
{
*cursor = 0L;
return KRB5_OK;
}
/* Utility routine: Creates the back-end data for a memory cache, and
threads it into the global linked list.
Call with the global list lock held. */
static krb5_error_code
{
krb5_mcc_data *d;
d = malloc(sizeof(krb5_mcc_data));
if (d == NULL)
return KRB5_CC_NOMEM;
if (err) {
free(d);
return err;
}
k5_cc_mutex_destroy(&d->lock);
free(d);
return KRB5_CC_NOMEM;
}
d->changetime = 0;
n = malloc(sizeof(krb5_mcc_list_node));
if (n == NULL) {
k5_cc_mutex_destroy(&d->lock);
free(d);
return KRB5_CC_NOMEM;
}
n->cache = d;
mcc_head = n;
*dataptr = d;
return 0;
}
/*
* Effects:
* Creates a new memory cred cache whose name is guaranteed to be
* unique. The name begins with the string TKT_ROOT (from mcc.h).
*
* Returns:
* The filled in krb5_ccache id.
*
* Errors:
* KRB5_CC_NOMEM - there was insufficient memory to allocate the
* krb5_ccache. id is undefined.
* system errors (from open, mutex locking)
*/
{
krb5_mcc_data *d;
/* Allocate memory */
return KRB5_CC_NOMEM;
if (err) {
return err;
}
/* Check for uniqueness with mutex locked to avoid race conditions */
while (1) {
if (err) {
return err;
}
break; /* got a match, loop again */
}
}
if (!ptr) break; /* got to the end without finding a match */
}
if (err) {
return err;
}
return KRB5_OK;
}
/* Utility routine: Creates a random memory ccache name.
* This algorithm was selected because it creates readable
* random ccache names in a fixed size buffer. */
{
static const unsigned char charlist[] =
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (!err) {
}
if (!err) {
}
if (!err) {
unsigned int i;
for (i = 0; i < bytecount; i++) {
}
}
return err;
}
/*
* Requires:
* id is a file credential cache
*
* Returns:
* A pointer to the name of the file cred cache id.
*/
const char * KRB5_CALLCONV
{
}
/*
* Modifies:
* id, princ
*
* Effects:
* Retrieves the primary principal from id, as set with
* krb5_mcc_initialize. The principal is returned is allocated
* storage that must be freed by the caller via krb5_free_principal.
*
* Errors:
* system errors
* ENOMEM
*/
{
*princ = 0L;
return KRB5_FCC_NOFILE;
}
}
{
}
/*
* Non-functional stub implementation for krb5_mcc_remove
*
* Errors:
* KRB5_CC_NOSUPP - not implemented
*/
static krb5_error_code KRB5_CALLCONV
{
return KRB5_CC_NOSUPP;
}
/*
* Requires:
* id is a cred cache returned by krb5_mcc_resolve or
* krb5_mcc_generate_new.
*
* Modifies:
* id
*
* Effects:
* Sets the operational flags of id to flags.
*/
{
return KRB5_OK;
}
static krb5_error_code KRB5_CALLCONV
{
*flags = 0;
return KRB5_OK;
}
/*
* Modifies:
* the memory cache
*
* Effects:
* Save away creds in the ccache.
*
* Errors:
* system errors (mutex locking)
* ENOMEM
*/
{
return ENOMEM;
if (err)
goto cleanup;
if (err) {
/* Solaris Kerberos - fix mem leaks */
goto cleanup;
}
return 0;
return err;
}
static krb5_error_code KRB5_CALLCONV
{
krb5_cc_ptcursor n = NULL;
n = malloc(sizeof(*n));
if (n == NULL)
return ENOMEM;
n->ops = &krb5_mcc_ops;
goto errout;
}
if (ret)
goto errout;
if (ret)
goto errout;
if (ret) {
}
*cursor = n;
return ret;
}
static krb5_error_code KRB5_CALLCONV
{
return 0;
return ENOMEM;
if (ret)
goto errout;
if (ret)
goto errout;
}
return ret;
}
static krb5_error_code KRB5_CALLCONV
{
return 0;
return 0;
}
static krb5_error_code KRB5_CALLCONV
{
*change_time = 0;
if (!ret) {
}
return ret;
}
/*
Utility routine: called by krb5_mcc_* functions to keep
result of krb5_mcc_last_change_time up to date
*/
static void
{
}
static krb5_error_code KRB5_CALLCONV
{
return ret;
}
static krb5_error_code KRB5_CALLCONV
{
return ret;
}
0,
"MEMORY",
NULL, /* move */
NULL, /* wasdefault */
};