From 9b99475b4ca9bce3fe0432c7268650f33378dcc2 Mon Sep 17 00:00:00 2001 From: John Kohl Date: Wed, 3 Apr 1991 09:40:58 +0000 Subject: [PATCH] add locking code git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@1980 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/ccache/file/fcc_maybe.c | 89 ++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/lib/krb5/ccache/file/fcc_maybe.c b/src/lib/krb5/ccache/file/fcc_maybe.c index c3988bd00..b5d0b34b8 100644 --- a/src/lib/krb5/ccache/file/fcc_maybe.c +++ b/src/lib/krb5/ccache/file/fcc_maybe.c @@ -18,6 +18,79 @@ static char rcsid_fcc_maybe_c[] = #include "fcc.h" #include /* XXX ip only? */ +#include +#include +#include + +#ifdef POSIX_FILE_LOCKS +#include +#include +#define SHARED_LOCK F_RDLCK +#define EXCLUSIVE_LOCK F_WRLCK +#define UNLOCK_LOCK F_UNLCK +#else +#include +#define SHARED_LOCK LOCK_SH +#define EXCLUSIVE_LOCK LOCK_EX +#define UNLOCK_LOCK LOCK_UN +#endif + +#define LOCK_IT 0 +#define UNLOCK_IT 1 + +static krb5_error_code fcc_lock_file PROTOTYPE((krb5_fcc_data *, + int, int)); + +static krb5_error_code +fcc_lock_file(data, fd, lockunlock) +krb5_fcc_data *data; +int fd; +int lockunlock; +{ + /* XXX need to in-line lock_file.c here, but it's sort-of OK since + we're already unix-dependent for file descriptors */ + +#ifdef POSIX_FILE_LOCKS + int lock_cmd = F_SETLKW; + struct flock lock_arg; +#define lock_flag lock_arg.l_type + lock_flag = -1; +#else + int lock_flag = -1; +#endif + + if (lockunlock == LOCK_IT) + switch (data->mode) { + case FCC_OPEN_RDONLY: + lock_flag = SHARED_LOCK; + break; + case FCC_OPEN_RDWR: + case FCC_OPEN_AND_ERASE: + lock_flag = EXCLUSIVE_LOCK; + break; + } + else + lock_flag = UNLOCK_LOCK; + + if (lock_flag == -1) + return(KRB5_LIBOS_BADLOCKFLAG); + +#ifdef POSIX_FILE_LOCKS + lock_arg.l_whence = 0; + lock_arg.l_start = 0; + lock_arg.l_len = 0; + if (fcntl(fd, lock_cmd, &lock_arg) == -1) { + if (errno == EACCES || errno == EAGAIN) /* see POSIX/IEEE 1003.1-1988, + 6.5.2.4 */ + return(EAGAIN); + return(errno); + } +#else + if (flock(fd, lock_flag) == -1) + return(errno); +#endif + return 0; +} krb5_error_code krb5_fcc_close_file (id) @@ -25,12 +98,17 @@ krb5_fcc_close_file (id) { int ret; krb5_fcc_data *data = (krb5_fcc_data *)id->data; + krb5_error_code retval; if (data->fd == -1) { abort (); /* XXX? */ } + retval = fcc_lock_file(data, data->fd, UNLOCK_IT); ret = close (data->fd); data->fd = -1; + if (retval) + return retval; + else return (ret == -1) ? krb5_fcc_interpret (errno) : 0; } @@ -43,12 +121,15 @@ krb5_fcc_open_file (id, mode) krb5_int16 fcc_fvno = htons(KRB5_FCC_FVNO); int fd; int open_flag; + krb5_error_code retval; if (data->fd != -1) { /* Don't know what state it's in; shut down and start anew. */ + (void) fcc_lock_file(data, data->fd, UNLOCK_IT); (void) close (data->fd); data->fd = -1; } + data->mode = mode; switch(mode) { case FCC_OPEN_AND_ERASE: open_flag = O_CREAT|O_TRUNC|O_RDWR; @@ -66,6 +147,11 @@ krb5_fcc_open_file (id, mode) if (fd == -1) return krb5_fcc_interpret (errno); + if (retval = fcc_lock_file(data, fd, LOCK_IT)) { + (void) close(fd); + return retval; + } + if (mode == FCC_OPEN_AND_ERASE) { /* write the version number */ int errsave, cnt; @@ -73,6 +159,7 @@ krb5_fcc_open_file (id, mode) if ((cnt = write(fd, (char *)&fcc_fvno, sizeof(fcc_fvno))) != sizeof(fcc_fvno)) { errsave = errno; + (void) fcc_lock_file(data, fd, UNLOCK_IT); (void) close(fd); return (cnt == -1) ? krb5_fcc_interpret(errsave) : KRB5_CC_IO; } @@ -80,10 +167,12 @@ krb5_fcc_open_file (id, mode) /* verify a valid version number is there */ if (read(fd, (char *)&fcc_fvno, sizeof(fcc_fvno)) != sizeof(fcc_fvno)) { + (void) fcc_lock_file(data, fd, UNLOCK_IT); (void) close(fd); return KRB5_CCACHE_BADVNO; } if (fcc_fvno != htons(KRB5_FCC_FVNO)) { + (void) fcc_lock_file(data, fd, UNLOCK_IT); (void) close(fd); return KRB5_CCACHE_BADVNO; } -- 2.26.2