⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acache.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2004 - 2007 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  */#include "krb5_locl.h"#include <krb5_ccapi.h>#ifdef HAVE_DLFCN_H#include <dlfcn.h>#endifRCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $");/* XXX should we fetch these for each open ? */static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;static cc_initialize_func init_func;#ifdef HAVE_DLOPENstatic void *cc_handle; #endiftypedef struct krb5_acc {    char *cache_name;    cc_context_t context;    cc_ccache_t ccache;} krb5_acc;static krb5_error_code acc_close(krb5_context, krb5_ccache);#define ACACHE(X) ((krb5_acc *)(X)->data.data)static const struct {    cc_int32 error;    krb5_error_code ret;} cc_errors[] = {    { ccErrBadName,		KRB5_CC_BADNAME },    { ccErrCredentialsNotFound,	KRB5_CC_NOTFOUND },    { ccErrCCacheNotFound,	KRB5_FCC_NOFILE },    { ccErrContextNotFound,	KRB5_CC_NOTFOUND },    { ccIteratorEnd,		KRB5_CC_END },    { ccErrNoMem,		KRB5_CC_NOMEM },    { ccErrServerUnavailable,	KRB5_CC_NOSUPP },    { ccNoError,		0 }};static krb5_error_codetranslate_cc_error(krb5_context context, cc_int32 error){    int i;    krb5_clear_error_string(context);    for(i = 0; i < sizeof(cc_errors)/sizeof(cc_errors[0]); i++)	if (cc_errors[i].error == error)	    return cc_errors[i].ret;    return KRB5_FCC_INTERNAL;}static krb5_error_codeinit_ccapi(krb5_context context){    const char *lib;    HEIMDAL_MUTEX_lock(&acc_mutex);    if (init_func) {	HEIMDAL_MUTEX_unlock(&acc_mutex);	krb5_clear_error_string(context);	return 0;    }    lib = krb5_config_get_string(context, NULL,				 "libdefaults", "ccapi_library", 				 NULL);    if (lib == NULL) {#ifdef __APPLE__	lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos";#else	lib = "/usr/lib/libkrb5_cc.so";#endif    }#ifdef HAVE_DLOPEN#ifndef RTLD_LAZY#define RTLD_LAZY 0#endif    cc_handle = dlopen(lib, RTLD_LAZY);    if (cc_handle == NULL) {	HEIMDAL_MUTEX_unlock(&acc_mutex);	krb5_set_error_string(context, "Failed to load %s", lib);	return KRB5_CC_NOSUPP;    }    init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize");    HEIMDAL_MUTEX_unlock(&acc_mutex);    if (init_func == NULL) {	krb5_set_error_string(context, "Failed to find cc_initialize"			      "in %s: %s", lib, dlerror());	dlclose(cc_handle);	return KRB5_CC_NOSUPP;    }    return 0;#else    HEIMDAL_MUTEX_unlock(&acc_mutex);    krb5_set_error_string(context, "no support for shared object");    return KRB5_CC_NOSUPP;#endif}    static krb5_error_codemake_cred_from_ccred(krb5_context context,		     const cc_credentials_v5_t *incred,		     krb5_creds *cred){    krb5_error_code ret;    int i;    memset(cred, 0, sizeof(*cred));    ret = krb5_parse_name(context, incred->client, &cred->client);    if (ret)	goto fail;    ret = krb5_parse_name(context, incred->server, &cred->server);    if (ret)	goto fail;    cred->session.keytype = incred->keyblock.type;    cred->session.keyvalue.length = incred->keyblock.length;    cred->session.keyvalue.data = malloc(incred->keyblock.length);    if (cred->session.keyvalue.data == NULL)	goto nomem;    memcpy(cred->session.keyvalue.data, incred->keyblock.data,	   incred->keyblock.length);    cred->times.authtime = incred->authtime;    cred->times.starttime = incred->starttime;    cred->times.endtime = incred->endtime;    cred->times.renew_till = incred->renew_till;    ret = krb5_data_copy(&cred->ticket,			 incred->ticket.data,			 incred->ticket.length);    if (ret)	goto nomem;    ret = krb5_data_copy(&cred->second_ticket,			 incred->second_ticket.data,			 incred->second_ticket.length);    if (ret)	goto nomem;    cred->authdata.val = NULL;    cred->authdata.len = 0;        cred->addresses.val = NULL;    cred->addresses.len = 0;        for (i = 0; incred->authdata && incred->authdata[i]; i++)	;        if (i) {	cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0]));	if (cred->authdata.val == NULL)	    goto nomem;	cred->authdata.len = i;	for (i = 0; i < cred->authdata.len; i++) {	    cred->authdata.val[i].ad_type = incred->authdata[i]->type;	    ret = krb5_data_copy(&cred->authdata.val[i].ad_data,				 incred->authdata[i]->data,				 incred->authdata[i]->length);	    if (ret)		goto nomem;	}    }        for (i = 0; incred->addresses && incred->addresses[i]; i++)	;        if (i) {	cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0]));	if (cred->addresses.val == NULL)	    goto nomem;	cred->addresses.len = i;		for (i = 0; i < cred->addresses.len; i++) {	    cred->addresses.val[i].addr_type = incred->addresses[i]->type;	    ret = krb5_data_copy(&cred->addresses.val[i].address,				 incred->addresses[i]->data,				 incred->addresses[i]->length);	    if (ret)		goto nomem;	}    }        cred->flags.i = 0;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDABLE)	cred->flags.b.forwardable = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_FORWARDED)	cred->flags.b.forwarded = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXIABLE)	cred->flags.b.proxiable = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PROXY)	cred->flags.b.proxy = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_MAY_POSTDATE)	cred->flags.b.may_postdate = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_POSTDATED)	cred->flags.b.postdated = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INVALID)	cred->flags.b.invalid = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_RENEWABLE)	cred->flags.b.renewable = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_INITIAL)	cred->flags.b.initial = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_PRE_AUTH)	cred->flags.b.pre_authent = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_HW_AUTH)	cred->flags.b.hw_authent = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED)	cred->flags.b.transited_policy_checked = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE)	cred->flags.b.ok_as_delegate = 1;    if (incred->ticket_flags & KRB5_CCAPI_TKT_FLG_ANONYMOUS)	cred->flags.b.anonymous = 1;    return 0;    nomem:    ret = ENOMEM;    krb5_set_error_string(context, "malloc - out of memory");    fail:    krb5_free_cred_contents(context, cred);    return ret;}static voidfree_ccred(cc_credentials_v5_t *cred){    int i;    if (cred->addresses) {	for (i = 0; cred->addresses[i] != 0; i++) {	    if (cred->addresses[i]->data)		free(cred->addresses[i]->data);	    free(cred->addresses[i]);	}	free(cred->addresses);    }    if (cred->server)	free(cred->server);    if (cred->client)	free(cred->client);    memset(cred, 0, sizeof(*cred));}static krb5_error_codemake_ccred_from_cred(krb5_context context,		     const krb5_creds *incred,		     cc_credentials_v5_t *cred){    krb5_error_code ret;    int i;    memset(cred, 0, sizeof(*cred));    ret = krb5_unparse_name(context, incred->client, &cred->client);    if (ret)	goto fail;    ret = krb5_unparse_name(context, incred->server, &cred->server);    if (ret)	goto fail;    cred->keyblock.type = incred->session.keytype;    cred->keyblock.length = incred->session.keyvalue.length;    cred->keyblock.data = incred->session.keyvalue.data;    cred->authtime = incred->times.authtime;    cred->starttime = incred->times.starttime;    cred->endtime = incred->times.endtime;    cred->renew_till = incred->times.renew_till;    cred->ticket.length = incred->ticket.length;    cred->ticket.data = incred->ticket.data;    cred->second_ticket.length = incred->second_ticket.length;    cred->second_ticket.data = incred->second_ticket.data;    /* XXX this one should also be filled in */    cred->authdata = NULL;        cred->addresses = calloc(incred->addresses.len + 1, 			     sizeof(cred->addresses[0]));    if (cred->addresses == NULL) {	ret = ENOMEM;	goto fail;    }    for (i = 0; i < incred->addresses.len; i++) {	cc_data *addr;	addr = malloc(sizeof(*addr));	if (addr == NULL) {	    ret = ENOMEM;	    goto fail;	}	addr->type = incred->addresses.val[i].addr_type;	addr->length = incred->addresses.val[i].address.length;	addr->data = malloc(addr->length);	if (addr->data == NULL) {	    ret = ENOMEM;	    goto fail;	}	memcpy(addr->data, incred->addresses.val[i].address.data, 	       addr->length);	cred->addresses[i] = addr;    }    cred->addresses[i] = NULL;    cred->ticket_flags = 0;    if (incred->flags.b.forwardable)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDABLE;    if (incred->flags.b.forwarded)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_FORWARDED;    if (incred->flags.b.proxiable)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXIABLE;    if (incred->flags.b.proxy)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PROXY;    if (incred->flags.b.may_postdate)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_MAY_POSTDATE;    if (incred->flags.b.postdated)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_POSTDATED;    if (incred->flags.b.invalid)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INVALID;    if (incred->flags.b.renewable)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_RENEWABLE;    if (incred->flags.b.initial)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_INITIAL;    if (incred->flags.b.pre_authent)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_PRE_AUTH;    if (incred->flags.b.hw_authent)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_HW_AUTH;    if (incred->flags.b.transited_policy_checked)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_TRANSIT_POLICY_CHECKED;    if (incred->flags.b.ok_as_delegate)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_OK_AS_DELEGATE;    if (incred->flags.b.anonymous)	cred->ticket_flags |= KRB5_CCAPI_TKT_FLG_ANONYMOUS;    return 0;fail:        free_ccred(cred);    krb5_clear_error_string(context);    return ret;}static cc_int32get_cc_name(krb5_acc *a){    cc_string_t name;    cc_int32 error;    error = (*a->ccache->func->get_name)(a->ccache, &name);    if (error)	return error;    a->cache_name = strdup(name->data);    (*name->func->release)(name);    if (a->cache_name == NULL)	return ccErrNoMem;    return ccNoError;}static const char*acc_get_name(krb5_context context,	     krb5_ccache id){    krb5_acc *a = ACACHE(id);    int32_t error;    if (a->cache_name == NULL) {	krb5_error_code ret;	krb5_principal principal;	char *name;	ret = _krb5_get_default_principal_local(context, &principal);	if (ret)	    return NULL;	ret = krb5_unparse_name(context, principal, &name);	krb5_free_principal(context, principal);	if (ret)	    return NULL;	error = (*a->context->func->create_new_ccache)(a->context,						       cc_credentials_v5,						       name,						       &a->ccache);	krb5_xfree(name);	if (error)	    return NULL;	error = get_cc_name(a);	if (error)	    return NULL;    }        return a->cache_name;}static krb5_error_codeacc_alloc(krb5_context context, krb5_ccache *id){    krb5_error_code ret;    cc_int32 error;    krb5_acc *a;    ret = init_ccapi(context);    if (ret)	return ret;    ret = krb5_data_alloc(&(*id)->data, sizeof(*a));    if (ret) {	krb5_clear_error_string(context);	return ret;    }        a = ACACHE(*id);    error = (*init_func)(&a->context, ccapi_version_3, NULL, NULL);    if (error) {	krb5_data_free(&(*id)->data);	return translate_cc_error(context, error);    }    a->cache_name = NULL;    return 0;}static krb5_error_codeacc_resolve(krb5_context context, krb5_ccache *id, const char *res){    krb5_error_code ret;    cc_int32 error;    krb5_acc *a;    ret = acc_alloc(context, id);    if (ret)	return ret;    a = ACACHE(*id);    error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);    if (error == ccNoError) {	error = get_cc_name(a);	if (error != ccNoError) {	    acc_close(context, *id);	    *id = NULL;	    return translate_cc_error(context, error);	}    } else if (error == ccErrCCacheNotFound) {	a->ccache = NULL;	a->cache_name = NULL;	error = 0;    } else {	*id = NULL;	return translate_cc_error(context, error);    }    return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -