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

📄 fcache.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1997 - 2008 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"RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $");typedef struct krb5_fcache{    char *filename;    int version;}krb5_fcache;struct fcc_cursor {    int fd;    krb5_storage *sp;};#define KRB5_FCC_FVNO_1 1#define KRB5_FCC_FVNO_2 2#define KRB5_FCC_FVNO_3 3#define KRB5_FCC_FVNO_4 4#define FCC_TAG_DELTATIME 1#define FCACHE(X) ((krb5_fcache*)(X)->data.data)#define FILENAME(X) (FCACHE(X)->filename)#define FCC_CURSOR(C) ((struct fcc_cursor*)(C))static const char*fcc_get_name(krb5_context context,	     krb5_ccache id){    return FILENAME(id);}int_krb5_xlock(krb5_context context, int fd, krb5_boolean exclusive,	    const char *filename){    int ret;#ifdef HAVE_FCNTL    struct flock l;    l.l_start = 0;    l.l_len = 0;    l.l_type = exclusive ? F_WRLCK : F_RDLCK;    l.l_whence = SEEK_SET;    ret = fcntl(fd, F_SETLKW, &l);#else    ret = flock(fd, exclusive ? LOCK_EX : LOCK_SH);#endif    if(ret < 0)	ret = errno;    if(ret == EACCES) /* fcntl can return EACCES instead of EAGAIN */	ret = EAGAIN;    switch (ret) {    case 0:	break;    case EINVAL: /* filesystem doesn't support locking, let the user have it */	ret = 0; 	break;    case EAGAIN:	krb5_set_error_string(context, "timed out locking cache file %s", 			      filename);	break;    default:	krb5_set_error_string(context, "error locking cache file %s: %s",			      filename, strerror(ret));	break;    }    return ret;}int_krb5_xunlock(krb5_context context, int fd){    int ret;#ifdef HAVE_FCNTL    struct flock l;    l.l_start = 0;    l.l_len = 0;    l.l_type = F_UNLCK;    l.l_whence = SEEK_SET;    ret = fcntl(fd, F_SETLKW, &l);#else    ret = flock(fd, LOCK_UN);#endif    if (ret < 0)	ret = errno;    switch (ret) {    case 0:	break;    case EINVAL: /* filesystem doesn't support locking, let the user have it */	ret = 0; 	break;    default:	krb5_set_error_string(context, 			      "Failed to unlock file: %s", strerror(ret));	break;    }    return ret;}static krb5_error_codefcc_lock(krb5_context context, krb5_ccache id,	 int fd, krb5_boolean exclusive){    return _krb5_xlock(context, fd, exclusive, fcc_get_name(context, id));}static krb5_error_codefcc_unlock(krb5_context context, int fd){    return _krb5_xunlock(context, fd);}static krb5_error_codefcc_resolve(krb5_context context, krb5_ccache *id, const char *res){    krb5_fcache *f;    f = malloc(sizeof(*f));    if(f == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return KRB5_CC_NOMEM;    }    f->filename = strdup(res);    if(f->filename == NULL){	free(f);	krb5_set_error_string(context, "malloc: out of memory");	return KRB5_CC_NOMEM;    }    f->version = 0;    (*id)->data.data = f;    (*id)->data.length = sizeof(*f);    return 0;}/* * Try to scrub the contents of `filename' safely. */static intscrub_file (int fd){    off_t pos;    char buf[128];    pos = lseek(fd, 0, SEEK_END);    if (pos < 0)        return errno;    if (lseek(fd, 0, SEEK_SET) < 0)        return errno;    memset(buf, 0, sizeof(buf));    while(pos > 0) {        ssize_t tmp = write(fd, buf, min(sizeof(buf), pos));	if (tmp < 0)	    return errno;	pos -= tmp;    }    fsync (fd);    return 0;}/* * Erase `filename' if it exists, trying to remove the contents if * it's `safe'.  We always try to remove the file, it it exists.  It's * only overwritten if it's a regular file (not a symlink and not a * hardlink) */static krb5_error_codeerase_file(const char *filename){    int fd;    struct stat sb1, sb2;    int ret;    ret = lstat (filename, &sb1);    if (ret < 0)	return errno;    fd = open(filename, O_RDWR | O_BINARY);    if(fd < 0) {	if(errno == ENOENT)	    return 0;	else	    return errno;    }    if (unlink(filename) < 0) {        close (fd);        return errno;    }    ret = fstat (fd, &sb2);    if (ret < 0) {	close (fd);	return errno;    }    /* check if someone was playing with symlinks */    if (sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) {	close (fd);	return EPERM;    }    /* there are still hard links to this file */    if (sb2.st_nlink != 0) {        close (fd);        return 0;    }    ret = scrub_file (fd);    close (fd);    return ret;}static krb5_error_codefcc_gen_new(krb5_context context, krb5_ccache *id){    krb5_fcache *f;    int fd;    char *file;    f = malloc(sizeof(*f));    if(f == NULL) {	krb5_set_error_string(context, "malloc: out of memory");	return KRB5_CC_NOMEM;    }    asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT);    if(file == NULL) {	free(f);	krb5_set_error_string(context, "malloc: out of memory");	return KRB5_CC_NOMEM;    }    fd = mkstemp(file);    if(fd < 0) {	int ret = errno;	krb5_set_error_string(context, "mkstemp %s", file);	free(f);	free(file);	return ret;    }    close(fd);    f->filename = file;    f->version = 0;    (*id)->data.data = f;    (*id)->data.length = sizeof(*f);    return 0;}static voidstorage_set_flags(krb5_context context, krb5_storage *sp, int vno){    int flags = 0;    switch(vno) {    case KRB5_FCC_FVNO_1:	flags |= KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS;	flags |= KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE;	flags |= KRB5_STORAGE_HOST_BYTEORDER;	break;    case KRB5_FCC_FVNO_2:	flags |= KRB5_STORAGE_HOST_BYTEORDER;	break;    case KRB5_FCC_FVNO_3:	flags |= KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE;	break;    case KRB5_FCC_FVNO_4:	break;    default:	krb5_abortx(context, 		    "storage_set_flags called with bad vno (%x)", vno);    }    krb5_storage_set_flags(sp, flags);}static krb5_error_codefcc_open(krb5_context context,	 krb5_ccache id,	 int *fd_ret,	 int flags,	 mode_t mode){    krb5_boolean exclusive = ((flags | O_WRONLY) == flags ||			      (flags | O_RDWR) == flags);    krb5_error_code ret;    const char *filename = FILENAME(id);    int fd;    fd = open(filename, flags, mode);    if(fd < 0) {	ret = errno;	krb5_set_error_string(context, "open(%s): %s", filename,			      strerror(ret));	return ret;    }	    if((ret = fcc_lock(context, id, fd, exclusive)) != 0) {	close(fd);	return ret;    }    *fd_ret = fd;    return 0;}static krb5_error_codefcc_initialize(krb5_context context,	       krb5_ccache id,	       krb5_principal primary_principal){    krb5_fcache *f = FCACHE(id);    int ret = 0;    int fd;    char *filename = f->filename;    unlink (filename);      ret = fcc_open(context, id, &fd, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);    if(ret)	return ret;    {	krb5_storage *sp;    	sp = krb5_storage_from_fd(fd);	krb5_storage_set_eof_code(sp, KRB5_CC_END);	if(context->fcache_vno != 0)	    f->version = context->fcache_vno;	else	    f->version = KRB5_FCC_FVNO_4;	ret |= krb5_store_int8(sp, 5);	ret |= krb5_store_int8(sp, f->version);	storage_set_flags(context, sp, f->version);	if(f->version == KRB5_FCC_FVNO_4 && ret == 0) {	    /* V4 stuff */	    if (context->kdc_sec_offset) {		ret |= krb5_store_int16 (sp, 12); /* length */		ret |= krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */		ret |= krb5_store_int16 (sp, 8); /* length of data */		ret |= krb5_store_int32 (sp, context->kdc_sec_offset);		ret |= krb5_store_int32 (sp, context->kdc_usec_offset);	    } else {		ret |= krb5_store_int16 (sp, 0);	    }	}	ret |= krb5_store_principal(sp, primary_principal);		krb5_storage_free(sp);    }    fcc_unlock(context, fd);    if (close(fd) < 0)	if (ret == 0) {	    ret = errno;	    krb5_set_error_string (context, "close %s: %s", 				   FILENAME(id), strerror(ret));	}    return ret;}static krb5_error_codefcc_close(krb5_context context,	  krb5_ccache id){    free (FILENAME(id));    krb5_data_free(&id->data);    return 0;}static krb5_error_codefcc_destroy(krb5_context context,	    krb5_ccache id){    erase_file(FILENAME(id));    return 0;}static krb5_error_codefcc_store_cred(krb5_context context,	       krb5_ccache id,	       krb5_creds *creds){    int ret;    int fd;    ret = fcc_open(context, id, &fd, O_WRONLY | O_APPEND | O_BINARY, 0);    if(ret)	return ret;    {	krb5_storage *sp;	sp = krb5_storage_from_fd(fd);	krb5_storage_set_eof_code(sp, KRB5_CC_END);	storage_set_flags(context, sp, FCACHE(id)->version);	if (!krb5_config_get_bool_default(context, NULL, TRUE,					  "libdefaults",					  "fcc-mit-ticketflags",					  NULL))	    krb5_storage_set_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER);	ret = krb5_store_creds(sp, creds);	krb5_storage_free(sp);    }    fcc_unlock(context, fd);    if (close(fd) < 0)	if (ret == 0) {	    ret = errno;	    krb5_set_error_string (context, "close %s: %s", 				   FILENAME(id), strerror(ret));	}    return ret;}

⌨️ 快捷键说明

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