The 'Security Digest' Archives (TM)

Archive: About | Browse | Search | Contributions | Feedback
Site: Help | Index | Search | Contact | Notices | Changes

ARCHIVE: Unix 'Security Mailing List' - Archives (1984 - 1987)
DOCUMENT: Unix 'Security Mailing List' #28 not known (1 file, 7908 bytes)
SOURCE: http://securitydigest.org/exec/display?f=unix/archive/028.txt&t=text/plain
NOTICE: securitydigest.org recognises the rights of all third-party works.

START OF DOCUMENT


Subject: # 28 - Security Mailing List

-------
Topics:
	Admin and new people on the list

----------------------------------------------------------------------------

Editor's corner.

This contains the second half of Pat Wood's programs and some notes he
sent along.  I've also changed the Subject lines (see above) so that
UCB mail users don't see the issue number truncated in 'mail'.


Newcomers to the list since last issue:
	Clyde Hoover (clyde@ut-ngp)
	George M. Sie (george@rebel)
	Scott Alexander (salex@linc.cis.upenn.edu)
	Chuck Athey (athey@lll-lcc)
	Rob Marchand (rob@array)
	Ronald W. Heiby (mcdchg!heiby@cbatt)
	Michael R. Pabrinkis (mpabrin@nswc-g.arpa)
	Rick Morin (cfcl!rdm@hoptoad)
	David Brower (daveb@rtech)
	Jeff Janock (jeff@necntc)
	Stuart Stirling (silver@emory)

----------------------------------------------------------------------------
: [join this to the end of the last posting --aburt]
echo restoring rspooler.c
sed 's/^X//' > rspooler.c <<\XxXxXxXxXx-EOF-XxXxXxXxXx
X/*
X** rspooler
X** rspooler pipe_file
X** reads from pipe_file (first argument) and sends data to 'lp'
X*/
X#include <stdio.h>
X#include <pwd.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	FILE *ipipe, *opipe, *popen();
X	struct passwd *pwentry, *getpwnam();
X	struct stat istatus;
X	int c;
X
X	if(argc != 2){
X		fprintf(stderr, "rspooler: needs spooler file\n");
X		exit(1);
X	}
X/*
X** if running as root, set UID to that of 'lp'
X*/
X	if(geteuid() == 0){
X		if((pwentry = getpwnam("lp")) == NULL){
X			fprintf(stderr, "rspooler: lp id not in /etc/passwd\n");
X			exit(2);
X		}
X		setuid(pwentry->pw_uid);
X	}
X/*
X** do forever
X*/
X	for(;;){
X/*
X** attempt to open named pipe
X*/
X		if((ipipe = fopen(argv[1], "r")) == NULL){
X			fprintf(stderr, "rspooler: cannot open %s\n", argv[1]);
X			exit(3);
X		}
X/*
X** make sure argument is a named pipe
X*/
X		if(fstat(fileno(ipipe), &istatus)){
X			fprintf(stderr, "rspooler: cannot stat %s\n", argv[1]);
X			exit(4);
X		}
X		if((istatus.st_mode & 010000) == 0){
X			fprintf(stderr, "rspooler: %s isn't a pipe\n", argv[1]);
X			exit(5);
X		}
X/*
X** open pipe to '/usr/bin/lp' with popen()
X*/
X		if((opipe = popen("PATH=/bin:/usr/bin lp -s -tjdm", "w")) == NULL){
X			fprintf(stderr, "rspooler: cannot run /usr/bin/lp\n");
X			exit(6);
X		}
X/*
X** copy input pipe file to output pipe command
X*/
X		while((c = getc(ipipe)) != EOF)
X			putc(c, opipe);
X/*
X** close pipes
X*/
X		fclose(ipipe);
X		pclose(opipe);
X	}
X}
XxXxXxXxXx-EOF-XxXxXxXxXx
echo restoring secure
sed 's/^X//' > secure <<\XxXxXxXxXx-EOF-XxXxXxXxXx
X#
X#	secure - security audit program 
X#	
X
XPATH=/bin:/usr/bin:/etc
X
X# 
X# note: finding files that are readable/writable by anyone requires 
X# a login account that doesn't have access to any files; the program
X# fndother should be SUID/SGID to that account
X#
X
X# 
X# directories to search for -b option
X#
X
Xsidlist="/bin /usr/bin /usr/lib /etc"
X
X#
X# name of administrative groups to check for multiple members 
X# (-g option)
X#
X
Xgrouplist="root adm bin sys "
X
X#
X# files to ignore for readable/writable check
X#
X
XIGNORERW="/rje/| /usr/tmp| /tmp| /usr/spool/uucppublic" 
X
X#
X# People that mail should not be sent to with -m option 
X# (Note single quotes and \n between each name)
X#
X
XNOMAIL='console\nuucp\nroot'
X
X#
X# Number of days since last login check (-l option)
X#
X
XLOG1DAYS=180
XLOG2DAYS=14
X
XERRORS=errors$$
XNONE="\t*** NONE FOUND ***"
XROOTID=0
Xumask 077
X
X#
X#	process options
X#
X
Xwhile [ $# -ne 0 ]
Xdo
X	case "$1"
X	in
X		-b  )	binck=1;;
X		-c  )	permck=1;;
X		-f  )	shift  
X			if [ $# -ne 0 ]
X			then
X				fsys=$1
X			else
X				errorflag=1
X				break
X			fi;;
X		-f* )   fsys=`echo $1 | cut -c3-`;;
X		-g  )	grpck=1;;
X		-l  )	loginck=1;;
X		-m  )	mailopt=1;;
X		-p  )	passwdck=1;;
X		-r  )	readck=1;;
X		-s  )	sidck=1;;
X		-u  )	shift
X			if [ $# -ne 0 ]
X			then
X				user=$1
X			else
X				errorflag=1
X				break
X			fi;;
X		-u* )	user=`echo $1 | cut -c3-`;;
X		-w  )	writeck=1;;
X		*   )	errorflag=1
X		        break;;
X	esac
X	
X	shift	
Xdone
X
Xif [ -n "$errorflag" ]
Xthen
X	echo '\n\tUsage:  secure [-bcglmprsw] [-f filesys | -u user]\n' >&2
X	exit 1
Xfi
X
Xid=`id | sed 's/uid=\([0-9]\{1,\}\).*$/\1/'`  # get id of runner
X
X#
X# 	check for option  consistency
X#
X
Xif [ "$id" -ne $ROOTID -a -n "$binck$fsys$grpck$loginck$permck$user" ]
Xthen
X	echo '\nOptions [bcfglu] can only be selected by root\n' >&2
X	exit 1
Xelif [ -n "$fsys" -a -n "$user" ]
Xthen
X	echo '\nOptions -f and -u cannot be used together\n' >&2
X	exit 1
Xfi
X
X#
X# 	set up default options if none selected
X#
X
Xanyflags="$binck$grpck$loginck$passwdck$permck$readck$sidck$writeck"
X
Xif [ -z "$anyflags" ]
Xthen
X	sidck=1
X	writeck=1
X
X	if [ "$id" -eq $ROOTID -a  -z "$user$fsys" ]
X	then
X		binck=1
X		grpck=1
X		loginck=1
X		passwdck=1
X	fi
Xfi
X
Xif [ $id -ne $ROOTID ]
Xthen
X	user=`id | sed 's/^uid=[0-9]*(\(.*\)) gid=.*$/\1/'`
Xfi
X
X#
X#  	start audit
X#
X
Xtrap 'echo "\n===== AUDIT INTERRUPTED =====\n" 
X rm -f $STALE1 $STALE2 $PROFS $NOPW $NOPWAGE $NOPWCH $FILES \
X	$SIDFILES $SIDBCFILES $BCFILES ${FILES}2 ${SIDFILES}2 $ERRORS; 
X exit 1'  1 2 3 15
X
Xecho "\n\nSECURITY AUDIT \t\t\t\t\t `date`"
Xecho "============== \t\t\t\t\t ============================"
X
X#
X# 	set uid and gid file listing
X#
X
Xif [ -n "$binck" ]
Xthen
X	echo "\n===== SYSTEM SET UID AND GID FILE CHECK ====="
X	
X	if [ -r "/etc/bincheck" ]
X	then
X		sidlist=`cat /etc/bincheck`
X	fi
X	
X	for dir in $sidlist
X	do
X		echo "\n$dir:"
X		ls -lt $dir | sed -n "/^.\{3,6\}[sS]/p" |
X		while file=`line`
X		do
X			name=`echo $file | sed 's/.* //'`
X			set -- `sum $dir/$name 2>>$ERRORS`
X			
X			if [ $? -ne 0 ]
X			then
X				echo "**err**\t$file"
X			else
X				echo "$1\t$file"
X			fi
X		done
X	done
X	
X	echo "\n\n"	
Xfi
X
X#
X#	file ownership and access modes check
X#
X
Xif [ -n "$permck" ]
Xthen
X	if [ -x /etc/perms ]
X	then
X		/etc/perms -c
X	else
X		echo "\n***** /etc/perms program not found!! *****\n"
X	fi
Xfi
X
X
X#
X# 	Perform login check and password check:
X#		1. look for people who haven't logged-in in the last
X#	 	  LOG1DAYS and LOG2DAYS (loginck)
X#		2. look for .profiles explicitly writable by anyone (loginck)
X#		3. look for logins with no passwords (passwdck)
X#		4. look for users whose passwords don't expire (passwdck)
X#		5. look for users who can't change their passwords (passwdck)
X#		6. look for users with the same uids (passwdck)
X#  		7. run /etc/pwck (passwdck)
X#
X
Xif [ -n "$loginck$passwdck" ]
Xthen
X	STALE1=stale1$$
X	STALE2=stale2$$
X	PROFS=prof$$
X	NOPW=nopw$$
X	NOPWAGE=pwage$$
X	NOPWCH=pwch$$
X	
X	while pwline=`line`
X	do
X		username=`echo $pwline | cut -d: -f1`
X		password=`echo $pwline | cut -d: -f2`
X		homedir=`echo $pwline | cut -d: -f6`
X		length=`expr "$password" : '.*'`
X
X		if [ -n "$loginck" -a $length -ge 13  -a \
X			 -f "$homedir/.profile" ]
X		then
X			find $homedir/.profile -atime +$LOG1DAYS \
X			-exec echo $username >> $STALE1 \; 2>>$ERRORS
X			
X			find $homedir/.profile -atime +$LOG2DAYS \
X			-exec echo $username >> $STALE2 \; 2>>$ERRORS
X
X			find $homedir/.profile -perm -2 \
X			-exec echo $username >> $PROFS \; 2>>$ERRORS
X		fi
X		
X		if [ -n "$passwdck" ]
X		then
X			if [ $length -eq 0 ]
X			then
X				echo "$username" >> $NOPW
X			elif [ $length -ge 13 -a $length -le 15 ]
X			then
X				echo "$username" >> $NOPWAGE
X			elif [ $length -gt 15 ] && \
X				expr X`echo $password | cut -c15` \< \
X				X`echo $password | cut -c16` > /dev/null
X			then
X				echo "$username" >> $NOPWCH
X			fi
X		fi
X	done < /etc/passwd
X		
X	if [ -n "$loginck" ]
X	then
X		echo "\n===== USERS WHO HAVE NOT LOGGED-IN IN \c"
X		echo "THE LAST $LOG1DAYS DAYS =====\n"
X		
X		if [ -s $STALE1 ]
X		then
X			sort $STALE1 | pr -t -w80 -8 
X		else
X			echo "$NONE"
X		fi
X		
X		echo "\n===== USERS WHO HAVE NOT LOGGED-IN IN \c"
X		echo "THE LAST $LOG2DAYS DAYS =====\n"
X		
X		if [ -s $STALE2 ]
X		then
X			sort $STALE2 | pr -t -w80 -8 
X		else
X			echo "$NONE"
X		fi
X
X		echo "\n===== USERS WHOSE .profile's ARE EXPLICITLY \c"
X		echo "WRITABLE BY ANYONE =====\n"
X
X		if [ -s $PROFS ]
X		then
X			sort $PROFS | pr -t -w80 -8
X		else
X			echo "$NONE"
X		fi
X		
X		rm -f $STALE1 $STALE2 $PROFS
X	fi
X	
X	if [ -n "$passwdck" ]
X	then
X		echo "\n===== USERS WITH NO PASSWORDS =====\n"
X		
X		if [ -s $NOPW ]
X		then
X			sort $NOPW | pr -t -w80 -8
X		else
X			echo "$NONE"
X		fi
X		
X		echo "\n===== USERS WITH PASSWORDS THAT DON'T EXPIRE =====\n"
X
X		if [ -s $NOPWAGE ]
X		then
X			sort $NOPWAGE | pr -t -w80 -8
X		else
X			echo "$NONE"
X		fi
X
X		echo "\n===== USERS WHO CAN'T CHANGE THEIR PASSWORD =====\n"
X
X		if [ -s $NOPWCH ]
X		then
X			sort $NOPWCH | pr -t -w80 -8
X		else
X			echo "$NONE"
X		fi
X
X		rm -f $NOPW $NOPWAGE $NOPWCH
X		
X		if [ -x /etc/pwck ]
X		then
X			echo "\n====== RUN OF /etc/pwck =====\n"
X			/etc/pwck 
X		fi
X		
X		echo "\n===== USERS WITH THE SAME UID =====\n"
X		dupids=`cut -d: -f3 /etc/passwd | sort -n | uniq -d`
X		
X		if [ -z "$dupids" ]
X		then
X			echo "$NONE"
X		else
X			for id in $dupids
X			do
X				echo "$id:"
X				sed -n "s/^\(.*\):.*:$id:.*$/\1/p" \
X				 /etc/passwd | cut -d: -f1 | 
X				pr -o5 -w65 -t -5
X				echo
X			done
X		fi
X	fi
Xfi
X
X#
X# 	group check:
X#		1. check groups in grouplist
X#		2. runs /etc/grpck
X#
X	
Xif [ -n "$grpck" ]
Xthen
X	echo "\n===== CHECK OF ADMINISTRATIVE GROUPS ====="
X	for login in $grouplist
X	do
X		pwline=`grep "^$login:" /etc/passwd `
X		if [ -z "$pwline" ]
X		then
X			continue
X		fi
X
X		groupid=`echo $pwline | cut -d: -f4`
X		if [ -n "$groupid" ]
X		then
X			members=`sed -n "s/^.*:.*:$groupid://p" /etc/group`
X			
X			if [ -n "$members" ]
X			then
X				list=`(echo "$members" | tr "," "\012";
X				sed -n "s/^\(.*\):.*:.*:$groupid:.*$/\1/p" \
X				/etc/passwd) | sort -b | uniq | fgrep -vx $login`
X				
X				if [ -n "$list" ]
X				then
X					echo "\nThe following users are in the \c"
X					echo "same group as $login ($groupid):\n"
X					echo "$list" | pr  -t -w80 -8 
X				fi
X			fi
X		fi
X	done
X
X	if [ -x /etc/grpck ]
X	then
X		echo "\n===== RUN OF /etc/grpck =====\n"
X		/etc/grpck
X	fi
Xfi
X
X#
X#	file system check:
X#		1. set uid and gid files
X#		2. block/character special files not in /dev (root only)
X#		3. files that are readable by anyone
X#		4. files that are writable by anyone
X#
X
Xif [ -n "$user" -o -n "$fsys" ]
Xthen
X	if [ -n "$user" ]
X	then
X		fsys=`grep "^$user:" /etc/passwd | cut -f6 -d:`
X		if [ -z "$fsys" ]
X		then
X			echo "*** can't find home directory for $user" >&2
X			exit 1
X		fi
X	fi
Xelse
X	fsys=/	# root
Xfi
X
Xif [ "$id" -eq $ROOTID ]
Xthen
X	blockchar="-o -type b -o -type c"
Xfi
X
XSIDBCFILES=sbcfiles$$
XSIDFILES=sfiles$$
XBCFILES=bcfiles$$
X
Xif [ -n "$sidck" ]
Xthen
X	echo "\n===== CHECKING $fsys FOR SET UID AND GID FILES =====\n"
X		
X	find $fsys \( -perm -2000 -o -perm -4000 $blockchar \) \
X		 -print > $SIDBCFILES.1
X	if [ -s $SIDBCFILES.1 ]
X	then
X		xargs ls -ld < $SIDBCFILES.1 > $SIDBCFILES 2>>$ERRORS
X	else
X		> $SIDBCFILES
X	fi
X	rm $SIDBCFILES.1
X
X	if [ -n "$blockchar" ]
X	then
X		# get block and char special files (ignore files in /dev)
X
X		sed -n "/^[bc].\{53\}\/dev\//d;/^[bc]/p" $SIDBCFILES > $BCFILES  
X		# get SUID/SGID files
X
X		grep -v "^[bc]" $SIDBCFILES > $SIDFILES
X	else
X		SIDFILES=$SIDBCFILES
X	fi
X
X	if [ -s "$SIDFILES" ]
X	then
X		tr -s " " "\011" < $SIDFILES | cut -f1,3,4,9 | tee ${SIDFILES}2
X	else
X		echo "$NONE"
X	fi
X
X	if [ -n "$blockchar" ]
X	then
X		echo "\n===== BLOCK/CHARACTER SPECIAL FILES IN $fsys =====\n"
X
X		if [ -s "$BCFILES" ]
X		then
X			tr -s " " "\011" < $BCFILES | cut -f1,3,4,9 
X		else
X			echo "$NONE"
X		fi
X	fi
Xfi
X
Xif [ -n "$readck$writeck" ]
Xthen
X	if [ -n "$readck" ]
X	then
X		cmd="-perm -4"
X		string="READABLE"
X	fi
X
X	if [ -n "$writeck" ]
X	then
X		if [ -n "$readck" ]
X		then
X			cmd="$cmd -o"
X			string="$string/"
X		fi
X		cmd="$cmd -perm -2"
X		string="${string}WRITABLE"
X	fi
X	
X	echo "\n===== FILES IN $fsys THAT ARE $string BY\c"
X	echo " ANYONE =====\n"
X
X	FILES=file$$
X
X#
X#	run "find"  by `fndother' SUID/SGID to someone that doesn't 
X#	have access to any files
X#
X	fndother "$fsys" "$cmd" > $FILES 
X				
X	if [ -s $FILES ]
X	then
X		xargs ls -ld < $FILES | egrep -v "$IGNORERW" |
X	  	tr -s " " "\011" | sed "s/[0-9]\{1,\},	//" |
X		# note char after last , in above sed is a single tab
X	  	cut -f1,3,9  | tee ${FILES}2
X	else
X		echo "$NONE"
X	fi
Xfi
X
Xif [ -n "$mailopt" ]
Xthen
X	for file in ${SIDFILES}2 ${FILES}2
X	do
X		if [ ! -s $file ]
X		then
X			continue
X		fi
X		
X		if [ $file = ${SIDFILES}2 ]
X		then
X			string2="SET UID/GID FILES WERE FOUND BY SECURE"
X		else
X			string2="FILES ARE $string BY ANYONE"
X		fi
X		
X		lastowner=""
X			
X		sort +2 $file |
X		while mfile=`line`
X		do
X			set -- $mfile
X			owner=$2
X					
X			if [ "$lastowner" = "$owner" ]
X			then
X				continue
X			fi
X				
X			if echo "$NOMAIL" | grep "^$owner$" >/dev/null
X			then
X				continue
X			fi
X
X			lastowner=$owner
X			pwline=`grep "^$owner:" /etc/passwd 2>>$ERRORS`
X						
X			if [ -z "$pwline" ]
X			then
X				continue
X			fi
X				
X			home=`echo $pwline | cut -d: -f6`
X
X			if [ -n "$home" -a \( -f "$home/.profile" -o \
X				"$owner" = root \) ]
X			then
X				( echo "\n==== THE FOLLOWING $string2 ====\n"
X				grep "	$owner	" $file ) | mail $owner
X				# note single tabs surround $owner above
X			fi
X		done
X	done
Xfi
X
Xif [ -s "$ERRORS" ]
Xthen
X	echo "\n===== ERRORS DETECTED =====\n"
X	cat $ERRORS
Xfi
X
Xrm -f  ${FILES} ${FILES}2 $ERRORS $SIDBCFILES $BCFILES ${SIDFILES} ${SIDFILES}2 
Xecho "\nAUDIT COMPLETE\n"
XxXxXxXxXx-EOF-XxXxXxXxXx
echo restoring shlock
sed 's/^X//' > shlock <<\XxXxXxXxXx-EOF-XxXxXxXxXx
XPATH=/bin:/usr/bin
Xstty -echo
X
Xwhile [ -z "$code" ]
Xdo
X	echo "\nEnter password: \c" 
X	read code < /dev/tty
Xdone
X
Xtrap "" 2 3
X
Xecho "
X
X
X
X*****************************************************
X*                                                   *
X*                                                   *
X*                                                   *
X*                                                   *
X*               TERMINAL SECURED !!!                *
X*                                                   *
X*                                                   *
X*                                                   *
X*                                                   *
X*****************************************************
X
X
X"
X
Xi=1
Xmatch=""
X
Xwhile [ "$match" != "$code" ]
Xdo
X	sleep $i
X	echo "\nEnter password: \c" 
X	read match < /dev/tty
X	i=`expr $i '*' 2`
Xdone
X
Xecho
Xstty echo
XxXxXxXxXx-EOF-XxXxXxXxXx
echo restoring fndother.c
sed 's/^X//' > fndother.c <<\XxXxXxXxXx-EOF-XxXxXxXxXx
X/*
X**  program to search file system for files that are
X**  readable/writable by anyone.  Must be SUID/SGID
X**  to user without access to any files on the system.
X*/
X
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{
X	char buf[256];
X	
X	sprintf (buf, "/bin/find %s %s -print 2>/dev/null", argv[1], argv[2]);
X	system (buf);
X}
XxXxXxXxXx-EOF-XxXxXxXxXx



----------------------------------------------------------------------------

Date: Mon, 2 Mar 87 00:35:55 EST
From: root@bellcore.uucp

Note to everyone who's interested in the programs I just posted:
We're working on a faster version of "secure" which makes just one
"find" pass on the file system.  At the moment, it prints out too
much, and needs to have some command-line options to control that.
I'll post it when it's in a more stable (and usable) form.

Pat Wood
Pipeline Associates, Inc.
{ihnp4,seismo,harpo}!bellcore!phw5!phw



----------------------------------------------------------------------------

Date: Mon, 2 Mar 87 00:14:02 EST
From: root@bellcore.uucp

The following is an improved permission maintaining program that was
first published in "UNIX System Security" by Steve Kochan and me.  This
version is faster as it uses a special program (mode) to figure out the
octal modes of a file, rather than 'ls -l | sed "bizarre stuff"'

The file 6300.binlist is a sample permissions file that contains the
default permissions for the /bin directory and the files that go in it.
Exception lists follow for shell programs that must be 755 mode and
SUID/SGID programs such as su and enable/disable.

Note that the line nosticky="" can be changed to nosticky="-i" to turn
off checking of the sticky bit on files (this should be a command-line
arg to turn this test on/off, but I'm too lazy to fix it).

For a complete description of the program and its options, consult the
Security Book; otherwise, most of the functions should be fairly obvious.

Pat Wood
Pipeline Associates, Inc.
{ihnp4,seismo,harpo}!bellcore!phw5!phw
--------------------------------cut here------------------------------
# To recover, type "sh archive"
echo restoring perms
sed 's/^X//' > perms <<\XxXxXxXxXx-EOF-XxXxXxXxXx
X#
X#	new perms: set or check file permissions
X#		uses "mode" program to determine file ownership and modes
X#		new option added: -i -- ignore sticky bit
X#
X
Xnosticky=""	# can be set to -i to ignore sticky by default
X
Xwhile [ $# -ne 0 ]
Xdo
X	case $1
X	in
X		-c)	check=1;
X			if [ -n "$set" -o -n "$make" ]
X			then
X				error=1
X			fi;;
X		-s)	set=1;
X			if [ -n "$check" -o -n "$make" ]
X			then
X				error=1
X			fi;;
X		-f)	shift;
X			if [ $# -eq 0 ]
X			then
X				error=1
X			else
X				PERMLIST=$1
X			fi;;
X		-f*)	PERMLIST=`echo $1 | cut -c3-`;;
X		-m)	make=1;
X			if [ -n "$set" -o -n "$check" ]
X			then
X				error=1
X			fi;;
X		-i)	nosticky=-i;;
X		*)	error=1;;
X	esac
X
X	shift
Xdone
X
Xif [ -n "$error" -o -z "$set$check$make" ]
Xthen
X	echo "
X	Usage:	perms -[csm] [-f file] 
X	-c		check file permissions against /etc/permlist
X	-s		set file permssions to agree with /etc/permlist
X	-f file		use "file" instead  (defaults to /etc/permlist
X			for -c and -s options; standard input for -m)
X	-m		take list of files from standard input (unless
X			-f option used) and write current permissions 
X			to standard output (for future runs of /etc/perms)
X			Files are listed one per line, and substitution is
X			allowed (e.g. /bin/* specifies all files in /bin)
X	"
X	exit 1
Xfi
X
Xif [ -z "$PERMLIST" ]
Xthen
X	if [ -n "$make" ]
X	then
X		PERMLIST="-"	# standard input
X	else
X		PERMLIST=/etc/permlist
X	fi
Xfi
X
Xif [ "$PERMLIST" != "-" -a ! -r "$PERMLIST" ]
Xthen
X	echo "\n*** Can't read $PERMLIST" >&2
X	exit 2
Xfi
X						
Xif [ -n "$check" ]
Xthen
X	echo "\n===== Checking permissions against $PERMLIST ====="
X	LOGFILE=/tmp/perms$$
X	trap "rm -f $LOGFILE; exit" 0 1 2
Xelif [ -n "$set" ]
Xthen
X	echo "\n===== Changing permissions to agree with $PERMLIST ====="
Xfi
X
Xif [ -n "$make" ]
Xthen
X	cat $PERMLIST | mode $nosticky
X	exit 0
Xfi
X
Xcat $PERMLIST |	
Xwhile permline=`line`
Xdo
X	if expr "$permline" : '#' > /dev/null
X	then
X		continue
X	fi
X
X        set -- $permline	
X
X	if [ -n "$check$set" ]
X	then
X		if [ $# -lt 4 ]
X		then
X			echo "Bad line in $PERMLIST: $permline, continuing" >&2
X			continue
X		fi
X
X		owner=$1
X		group=$2
X		mode=$3
X		shift; shift; shift 	# shift n not in earlier releases
X	fi
X	
X	for file in $*
X	do
X		if [ -n "$set" ]
X		then
X			chown $owner $file  && chgrp $group $file && \ 
X			chmod $mode $file
X			continue
X		fi
X
X		if [ -n "$check" -a -s $LOGFILE ]
X		then
X		# see if this file has already been logged
X
X			if  grep "^$file	" $LOGFILE >/dev/null 2>&1
X			then
X				# remove from the LOGFILE
X				grep -v "^$file	" $LOGFILE >/tmp/permx$$
X				mv /tmp/permx$$ $LOGFILE
X			fi
X		fi
X
X		# get octal mode for file
X
X		fileperm=`mode $nosticky $file`  || continue
X		set -- $fileperm
X
X		currowner=$1
X		currgroup=$2
X		currmode=$3
X
X		# assume here that permissions will match
X
X		if [ "$currowner$currgroup$currmode" != \
X			"$owner$group$mode" ]
X		then
X			cstr="$file\t"
X
X			if [ "$currowner" != "$owner"  ]
X			then
X				cstr="$cstr   OWNER=$currowner ($owner)"
X			fi
X
X			if [ "$currgroup" != "$group"  ]
X			then
X				cstr="$cstr   GROUP=$currgroup ($group)"
X			fi
X
X			if [ "$currmode" != "$mode"  ]
X			then
X				cstr="$cstr   MODE=$currmode ($mode)"
X			fi
X
X			echo "$cstr" >> $LOGFILE
X		fi
X	done
Xdone
X
Xif [ -n "$check" ]
Xthen
X	if [ -s $LOGFILE ]
X	then
X		echo "\nThe following files do not check.  Fields \c"
X		echo "that don't match\nare listed followed by \c"
X		echo "the desired value in parentheses.\n"
X		sort $LOGFILE
X	else
X		echo "\n*** All files check out okay! ***\n"
X	fi
Xfi
XxXxXxXxXx-EOF-XxXxXxXxXx
echo restoring mode.c
sed 's/^X//' > mode.c <<\XxXxXxXxXx-EOF-XxXxXxXxXx
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <pwd.h>
X#include <grp.h>
X
X#define MAXSIZE 256
X
Xint eflag = 0;
Xint nosticky;
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X	char fname[MAXSIZE];
X
X	/* check for option */
X	if (argc != 1)
X		if (argv[1][0] == '-' && argv[1][1] == 'i') {
X			nosticky = 1;
X			argv++; argc--;
X		}
X
X	if (argc == 1)
X		while (scanf ("%s", fname) > 0)
X			prmode (fname);
X	else
X		while (--argc)
X			prmode (*++argv);
X
X	exit (eflag);
X}
X
Xprmode (name)
Xchar *name;
X{
X	struct stat stats;
X	struct passwd *user, *getpwuid();
X	struct group *group, *getgrgid();
X
X	if (stat (name, &stats)) {
X		fprintf (stderr, "cannot stat %s\n", name);
X		eflag = 1;
X		return;
X	}
X
X	if ((user = getpwuid (stats.st_uid)) == NULL)
X		printf ("%o	", stats.st_uid);
X	else
X		printf ("%s	", user->pw_name);
X
X	if ((group = getgrgid (stats.st_gid)) == NULL)
X		printf ("%o	", stats.st_gid);
X	else
X		printf ("%s	", group->gr_name);
X
X	if (nosticky)
X		stats.st_mode &= 0176777;
X
X	printf ("%o	%s\n", stats.st_mode & 07777, name);
X}
XxXxXxXxXx-EOF-XxXxXxXxXx
echo restoring 6300.binlist
sed 's/^X//' > 6300.binlist <<\XxXxXxXxXx-EOF-XxXxXxXxXx
X#
X#	Define owner, group owner and permissions of files
X#		(separate fields by tabs)
X#	Note that the order of file specifications is important
X#	(i.e., list global permissions first before specific
X#	 file permissions, as in /bin/* before particular files in /bin)
X#
X#owner  group	perms 	file(s) 
X#		(octal)
X#------------------------------------------------------------
X#
X#	permissions for /bin
X#
Xbin	bin	755	/bin
X# default for all files in /bin
Xbin	bin	711	/bin/*
X#
Xbin	bin	755	/bin/diff3 /bin/dircmp /bin/dirname
Xbin	bin	755	/bin/false /bin/true /bin/whodo
Xbin	bin	700	/bin/chroot /bin/pwadmin
Xsysinfo	bin	4711	/bin/df /bin/ipcs /bin/ps /bin/pstat
Xroot	bin	4711	/bin/mkdir /bin/newgrp /bin/passwd /bin/rmdir
Xroot	bin	4711	/bin/su
Xlp	bin	4711	/bin/enable /bin/disable
Xroot	root	711	/bin/login
XxXxXxXxXx-EOF-XxXxXxXxXx



----------------------------------------------------------------------------

----------------------------------------------------------------------------

                        The UNIX Security Mailing List

                 Ignore the headers on this list and mail to:
                  ...!hao!isis!security (mail for the list).
                  ...!hao!isis!sec-request (administrativia).

END OF DOCUMENT