17c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27c478bd9Sstevel@tonic-gate 37c478bd9Sstevel@tonic-gate /* 47c478bd9Sstevel@tonic-gate * lib/krb5/ccache/ccbase.c 57c478bd9Sstevel@tonic-gate * 6505d05c7Sgtb * Copyright 1990,2004 by the Massachusetts Institute of Technology. 77c478bd9Sstevel@tonic-gate * All Rights Reserved. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 107c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 117c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 127c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 13505d05c7Sgtb * 147c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 157c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 167c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 177c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 187c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 197c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 207c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 217c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 227c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 237c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 247c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 257c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 267c478bd9Sstevel@tonic-gate * or implied warranty. 27505d05c7Sgtb * 287c478bd9Sstevel@tonic-gate * 297c478bd9Sstevel@tonic-gate * Registration functions for ccache. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 32*d51f1d33Smp /* 33*d51f1d33Smp * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 34*d51f1d33Smp * Use is subject to license terms. 35*d51f1d33Smp */ 36*d51f1d33Smp 37*d51f1d33Smp 38505d05c7Sgtb #include "k5-int.h" 39505d05c7Sgtb #include "k5-thread.h" 40505d05c7Sgtb 41505d05c7Sgtb #include "fcc.h" 42505d05c7Sgtb #include "cc-int.h" 43505d05c7Sgtb 44505d05c7Sgtb struct krb5_cc_typelist { 45505d05c7Sgtb const krb5_cc_ops *ops; 46505d05c7Sgtb struct krb5_cc_typelist *next; 47505d05c7Sgtb }; 48505d05c7Sgtb extern const krb5_cc_ops krb5_mcc_ops; 497c478bd9Sstevel@tonic-gate 50505d05c7Sgtb #ifdef _WIN32 51505d05c7Sgtb extern const krb5_cc_ops krb5_lcc_ops; 52505d05c7Sgtb static struct krb5_cc_typelist cc_lcc_entry = { &krb5_lcc_ops, NULL }; 53505d05c7Sgtb static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, &cc_lcc_entry }; 54505d05c7Sgtb #else 55505d05c7Sgtb static struct krb5_cc_typelist cc_mcc_entry = { &krb5_mcc_ops, NULL }; 56505d05c7Sgtb #endif 577c478bd9Sstevel@tonic-gate 58505d05c7Sgtb static struct krb5_cc_typelist cc_fcc_entry = { &krb5_cc_file_ops, 59505d05c7Sgtb &cc_mcc_entry }; 60505d05c7Sgtb 61505d05c7Sgtb static struct krb5_cc_typelist *cc_typehead = &cc_fcc_entry; 62505d05c7Sgtb static k5_mutex_t cc_typelist_lock = K5_MUTEX_PARTIAL_INITIALIZER; 63505d05c7Sgtb 64505d05c7Sgtb int 65505d05c7Sgtb krb5int_cc_initialize(void) 66505d05c7Sgtb { 67505d05c7Sgtb int err; 68505d05c7Sgtb 69505d05c7Sgtb err = k5_mutex_finish_init(&krb5int_mcc_mutex); 70505d05c7Sgtb if (err) 71505d05c7Sgtb return err; 72505d05c7Sgtb err = k5_mutex_finish_init(&cc_typelist_lock); 73505d05c7Sgtb if (err) 74505d05c7Sgtb return err; 75505d05c7Sgtb err = k5_mutex_finish_init(&krb5int_cc_file_mutex); 76505d05c7Sgtb if (err) 77505d05c7Sgtb return err; 78505d05c7Sgtb return 0; 79505d05c7Sgtb } 80505d05c7Sgtb 81505d05c7Sgtb void 82505d05c7Sgtb krb5int_cc_finalize(void) 83505d05c7Sgtb { 84505d05c7Sgtb struct krb5_cc_typelist *t, *t_next; 85505d05c7Sgtb k5_mutex_destroy(&cc_typelist_lock); 86505d05c7Sgtb k5_mutex_destroy(&krb5int_cc_file_mutex); 87505d05c7Sgtb k5_mutex_destroy(&krb5int_mcc_mutex); 88505d05c7Sgtb for (t = cc_typehead; t != &cc_fcc_entry; t = t_next) { 89505d05c7Sgtb t_next = t->next; 90505d05c7Sgtb free(t); 91505d05c7Sgtb } 92505d05c7Sgtb } 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * Register a new credentials cache type 977c478bd9Sstevel@tonic-gate * If override is set, replace any existing ccache with that type tag 987c478bd9Sstevel@tonic-gate */ 997c478bd9Sstevel@tonic-gate 100505d05c7Sgtb krb5_error_code KRB5_CALLCONV 101505d05c7Sgtb krb5_cc_register(krb5_context context, krb5_cc_ops *ops, krb5_boolean override) 1027c478bd9Sstevel@tonic-gate { 1037c478bd9Sstevel@tonic-gate struct krb5_cc_typelist *t; 104505d05c7Sgtb krb5_error_code err; 105505d05c7Sgtb 106505d05c7Sgtb err = k5_mutex_lock(&cc_typelist_lock); 107505d05c7Sgtb if (err) 108505d05c7Sgtb return err; 1097c478bd9Sstevel@tonic-gate for (t = cc_typehead;t && strcmp(t->ops->prefix,ops->prefix);t = t->next) 1107c478bd9Sstevel@tonic-gate ; 1117c478bd9Sstevel@tonic-gate if (t) { 1127c478bd9Sstevel@tonic-gate if (override) { 1137c478bd9Sstevel@tonic-gate t->ops = ops; 114505d05c7Sgtb k5_mutex_unlock(&cc_typelist_lock); 1157c478bd9Sstevel@tonic-gate return 0; 116505d05c7Sgtb } else { 117505d05c7Sgtb k5_mutex_unlock(&cc_typelist_lock); 1187c478bd9Sstevel@tonic-gate return KRB5_CC_TYPE_EXISTS; 119505d05c7Sgtb } 1207c478bd9Sstevel@tonic-gate } 121505d05c7Sgtb if (!(t = (struct krb5_cc_typelist *) malloc(sizeof(*t)))) { 122505d05c7Sgtb k5_mutex_unlock(&cc_typelist_lock); 1237c478bd9Sstevel@tonic-gate return ENOMEM; 124505d05c7Sgtb } 1257c478bd9Sstevel@tonic-gate t->next = cc_typehead; 1267c478bd9Sstevel@tonic-gate t->ops = ops; 1277c478bd9Sstevel@tonic-gate cc_typehead = t; 128505d05c7Sgtb k5_mutex_unlock(&cc_typelist_lock); 1297c478bd9Sstevel@tonic-gate return 0; 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Resolve a credential cache name into a cred. cache object. 1347c478bd9Sstevel@tonic-gate * 1357c478bd9Sstevel@tonic-gate * The name is currently constrained to be of the form "type:residual"; 1367c478bd9Sstevel@tonic-gate * 1377c478bd9Sstevel@tonic-gate * The "type" portion corresponds to one of the predefined credential 1387c478bd9Sstevel@tonic-gate * cache types, while the "residual" portion is specific to the 1397c478bd9Sstevel@tonic-gate * particular cache type. 1407c478bd9Sstevel@tonic-gate */ 1417c478bd9Sstevel@tonic-gate 142505d05c7Sgtb #include <ctype.h> 143505d05c7Sgtb krb5_error_code KRB5_CALLCONV 144505d05c7Sgtb krb5_cc_resolve (krb5_context context, const char *name, krb5_ccache *cache) 1457c478bd9Sstevel@tonic-gate { 1467c478bd9Sstevel@tonic-gate struct krb5_cc_typelist *tlist; 1477c478bd9Sstevel@tonic-gate char *pfx, *cp; 148505d05c7Sgtb const char *resid; 149505d05c7Sgtb unsigned int pfxlen; 150505d05c7Sgtb krb5_error_code err; 151505d05c7Sgtb 152*d51f1d33Smp /* Solaris Kerberos */ 153*d51f1d33Smp if (!name) 154*d51f1d33Smp return KRB5_CC_BADNAME; 155*d51f1d33Smp 1567c478bd9Sstevel@tonic-gate cp = strchr (name, ':'); 1577c478bd9Sstevel@tonic-gate if (!cp) { 1587c478bd9Sstevel@tonic-gate if (krb5_cc_dfl_ops) 159505d05c7Sgtb return (*krb5_cc_dfl_ops->resolve)(context, cache, name); 1607c478bd9Sstevel@tonic-gate else 1617c478bd9Sstevel@tonic-gate return KRB5_CC_BADNAME; 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate pfxlen = cp - name; 1657c478bd9Sstevel@tonic-gate 166505d05c7Sgtb if ( pfxlen == 1 && isalpha(name[0]) ) { 167505d05c7Sgtb /* We found a drive letter not a prefix - use FILE: */ 168505d05c7Sgtb pfx = strdup("FILE:"); 169505d05c7Sgtb if (!pfx) 170505d05c7Sgtb return ENOMEM; 171505d05c7Sgtb 172505d05c7Sgtb resid = name; 173505d05c7Sgtb } else { 174505d05c7Sgtb resid = name + pfxlen + 1; 175505d05c7Sgtb 176505d05c7Sgtb pfx = malloc (pfxlen+1); 177505d05c7Sgtb if (!pfx) 178505d05c7Sgtb return ENOMEM; 179505d05c7Sgtb 180505d05c7Sgtb memcpy (pfx, name, pfxlen); 181505d05c7Sgtb pfx[pfxlen] = '\0'; 182505d05c7Sgtb } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate *cache = (krb5_ccache) 0; 1857c478bd9Sstevel@tonic-gate 186505d05c7Sgtb err = k5_mutex_lock(&cc_typelist_lock); 187505d05c7Sgtb if (err) { 188505d05c7Sgtb free(pfx); 189505d05c7Sgtb return err; 190505d05c7Sgtb } 1917c478bd9Sstevel@tonic-gate for (tlist = cc_typehead; tlist; tlist = tlist->next) { 1927c478bd9Sstevel@tonic-gate if (strcmp (tlist->ops->prefix, pfx) == 0) { 193505d05c7Sgtb krb5_error_code (KRB5_CALLCONV *ccresolver)() = tlist->ops->resolve; 194505d05c7Sgtb k5_mutex_unlock(&cc_typelist_lock); 1957c478bd9Sstevel@tonic-gate free(pfx); 196505d05c7Sgtb return (*ccresolver)(context, cache, resid); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate } 199505d05c7Sgtb k5_mutex_unlock(&cc_typelist_lock); 2007c478bd9Sstevel@tonic-gate if (krb5_cc_dfl_ops && !strcmp (pfx, krb5_cc_dfl_ops->prefix)) { 2017c478bd9Sstevel@tonic-gate free (pfx); 2027c478bd9Sstevel@tonic-gate return (*krb5_cc_dfl_ops->resolve)(context, cache, resid); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate free(pfx); 2057c478bd9Sstevel@tonic-gate return KRB5_CC_UNKNOWN_TYPE; 2067c478bd9Sstevel@tonic-gate } 207