Lock Files and setuid Access in Fortran

Note: For security reasons, the setuid bit is no longer effective for programs stored in your home directory on strauss (as of April 1998). The file locking example still works.

Question: I am writing a data base access program in Fortran and I want every user in our group to be able to read and modify the file, but ONLY when they are running my program. Also it is important that only one user at a time has the file open for modification. How should I set things in unix so both of the following are true?

  1. When running my program any member of our group can read and modify the information in the data base, but without using my program they can not modify or even read the data base file.
  2. Access should be allowed to only one user at a time for modifying the file.
Answer: These are two separate goals which are solved by entirly different means. The first is an access problem and is solved in Unix by using the change mode command chmod and the change group command chgrp. The folowing example uses a Fortran program, but the same idea will apply to any executable. The second goal is called file locking, and can be acheived in Fortran without and explicit use of Unix,i.e., just using standard Fortran I/O statements.
  1. If you set the access on your data file so only you can read and write the file, and then set the "setuid" bit on your executable then your program can get to the data even while the user can't get to the data without using any other means.
  2. This is called "locking the file". One simple way to do this is to create a separate file called a "lock file" which is present only when the data file is being used. This can be done in Fortran with just the open and close statements.

Example of a program to read the file

Here is a simple Fortran program which will read a direct access data base and print the values (upto 100 records).

logread.f

character*10 value character*40 filename/'/home/strauss/usrc/49/18795/log'/ open(10,file=filename,recl=16,access='direct',form='formatted') do 19 i=1,100 read(10,err=19,end=99,rec=i,fmt='(i5,x,a10)') irec,value write(*,fmt='(i5,x,a10)') irec, value 19 continue 99 close(10) Here are the unix commands to compile and install the program so the the program can be run as you by anybody in group 0329. f77 -o logread logread.f chgrp 0329 logread chmod 4710 logread chmod 600 /home/strauss/usrc/49/18795/log mv logread ~/bin Explanation:
f77 -o logread logread.f
This will compile the Fortran and make an executeable called "logread".
chgrp 0329 logread
The chgrp command will change the group ownership to the group that will be executing your program. Replace "0329" with your group name.
chmod 4710 logread
This change mode command will set the "setuid bit"; Read, write and execute for you; just execute for any user in group 0329; and no access for others.
chmod 600 /home/strauss/usrc/49/18795/log
This is the change mode command for the data file. It allows read and write to you, and your program since it will be run as you. No access for all others.
mv logread ~/bin
Finally, this will move the executable to its production directory. Tell your users to include your bin directory in their path.

Example of a program which locks the file

Here is an example of a Fortran program that only allows one user at a time access to the data base for modification.

logwrite.f

character*10 value character*40 log/'/home/strauss/usrc/49/18795/log'/ character*40 lock/'/home/strauss/usrc/49/18795/log.lock'/ open(11,file=lock,status='new',err=99) open(10,file=log,recl=16,access='direct',form='formatted') write(*,fmt='(a)') 'Enter record number:' read(*,fmt='(i)') irec write(*,fmt='(a)') 'Enter string:' read(*,fmt='(a)') value write(10,rec=irec,fmt='(i5,x,a10)') irec, value close(10) close(11,status='delete') stop 99 write(*,fmt='(a,a)') 'Locked file: ',log end

If the lock file does not exist, the first open file will create it and proceed with no error jump. When the program is ready to close the data file it also closes the lock file with a status of delete to remover it. Now the data base is ready for another user.

If the lock file does exit it means the file is busy and some other user is using the file. At this point the program exits with an appropriate error message so the user knows to try again later.