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

📄 tf_util.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Source: /usr/src/kerberosIV/krb/RCS/tf_util.c,v $ * $Author: bostic $ * * Copyright 1987, 1988 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * <mit-copyright.h>. */#ifndef lintstatic char rcsid_tf_util_c[] ="$Id: tf_util.c,v 4.10 93/05/21 17:45:38 bostic Exp $";#endif /* lint */#include <mit-copyright.h>#include <stdio.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include <des.h>#include <krb.h>#ifdef TKT_SHMEM#include <sys/param.h>#include <sys/ipc.h>#include <sys/shm.h>#endif /* TKT_SHMEM */#define TOO_BIG -1#define TF_LCK_RETRY ((unsigned)2)	/* seconds to sleep before					 * retry if ticket file is					 * locked */extern  errno;extern int krb_debug;#ifdef TKT_SHMEMchar *krb_shm_addr = 0;static char *tmp_shm_addr = 0;static char krb_dummy_skey[8] = {0,0,0,0,0,0,0,0};char *shmat();#endif /* TKT_SHMEM *//* * fd must be initialized to something that won't ever occur as a real * file descriptor. Since open(2) returns only non-negative numbers as * valid file descriptors, and tf_init always stuffs the return value * from open in here even if it is an error flag, we must * 	a. Initialize fd to a negative number, to indicate that it is * 	   not initially valid. *	b. When checking for a valid fd, assume that negative values *	   are invalid (ie. when deciding whether tf_init has been *	   called.) *	c. In tf_close, be sure it gets reinitialized to a negative *	   number.  */static  fd = -1;static	curpos;				/* Position in tfbfr */static	lastpos;			/* End of tfbfr */static	char tfbfr[BUFSIZ];		/* Buffer for ticket data */static tf_gets(), tf_read();/* * This file contains routines for manipulating the ticket cache file. * * The ticket file is in the following format: * *      principal's name        (null-terminated string) *      principal's instance    (null-terminated string) *      CREDENTIAL_1 *      CREDENTIAL_2 *      ... *      CREDENTIAL_n *      EOF * *      Where "CREDENTIAL_x" consists of the following fixed-length *      fields from the CREDENTIALS structure (see "krb.h"): * *              char            service[ANAME_SZ] *              char            instance[INST_SZ] *              char            realm[REALM_SZ] *              C_Block         session *              int             lifetime *              int             kvno *              KTEXT_ST        ticket_st *              long            issue_date * * Short description of routines: * * tf_init() opens the ticket file and locks it. * * tf_get_pname() returns the principal's name. * * tf_get_pinst() returns the principal's instance (may be null). * * tf_get_cred() returns the next CREDENTIALS record. * * tf_save_cred() appends a new CREDENTIAL record to the ticket file. * * tf_close() closes the ticket file and releases the lock. * * tf_gets() returns the next null-terminated string.  It's an internal * routine used by tf_get_pname(), tf_get_pinst(), and tf_get_cred(). * * tf_read() reads a given number of bytes.  It's an internal routine * used by tf_get_cred(). *//* * tf_init() should be called before the other ticket file routines. * It takes the name of the ticket file to use, "tf_name", and a * read/write flag "rw" as arguments.  * * It tries to open the ticket file, checks the mode, and if everything * is okay, locks the file.  If it's opened for reading, the lock is * shared.  If it's opened for writing, the lock is exclusive.  * * Returns KSUCCESS if all went well, otherwise one of the following:  * * NO_TKT_FIL   - file wasn't there * TKT_FIL_ACC  - file was in wrong mode, etc. * TKT_FIL_LCK  - couldn't lock the file, even after a retry */tf_init(tf_name, rw)    char   *tf_name;{    int     wflag;    uid_t   me, getuid();    struct stat stat_buf;#ifdef TKT_SHMEM    char shmidname[MAXPATHLEN];     FILE *sfp;    int shmid;#endif    switch (rw) {    case R_TKT_FIL:	wflag = 0;	break;    case W_TKT_FIL:	wflag = 1;	break;    default:	if (krb_debug) fprintf(stderr, "tf_init: illegal parameter\n");	return TKT_FIL_ACC;    }    if (lstat(tf_name, &stat_buf) < 0)	switch (errno) {	case ENOENT:	    return NO_TKT_FIL;	default:	    return TKT_FIL_ACC;	}    me = getuid();    if ((stat_buf.st_uid != me && me != 0) ||	((stat_buf.st_mode & S_IFMT) != S_IFREG))	return TKT_FIL_ACC;#ifdef TKT_SHMEM    (void) strcpy(shmidname, tf_name);    (void) strcat(shmidname, ".shm");    if (stat(shmidname,&stat_buf) < 0)	return(TKT_FIL_ACC);    if ((stat_buf.st_uid != me && me != 0) ||	((stat_buf.st_mode & S_IFMT) != S_IFREG))	return TKT_FIL_ACC;#endif /* TKT_SHMEM */    /*     * If "wflag" is set, open the ticket file in append-writeonly mode     * and lock the ticket file in exclusive mode.  If unable to lock     * the file, sleep and try again.  If we fail again, return with the     * proper error message.      */    curpos = sizeof(tfbfr);#ifdef TKT_SHMEM    sfp = fopen(shmidname, "r");	/* only need read/write on the					   actual tickets */    if (sfp == 0)    	return TKT_FIL_ACC;    shmid = -1;    {	char buf[BUFSIZ];	int val;			/* useful for debugging fscanf */	/* We provide our own buffer here since some STDIO libraries	   barf on unbuffered input with fscanf() */	setbuf(sfp, buf);	if ((val = fscanf(sfp,"%d",&shmid)) != 1) {	    (void) fclose(sfp);	    return TKT_FIL_ACC;	}	if (shmid < 0) {	    (void) fclose(sfp);	    return TKT_FIL_ACC;	}	(void) fclose(sfp);    }    /*    * global krb_shm_addr is initialized to 0.  Ultrix bombs when you try and    * attach the same segment twice so we need this check.    */    if (!krb_shm_addr) {    	if ((krb_shm_addr = shmat(shmid,0,0)) == -1){		if (krb_debug)		    fprintf(stderr,			    "cannot attach shared memory for segment %d\n",			    shmid);		krb_shm_addr = 0;	/* reset so we catch further errors */		return TKT_FIL_ACC;	    }    }    tmp_shm_addr = krb_shm_addr;#endif /* TKT_SHMEM */        if (wflag) {	fd = open(tf_name, O_RDWR, 0600);	if (fd < 0) {	    return TKT_FIL_ACC;	}	if (flock(fd, LOCK_EX | LOCK_NB) < 0) {	    sleep(TF_LCK_RETRY);	    if (flock(fd, LOCK_EX | LOCK_NB) < 0) {		(void) close(fd);		fd = -1;		return TKT_FIL_LCK;	    }	}	return KSUCCESS;    }    /*     * Otherwise "wflag" is not set and the ticket file should be opened     * for read-only operations and locked for shared access.      */    fd = open(tf_name, O_RDONLY, 0600);    if (fd < 0) {	return TKT_FIL_ACC;    }    if (flock(fd, LOCK_SH | LOCK_NB) < 0) {	sleep(TF_LCK_RETRY);	if (flock(fd, LOCK_SH | LOCK_NB) < 0) {	    (void) close(fd);	    fd = -1;	    return TKT_FIL_LCK;	}    }    return KSUCCESS;}/* * tf_get_pname() reads the principal's name from the ticket file. It * should only be called after tf_init() has been called.  The * principal's name is filled into the "p" parameter.  If all goes well, * KSUCCESS is returned.  If tf_init() wasn't called, TKT_FIL_INI is * returned.  If the name was null, or EOF was encountered, or the name * was longer than ANAME_SZ, TKT_FIL_FMT is returned.  */tf_get_pname(p)    char   *p;{    if (fd < 0) {	if (krb_debug)	    fprintf(stderr, "tf_get_pname called before tf_init.\n");	return TKT_FIL_INI;    }    if (tf_gets(p, ANAME_SZ) < 2)	/* can't be just a null */	return TKT_FIL_FMT;    return KSUCCESS;}/* * tf_get_pinst() reads the principal's instance from a ticket file. * It should only be called after tf_init() and tf_get_pname() have been * called.  The instance is filled into the "inst" parameter.  If all * goes well, KSUCCESS is returned.  If tf_init() wasn't called, * TKT_FIL_INI is returned.  If EOF was encountered, or the instance * was longer than ANAME_SZ, TKT_FIL_FMT is returned.  Note that the * instance may be null.  */tf_get_pinst(inst)

⌨️ 快捷键说明

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