17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * lib/krb5/os/lock_file.c
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * Copyright 1990, 1998 by the Massachusetts Institute of Technology.
57c478bd9Sstevel@tonic-gate  * All Rights Reserved.
67c478bd9Sstevel@tonic-gate  *
77c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
87c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
97c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
107c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
11*55fea89dSDan Cross  *
127c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
137c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
147c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
157c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
167c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
177c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
187c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
197c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
207c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
217c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
227c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
237c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
247c478bd9Sstevel@tonic-gate  * or implied warranty.
25*55fea89dSDan Cross  *
267c478bd9Sstevel@tonic-gate  *
277c478bd9Sstevel@tonic-gate  * libos: krb5_lock_file routine
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate 
30159d09a2SMark Phalan #include "k5-int.h"
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate 
33505d05c7Sgtb #if !defined(_WIN32)
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate /* Unix version...  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #if HAVE_UNISTD_H
387c478bd9Sstevel@tonic-gate #include <unistd.h>
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifdef HAVE_FCNTL_H
447c478bd9Sstevel@tonic-gate #include <fcntl.h>
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #if defined(HAVE_FCNTL_H) && defined(F_SETLKW) && defined(F_RDLCK)
487c478bd9Sstevel@tonic-gate #define POSIX_FILE_LOCKS
497c478bd9Sstevel@tonic-gate #endif
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #ifdef HAVE_FLOCK
527c478bd9Sstevel@tonic-gate #ifndef sysvimp
537c478bd9Sstevel@tonic-gate #include <sys/file.h>
547c478bd9Sstevel@tonic-gate #endif
557c478bd9Sstevel@tonic-gate #else
567c478bd9Sstevel@tonic-gate #ifndef LOCK_SH
577c478bd9Sstevel@tonic-gate #define LOCK_SH 0
587c478bd9Sstevel@tonic-gate #define LOCK_EX 0
597c478bd9Sstevel@tonic-gate #define LOCK_UN 0
607c478bd9Sstevel@tonic-gate #endif
617c478bd9Sstevel@tonic-gate #endif
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate /*ARGSUSED*/
647c478bd9Sstevel@tonic-gate krb5_error_code
krb5_lock_file(krb5_context context,int fd,int mode)65505d05c7Sgtb krb5_lock_file(krb5_context context, int fd, int mode)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate     int 		lock_flag = -1;
687c478bd9Sstevel@tonic-gate     krb5_error_code	retval = 0;
697c478bd9Sstevel@tonic-gate #ifdef POSIX_FILE_LOCKS
707c478bd9Sstevel@tonic-gate     int lock_cmd = F_SETLKW;
71505d05c7Sgtb     struct flock lock_arg = { 0 };
727c478bd9Sstevel@tonic-gate #endif
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate     switch (mode & ~KRB5_LOCKMODE_DONTBLOCK) {
757c478bd9Sstevel@tonic-gate     case KRB5_LOCKMODE_SHARED:
767c478bd9Sstevel@tonic-gate #ifdef POSIX_FILE_LOCKS
777c478bd9Sstevel@tonic-gate 	lock_arg.l_type = F_RDLCK;
787c478bd9Sstevel@tonic-gate #endif
797c478bd9Sstevel@tonic-gate 	lock_flag = LOCK_SH;
807c478bd9Sstevel@tonic-gate 	break;
817c478bd9Sstevel@tonic-gate     case KRB5_LOCKMODE_EXCLUSIVE:
827c478bd9Sstevel@tonic-gate #ifdef POSIX_FILE_LOCKS
837c478bd9Sstevel@tonic-gate 	lock_arg.l_type = F_WRLCK;
847c478bd9Sstevel@tonic-gate #endif
857c478bd9Sstevel@tonic-gate 	lock_flag = LOCK_EX;
867c478bd9Sstevel@tonic-gate 	break;
877c478bd9Sstevel@tonic-gate     case KRB5_LOCKMODE_UNLOCK:
887c478bd9Sstevel@tonic-gate #ifdef POSIX_FILE_LOCKS
897c478bd9Sstevel@tonic-gate 	lock_arg.l_type = F_UNLCK;
907c478bd9Sstevel@tonic-gate #endif
917c478bd9Sstevel@tonic-gate 	lock_flag = LOCK_UN;
927c478bd9Sstevel@tonic-gate 	break;
937c478bd9Sstevel@tonic-gate     }
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate     if (lock_flag == -1)
967c478bd9Sstevel@tonic-gate 	return(KRB5_LIBOS_BADLOCKFLAG);
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate     if (mode & KRB5_LOCKMODE_DONTBLOCK) {
997c478bd9Sstevel@tonic-gate #ifdef POSIX_FILE_LOCKS
1007c478bd9Sstevel@tonic-gate 	lock_cmd = F_SETLK;
1017c478bd9Sstevel@tonic-gate #endif
1027c478bd9Sstevel@tonic-gate #ifdef HAVE_FLOCK
1037c478bd9Sstevel@tonic-gate 	lock_flag |= LOCK_NB;
1047c478bd9Sstevel@tonic-gate #endif
1057c478bd9Sstevel@tonic-gate     }
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate #ifdef POSIX_FILE_LOCKS
1087c478bd9Sstevel@tonic-gate     lock_arg.l_whence = 0;
1097c478bd9Sstevel@tonic-gate     lock_arg.l_start = 0;
1107c478bd9Sstevel@tonic-gate     lock_arg.l_len = 0;
1117c478bd9Sstevel@tonic-gate     if (fcntl(fd, lock_cmd, &lock_arg) == -1) {
1127c478bd9Sstevel@tonic-gate 	if (errno == EACCES || errno == EAGAIN)	/* see POSIX/IEEE 1003.1-1988,
1137c478bd9Sstevel@tonic-gate 						   6.5.2.4 */
1147c478bd9Sstevel@tonic-gate 	    return(EAGAIN);
1157c478bd9Sstevel@tonic-gate 	if (errno != EINVAL)	/* Fall back to flock if we get EINVAL */
1167c478bd9Sstevel@tonic-gate 	    return(errno);
1177c478bd9Sstevel@tonic-gate 	retval = errno;
1187c478bd9Sstevel@tonic-gate     } else
1197c478bd9Sstevel@tonic-gate 	    return 0;		/* We succeeded.  Yay. */
1207c478bd9Sstevel@tonic-gate #endif
121*55fea89dSDan Cross 
1227c478bd9Sstevel@tonic-gate #ifdef HAVE_FLOCK
1237c478bd9Sstevel@tonic-gate     if (flock(fd, lock_flag) == -1)
1247c478bd9Sstevel@tonic-gate 	retval = errno;
1257c478bd9Sstevel@tonic-gate #endif
126*55fea89dSDan Cross 
1277c478bd9Sstevel@tonic-gate     return retval;
1287c478bd9Sstevel@tonic-gate }
129505d05c7Sgtb #else   /* Windows or Macintosh */
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate krb5_error_code
krb5_lock_file(context,fd,mode)1327c478bd9Sstevel@tonic-gate krb5_lock_file(context, fd, mode)
1337c478bd9Sstevel@tonic-gate     krb5_context context;
1347c478bd9Sstevel@tonic-gate     int fd;
1357c478bd9Sstevel@tonic-gate     int mode;
1367c478bd9Sstevel@tonic-gate {
1377c478bd9Sstevel@tonic-gate     return 0;
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate #endif
140