SOLUTIONS TO EXERCISES


Section 2| Section 3| Section 4| Section 5| Section 6| Section 7| Section 8| Section 9| Section 10| Section 11| Section 12| Section 13| Section 14| Section 15| Section 16

Section 2

1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10 / 11
2-1.
a) echo *
all the files
b) echo *[!0-9]
all the files that don't end in a number, memo2.sv
c) echo m[a-df-z]*
any file starting with an m followed by any lowercase letter other than e.
d) echo [A-Z]*
all files starting with an upper case letter
e) echo jan*
all files starting with jan
f) echo *.*
all files with a name that contains a . UNIX is not MS-DOS there is no need for a file to have a . in its name.
g) echo ?????
any file with a five character name
h) echo *89
any file ending with 89
i) echo jan?? feb?? mar??
jan85 jan86 jan87 jan88 feb86 mar88
j) echo [fjm] [ae] [bnr] *
feb86 jan12.89 jan19.89 jan26.89 jan5.89 jan85 jan86 jan87 jan88 mar88

2-2.
a) ls wc -1
Count the number of lines output by the ls command. This has the affect of counting how many files are in the current directory. When output from ls is sent to the screen it is usually put into columns. Whenever the output from ls is sent to a pipe it is sent one filename per line. Try the following commands ls and ls | cat Do you see the difference?
b) rm ???
remove all files with three character filenames from the current directory
c) who wc -1
Count the number of lines output by the who command. In effect this counts the number of users who are currently logged onto the computer.
d) mv progs/* /usr/steve/backup
Move all the files from the progs subdirectory into the directory /usr/steve/backup
e) ls *.c wc -1
See a). This command counts the number of files with .c extensions in the current directory.
f) rm *.o
Remove all files with a .o extension from the current directory
g) who sort
Sort the output of the who command in alphabetical order.
h) pwd
Display the current working directory
i) cp memo1 ..
Copy the file memo1 into the parent directory
j) plotdata 2>errors &
Run the program plotdata in the background and redirect standard error so that it is written to the file errors rather than to the screen.

2-3.
a) no, to be able to obtain a directory listing a user needs to have read and execute access on a directory.
b) yes, the user astaff has the required privileges because it is a member of the group owner.
c) yes, astudent can obtain a directory listing. However if the other access permissions on the jonesd directory were changed so that others had no access at all astudent would not be able to get a directory listing of the docs directory.
To access a subdirectory a user must have at least execute access on all the parent directories.
d) yes, astudent can create a file in the docs directory. To be able to create a file in a directory you need write access.

2-4.
a) 605
b) 777
c) 073

2-5.
a) --x--x--x
b) r-xr-x---
c) rwxr-x---

2-6. If you can't see the value for shell by just typing set try one of the following commands:
		echo $SHELL		echo $shell

2-7. Yes the shell variable should change if you run a different type of shell.


2-8. The output of the command
		echo Multiply is signified by the * symbol
	will be
		Multiply is signified by the file_list symbol
where file_list will be all the filenames in the current directory.


2-9. The output of the following two lines
		string=hello there how are you
		echo $string
	will be
		hello
The shell variable is assigned only the first word. The shell interprets the space after hello as separating out a command and ignores the rest of the arguments. Using quote characters as follows would have solved the problem
	string="hello there how are you"

2-10.
I've use the touch command to create the file but there are a number of methods that could've been used. touch accepts a file name and creates a file of that name if one already doesn't exist. If one does exist it updates the time the file was last modified.
a) touch stars\*
b) touch "hello my friend" touch hello\ my\ friend
c) touch \"goodbye\"
d) rm stars\* "hello my friend" \"goodbye\"

2-11.
a) echo "** hello **"
output: ** hello **
The " " cause the shell to treat the * character as a normal character.
b) echo this is a star *
output: this is a star file_list
file_list will be the list of all files in the current directory. The shell interprets the * as a wildcard character and replaces it with the appropriate list of filenames.
c) echo ain\\\\'t you my friend
output: >
The shell will be waiting for some more input. The shell interprets the \\\\ to mean that it should treat two \ characters as normal characters and display them. This leaves the command line with one '. The shell now waits for another '. At the > prompt enter a ' character.
d) echo "the output of the ls command is `ls`"
output: the output of the ls command is ls_output
ls_output will be the output of the ls command.
e) echo 'the output of the pwd command is `pwd`
output: the output of the pwd command is `pwd`
The ' ' quotes around the command means that anything inside them is treated as a normal character and just displayed on the screen.

Section 3


1 / 2 / 3 / 4 / 5 / 6 / 7 / 8
3-1. Fairly self explanatory. Just follow the instructions.


3-2.
	#!/bin/sh
	echo The current directory is `pwd` and it contains `ls`

3-3.
a) e) and f) are valid variable names
The others are not because a shell variable name must start with either a letter or an underscore, and can only contain letters, numbers or an underscore (not #.)

3-4.
a) ls $home
b) mv ${home}temp ${home}temp2

3-5.
	#!/bin/sh
	echo $0 accepted $# command line arguments
	echo they were $*
$0 should be used here as it allows the shell procedure to be renamed and it will still work as specified.


3-6.
	#!/bin/sh
	if [ $# -eq 0 ]
	then
	   echo No parameters were passed.
	   exit 1
	fi
	echo $0 accepted $# command line arguments
	echo they were $*

3-7.
	#!/bin/sh
	if [ $# -eq 0 ]
	then
	   echo usage: $0 filename
	   echo $0 will test to see if filename exists
	   exit 1
	fi
	if [ -f $1 ]
	then
	   echo The file $1 exists.
	else
	   echo The file $1 does not exist.
	fi

3-8.
	#!/bin/sh
	if [ $# -eq 0 ]
	then
	   echo usage: $0 filename
	   echo $0 will test to see if filename exists
	   exit 1
	fi
	for filename in $*
	do
	   if [ -f $filename ]
	   then
	      echo The file $filename exists.
	   else
	      echo The file $filename does not exist.
	   fi
	done

Section 4


1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10
4-1.
	#!/bin/sh

	if [ $# -eq 0 ]
	then
	  echo USAGE: $0 list_of_filenames
	  echo $0 will return what type of files they are
	  exit 1
	fi

	file_type()
	{
	  if [ -d $1 ]
	  then
	    type=directory
	  elif [ -h $1 ]
	  then
	    type="symbolic link"
	  elif [ -c $1 ]
	  then
	    type="character device file"
	  elif [ -b $1 ]
	  then
	     type="block device file"
	  elif [ -p $1 ]
	  then
	    type="named pipe"
	  elif [ -f $1 ]
	  then
	    type="normal file"
	  else
	    type="something very unusual"
	  fi
	}

	for filename in $*
	do
	  file_type $filename
	  echo $filename is a $type
	done

4-2.
	#!/bin/bash
	ok()
	{
	  echo -n '(y,n) ==> '
	  read response
	  # put the response into uppercase
	  # it makes the comparison easier
	  response=`echo $response | tr [a-Z] [A-Z]`
	  case $response in
	    N | NO)     ;;
	    Y | YES)    ;;
	    *)  response=ERROR;;
	  esac
	}

	ok
	echo $response

4-3.
	#!/usr/local/bin/bash

	while read num1 num2
	do
	  echo $num1 + $num2 = `expr $num1 + $num2` >> totals
	done < amounts

4-4.
	#!/usr/local/bin/bash

	trap "echo $0 received signal 15" 15

	while [ 0 -eq 0 ]
	do
	  # do nothing useful
	  echo > /dev/null
	done

4-5.
a) any text starting with abc, followed by any character, followed by def
b) first letter a or A, second letter b or B, third letter c or C followed by dD
c) matches the end of a line
d) any text starting with zero or more characters that aren't s or S, followed by zero or more occurrences of one of a e i o u followed by zero or more occurrences of any lower case letter e) the text hello^there$friend (remember ^ and $ only have special meaning if they are at the start or the end of an RE)
f) any text starting with either a b c and ending with a *
g) any occurrence of the text [hello there. where the . can be repeated zero or more times, and the text must be at the end of the line

4-6.
a) grep ^j /etc/passwd
b) grep ^j.*bash$ /etc/passwd
c) grep .*:.*:.*:[0-9][:0-9][^0-9] /etc/passwd
The .*: are used to ignore the first few fields until we get to the group field of /etc/passwd. The [0-9][:0-9][^0-9] takes into account the following situations (for the group number) There is still one instance when this will fail and that is when the group number is less than 10 and the first character in the GCOS field (the next field after the group field) is a number.

4-7.
a) 1,$s/UNIX/UNIX\[tm\]/g
b) /BEGIN/,/END/s/Write/Writeln/g
c) 1,$s/^>//

4-8.
a)delete all lines from the line after the current line until the end of the file
b)for all lines in the file replace all occurrences of OSF with Open Software Foundation
c)from the first line in the file to the next line that contains end find any number of lower case letters followed by a space and then by any number of numeric characters and swap them around.
i.e. abc 43222 becomes 43222 abc

4-9.
	awk 'BEGIN { FS=":" }
	     {  total=$3+$4
	        printf "%s, %s  %3d/n", $1, $2, total
	     }' results.dat

4-10.
	#!/usr/local/bin/bash

	if [ $# -eq 0 ]
	then
	  echo Usage: $0 group_id
	  echo $0 will return a list of users belonging to the group id
	  exit 1
	fi

	for group in $*
	do
	  awk 'BEGIN { FS=":"
	             count=0 }
	     /.*:.*:.*:'$group':/{ print $1
	                           count++ }
	     END { if ( count !=0 )
	           printf "Group '$group' has %d users\n", count
	           else
	           printf "Group '$group' has no users\n" 
	         }' /etc/passwd
	done

Section 5


1 / 2
5-1. Factors that might affect policy etc. might include
5-2. Other areas that might require policy include

Section 6


1 / 2 / 3 / 4 / 5 / 6 / 7
6-1.
The location and format in which to specify an alias will be system dependent.
On a Linux machine using smail (smail is the mail system) the file to modify will be /usr/lib/aliases. The format of the entry will look something like
temp:david

This defines an alias temp. All mail sent to temp will actually be forwarded to the account with the username david.


6-2.
Remember that .login and .logout are files used by the C shell only. If your login shell is bash or another of the Bourne shell variants then these files will not be executed.

Add the following to your .profile (if you are using a Bourne shell derivative) or to your .login (if you using a C shell derivative).

	echo Logged in `date` > $HOME/account.usage
Add the following to your .logout
	echo Logged out `date` > $HOME/account.usage

6-3. & 6-4. These questions are best answered for your system by
6-5.
	#!/usr/local/bin/bash
	#
	# FILE:  	create_mail
	# PURPOSE:	Create a new mail file for a user with 
	#		correct permissions.  Login name is first 
	#		parameter
	# AUTHOR:  	David Jones
	# HISTORY: 	18/9/94 Created
	#

	MAIL_DIR=/usr/spool/mail

	# check to see parameter passed in
	if [ "$1" = "" ]
	then
	  echo 'ERROR: expecting login name as first parameter'
	  exit 1
	fi

	# check to see if file already exists
	if [ -r $MAIL_DIR/$1 ]
	then
	  echo 'ERROR: mail file already exists'
	  exit 2
	fi

	# create the file
	touch $MAIL_DIR/$1
	chown $1 $MAIL_DIR/$1
	chgrp mail $MAIL_DIR/$1
	chmod 660 $MAIL_DIR/$1

6-6.
There are a number of possible solutions there are two solutions listed below. Which solution do you think will take the most time? Use the time command to find out.
#!/usr/local/bin/bash
#
# FILE:      	get_uid.sh
# PURPOSE:  	Using commands other than awk obtain 
#			the next free UID number from the 
#			/etc/passwd file
# AUTHOR:   	David Jones
# HISTORY:  	18/9/94 Created
#

getuid()
{
 NEXT_UID=`sort -t: -n +2 -3 /etc/passwd | cut -d: -f3 | tail -1`
 NEXT_UID=`expr $NEXT_UID + 1`
}
getuid
echo $NEXT_UID
There is a problem with the above solution in how it picks the UID. The question asked for the next free UID but in most cases what you really want here is the next free UID between a certain upper and lower value. For example, on my machine aldur there is a predefined user nobody with a UID of 60000 so the above solution will return a number greater than that leaving about 59000 free UIDs below it. Also as mentioned in the section it is often a good idea to leave UIDs less than 100 to the system users. However on a number of systems there are not 100 system users to start with.

The following solution using awk includes a specification of a lower and upper bound for the UID.

#!/usr/local/bin/bash
#
# FILE:    	get_uid.awk
# PURPOSE:  	Using awk obtain the next free UID 
#			number from the /etc/passwd file
# AUTHOR:  	David Jones
# HISTORY: 	18/9/94 Created
#

# next uid must be > LOWER and < GREATER
LOWER_UID=100
UPPER_UID=60000

getuid()
{
  awk 'BEGIN  	{ 	FS=":"
             		UID=0 
				}
           { if (($3>UID) && ($3>'$LOWER_UID') && 
	      ($3<'$UPPER_UID'))
		   UID=$3 }
  END   { printf "%d\n", UID }' < /etc/passwd > /tmp/get_uid.$$

  NEXT_UID=`cat /tmp/get_uid.$$`
  NEXT_UID=`expr $NEXT_UID + 1`
  rm /tmp/get_uid.$$
}
getuid
echo this is it $NEXT_UID

6-7.
	#!/usr/local/bin/bash
	#
	# FILE:    	make_username
	# PURPOSE: 	Accept a firstname and a lastname as 
	#			parameters
	#      		Convert them into a username 
	#			consisting of the 
	#			first seven letters of the surname 
	#			and the first initial
	# AUTHOR:   	David Jones
	# HISTORY:  	18/9/94 Created
	#
	# check that we got everything
	if [ $# -ne 2 ]
	then
	  echo -n 'ERROR: expecting both firstname and '
	  echo 'lastname as parameters'
	  exit 1
	fi

	INITIAL=`echo $1 | cut -c1`
	REST=`echo $2 | cut -c1-7`

	username=$REST$INITIAL

Section 7


1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17
7-1. & 7-2. These two are up to you to explore on your system.
7-3. All terminals should be character devices.
7-4. In most cases you should find the device file for a terminal owned by the user that is logged into the terminal and they will have read/write access (for fairly obvious reasons). The group owner will typically be the group tty and the group will have write access.

Terminals not being used will have different permissions. The user becomes owner of the terminal during the login process


7-5. ls -l /dev > device.listing
or on some systems that have multiple sub-directories under /dev try
ls -lR /dev > device.listing
7-6. Deleting the device file associated with a current session will not affect the current session. However once logged out you will not be able to log back in on that same terminal. The operating system automatically runs a couple of processes (explained in a later section) which display the login: prompt. These process need to be able to access the device file for the terminal if they are to work.

Don't forget to use mknod to recreate the device file.


7-7. The manual pages for system calls are stored in section two of the manual. By typing man kill it will display the first manual page for something called kill. This will generally be the user command kill. User commands are stored in section one of the manual and are thus found first.

man 2 kill
Tells the system to display the manual page for kill that appears in section two of the manual.

Some systems display the user with a choice of all matching man pages. For example:

	bash$ man kill

	 1  kill(1)  kill - terminate a process by default
	 2  kill(2)  kill - send a signal to a process or a group of processes

	View which man page? (q to quit) [1]

7-8. This question entails (shock! horror!) some mathematics but it is fairly simple maths at that.

direct blocks = 10 * 512
single indirect = 256 * 512
double indirect = 256 * 256 * 512
triple indirect = 256 * 256 * 256 * 512

The actual total works out to be something in excess of 8 Gigabytes. This is a very large figure, larger than normal. Mainly because on a real system a 512 byte block is not going to be able to contain 256 block pointers. (Under System V a 1K block contains 256 block addresses).

If System V uses 1K blocks that can contain 256 block addresses and the i-node uses the above structure (10 direct blocks and a single, double, triple indirect block) what is the biggest size file System V can handle?


7-9. With a hard link you should see that the i-node numbers are exactly the same but the i-node numbers will differ with the soft link.
7-10. The permissions for a file are stored on the i-node. Since a hard link uses the same i-node as the file it points to if you change the protection on either you change the protection for both.
7-11. Since a soft link uses a different i-node changing the permissions on the link or the original file won't affect the other.
7-12.
	bash$ cd /
	bash$ ls -i
	 5422 Mail          159 home          163 proc         8795 UNIX
	   33 bin             3 lost+found    164 sbin          168 usr
	   34 dev           161 mnt           166 stand         287 var
	   48 etc           162 opt         11928 tmp
	bash$ ls -id /
	    2 /

7-13. Use the mount command without parameters to discover existing mounted file systems and examine the file /etc/fstab or /etc/vfstab to discover those that are mounted at startup. On some systems some file systems may be mounted automatically using individual mount commands in the systems startup scripts (talked about in a later section).
7-14. If you enter the command man mount and look at the files associated with this command (a section towards the end of the man page) you may find mention made of the fstab, vfstab, or other files your system uses.
7-15. Under Linux you might do the following
7-16. It may take a number of attempts to successfully ruin the floppy's file system.
7-17. You should now know that UNIX buffers information in memory before writing it to disk. Most UNIX operating systems also have a background process running that wakes up every 30 seconds or so and flushes the buffers (writing them all to disk). This process is usually called update, fsflush or sdflush (does it appear on your system?)

The command sync forces the buffers to be flushed straight away. One of the first things that happens when you use umount is that it flushes the buffers.


Section 8

1 / 2 / 3 / 4
8-1.
	bash$ cat > $HOME/tmp/temp.dat
	this is temp.dat
	
	bash$ tar cvf backup.tar $HOME

	tar is one command where the switches don't need the -.
8-2.
bash$ tar xvf backup.tar $HOME/tmp/temp.dat

The above may or may not work depending on whether or not the version of tar you are using automatically makes absolute path names into relative paths (by removing the first /). If it does it will not find any file in the archive starting with a / in the tape archive (which is what the extract command has told it to do). In that case you will have to repeat the command but put in the full relative path for the file you wish to extract.

You should be careful where the file you are attempting to extract will be placed. If you are extracting a using relative path the file will be placed relative to your current directory. If not it will be placed at the absolute location specified by the path.

8-3.
dd if=/dev/fd0 of=$HOME/floppy.file
You might change the floppy device file if you are using another device.
8-4.
	dd if=temp.tar.old | gzip - > temp.tar.gz

Section 9

1 / 2 / 3
9-1. & 9-2. For you to answer.

9-3.

One definition of a daemon is a process that has no controlling terminal (not a strictly correct definition). By default, most ps commands do not display all processes. To display all processes you generally have to use some command line arguments. These arguments will differ from system to system but -ax or -ae are good ones to start with. If these don't work examine the manual page for ps.

One of the columns displayed by ps will be the controlling terminal. For a process without a controlling terminal some systems will display ?. Working on this premise the following command may workps -ae | grep \?


Section 10

1 / 2 / 3 / 4 / 5 / 6 / 7
10-1. A task for you to perform.

10-2.

Those of you using the bash shell may have problems changing the keys for erase, though changing intr appears to work as expected (under bash). The following is an example of it done using the Bourne shell.
$ stty -a
line = NTTYDISC; speed 9600 baud
erase = DEL; kill = ^u; min = 6; time = 1; intr = ^c; quit = ^|; eof = ^d;
eol = ^`; start = ^q; stop = ^s;
parenb -parodd cs7 -cstopb -hupcl cread -clocal -loblk
-ignbrk brkint ignpar -parmrk inpck istrip -inlcr -igncr icrnl -iuclc
ixon -ixany -ixoff
isig icanon -xcase echo echoe echok -echonl -noflsh
opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel
$ stty erase \^i		change the erase character to control-i
$ stty -a
line = NTTYDISC; speed 9600 baud
erase = ^i; kill = ^u; min = 6; time = 1; intr = ^c; quit = ^|; eof = ^d;
eol = ^`; start = ^q; stop = ^s;
parenb -parodd cs7 -cstopb -hupcl cread -clocal -loblk
-ignbrk brkint ignpar -parmrk inpck istrip -inlcr -igncr icrnl -iuclc
ixon -ixany -ixoff
isig icanon -xcase echo echoe echok -echonl -noflsh
opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel
$ d^?^?^?			try to use the backspace key three times
d: not found
$ stty erase ^?			change erase back to the backspace key
10-3. This should cause no real problems and you should see how it changes the output of the commands.

10-4. Something for you to complete.

10-5. Much the same result can be achieved by changing your current terminal to something completely wrong. If your terminal is currently set up as a vt100 change it to a tvi912b and see how this affects the output of various commands.

10-6. The following is what happens on my system. The reason being is that vi has looked up the system's terminal configuration database looking for myterm. It hasn't found an entry so it doesn't know about any extended capabilities (like how to clear the screen, position a character at a specific location on the screen etc). It then defaults back to what it calls open mode which means no extended features (one line at a time much like ed).

	bash$ TERM=myterm
	bash$ vi /etc/passwd
	myterm: Unknown terminal type
	I don't know what kind of terminal you are on - all I have is 'myterm'.
	[Using open mode]
10-7. The following solution is for a system using terminfo. The solution for a system using termcap is to bring the /etc/termcap file into vi and then search for your terminal name (e.g. /vt100).
	bash$ echo $TERM
	vt100
	bash$ ls /usr/lib/terminfo/v/vt100
	/usr/lib/terminfo/v/vt100
	bash$ infocmp -C vt100
	#       Reconstructed via infocmp from file: /usr/share/lib/terminfo/v/vt100
	vt100|vt100-am|dec vt100 (w/advanced video):\
	        :am:mi:ms:xn:xo:bs:pt:\
	        :co#80:li#24:\
	        :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:as=^N:\
	        :cd=50\E[J:ce=3\E[K:cl=50\E[H\E[J:cm=5\E[%i%d;%dH:\
	        :cs=\E[%i%d;%dr:ct=\E[3g:ho=\E[H:k0=\EOy:k1=\EOP:\
	        :k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOt:k6=\EOu:k7=\EOv:\
	        :k8=\EOl:k9=\EOw:kb=\b:kd=\EOB:ke=\E[?1l\E>:kl=\EOD:\
	        :kr=\EOC:ks=\E[?1h\E=:ku=\EOA:nd=2\E[C:\
	        :r2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:rc=\E8:sc=\E7:\
	        :se=2\E[m:so=2\E[1;7m:sr=5\EM:st=\EH:ue=2\E[m:\
	        :up=2\E[A:us=2\E[4m:

Section 11

1 / 2
11-1. & 11-2. Both for you to answer on your system.

Section 12

1 / 2 / 3 / 4 / 5 / 6 / 7 / 8
12-1. If you receive a host not found message there are number of possible problems 12-2. Let's say the user type telnet sunsite.unc.edu 12-3. Use the command outlined in the section.

12-4.

	bash$ arp -a
	pol.cqu.EDU.AU (138.77.37.28) at aa:0:4:0:b:1c
	jasper.cqu.EDU.AU (138.77.1.1) at aa:0:4:0:b:1c
	bash$ ping bertha
	bertha.ucq.edu.au is alive
	bash$ arp -a
	pol.cqu.EDU.AU (138.77.37.28) at aa:0:4:0:b:1c
	bertha.cqu.EDU.AU (138.77.37.37) at aa:0:4:0:b:1c
	jasper.cqu.EDU.AU (138.77.1.1) at aa:0:4:0:b:1c
12-5. The standard daemons for smtp are usually smtpd or maybe smail (amongst others). They are typically started up in the systems startup files.

12-6.

	telnet jasper 21
	Trying 138.77.1.1...
	Connected to jasper.cqu.edu.au.
	Escape character is '^]'.
	220 jasper.cqu.edu.au FTP server....ready.
	help
	....list of valid commands
	user anonymous		log on as an anonymous user
	331 Guest login ok, send your complete e-mail ...
	pass david@pol		send my e-mail address as a password
12-7. Any number of uses of the netstat command will answer this. Try -s or refer to your systems manual pages.

12-8. Another for you to discover, try looking at the manual pages.


Section 13

1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9
13-1. Follow the instructions contained in the section.

13-2. The order of hostname and -l username can differ from system to system. On the machine aldur running SysV -l username comes first.

a) rsh jasper ls /etc
b) rsh jasper cat /etc/passwd > $HOME/passwd
c) ls | rsh jasper 'cat - listing'
d) rsh jasper tar cvf - > directory.tar
13-3.
a) This /etc/exports is invalid because the directory /usr/users is a sub-directory of /usr and is on the same device. This breaks the second rule outlined in the section.
b) Valid. (in very old versions of this question the file contained the directory /usr/local/temp which would make it invalid, but this directory has been removed from the question)
13-4. Try the command find / -name PUT_NAME_HERE -print

13-5. Most of these daemons will be started by the systems startup files.

13-6. Simplest method is to examine the output of an appropriate ps command and see if any of the daemons mentioned in the section are running. You can also look in the /etc/fstab, /etc/vfstab and /etc/exports files.

13-7. Follow the steps outlined in the section.

13-8. Performing a traceroute that passes through a large number of gateways increases the possibility of two different runs being different. The Internet has the ability to use different routes to get to the same destination.

13-9.

	a)	bash$ nslookup
		Default Server:  jasper.cqu.edu.au
		Address:  138.77.1.1

		> ls -a cqu.edu.au
		[jasper.cqu.edu.au]
		Host or domain name            Alias
		 mailroom                       janus.cqu.edu.au
		 library                        onyx.cqu.edu.au
		 civax                          topaz.cqu.edu.au
		 info                           janus.cqu.edu.au
		 cq-pan                         bertha.cqu.edu.au
		 www                            janus.cqu.edu.au
		 newsroom                       janus.cqu.edu.au
		 bindmaster                     jasper.cqu.edu.au

	b)	> ls -h cqu.edu.au > hosts
		[jasper.ucq.edu.au]
		##########
		Received 545 records.	looking at the file hosts revealed 136 hosts

	c)	> server cc.uq.oz.au
		Default Server:  cc.uq.oz.au
		Address:  130.102.128.5
		> www.cc.uq.oz.au
		Server:  cc.uq.oz.au
		Address:  130.102.128.5
		Name:    dingo.cc.uq.oz.au
		Address:  130.102.2.14
		Aliases:  www.cc.uq.oz.au

Section 14

1 / 2 / 3 / 4 / 5 / 6 / 7
14-1.
#!/usr/local/bin/bash
#
# FILE:         passwdck
# PURPOSE:      Perform the following checks on the /etc/passwd file
#               *  that all accounts have passwords
#               *  that all accounts have usernames
#               *  only the account root has uid of 0
#               *  only the proper accounts have gid of 0
#               *  only additions performed by Sys Admin have been 
#                  made. Keeps a copy of /etc/passwd in a protected 
#                  file $ROOTDIR/.old.passwd
#               *  file permissions on /etc/passwd haven't been 
#                  altered
# AUTHOR:       David Jones
# HISTORY:      2/9/94 Created
#

PASSWORD_FILE='/etc/passwd' # file containing encrypted passwords
PERMISSIONS="-r--r--r--"    # permissions for /etc/passwd file
ROOTDIR=/root               # directory in which .old.password is stored

# Check that all accounts have passwords
awk -F- '{ FS=":" }
         {
           if ( $2=="" )
             printf "passwdck: ERROR user %s has no password\n", $1
         }' < $PASSWORD_FILE

# display user ids for accounts without usernames
# display usernames of accounts other than system accounts with uids of 0
awk '{ FS=":" }
     {
       if ( $1=="" )
         printf "passwdck: ERROR userid %s has no username\n", $3

       if ( $3=="0" && $1!="root" && $1!="setup" && $1!="powerdown" &&
            $1!="sysadm" && $1!="checkfsys" && $1!="makefsys" &&
            $1!="mountfsys" && $1!="umountfsys" )
         printf "passwdck: ERROR user %s has uid of 0\n", $1
     }'< /etc/passwd

# check for changes in the password file
diff /etc/passwd $ROOTDIR/.old.password > /dev/null

if [ $? -ne 0 ]
then
  echo passwdck: ERROR $PASSWORD_FILE has been illegally changed.
  RETURN=1
fi

# check on the permissions for the passwd file
if [ ! "`ls -l /etc/passwd | cut -d' ' -f1`" = $PERMISSIONS ]
then
  echo passwdck: ERROR illegal permissions on /etc/passwd
fi
14-2. The following is a very coarse grained answer to the question.
#!/usr/local/bin/bash
#
# FILE:         fs_check
# PURPOSE:      Perform the following checks on the security of the 
#               filesystem
# AUTHOR:       David Jones
# HISTORY:      2/9/94 Created
#

ROOTDIR=/root               # directory in which summary files are kept

# directories or files to be checked could be placed into a specific file
DIRECTORIES='/dev/hda* /etc/passwd'

# create filename for new summary file
# FORMAT is $ROOTDIR/summary."todays_date"
SUMMARY_FILE="$ROOTDIR/summary.`date | cut -d: -f1 | tr ' ' _`"

# move previous summary file
mv $ROOTDIR/summary* $ROOTDIR/old.summary

for directory_name in $DIRECTORIES
do
  ls -lR $directory_name >> $SUMMARY_FILE
done

diff $ROOTDIR/old.summary $SUMMARY_FILE
14-3. The main difference is the addition of the s in the executable fields for the owner and the group. This means that the passwd program is both setuid and setgid.
	# which passwd
	/usr/bin/passwd
	# ls -l /usr/bin/passwd
	-r-sr-sr-x   1 root     sys        20240 Nov 23  1991 /usr/bin/passwd
14-4. Methods exist using symbolic and numeric permissions
	chmod 4??? filename	set uid
	chmod 2??? filename	set gid
	Where ??? is replaced with the normal numeric permissions and 
	filename is the name of the file
	chmod u+s filename	set uid
	chmod g+s filename	set gid
14-5.
	bash$ i_am
	The real uid is 201
	The effective uid is 201
	The real gid is 1
	The effective gid is 1

	# chown root i_am
	# chmod u+s i_am
	# ls -l i_am
	total 80
	-rwsr-xr-x 1 root  other   5600 Oct  2 19:47 i_am

	bash$ i_am
	The real uid is 201
	The effective uid is 0
	The real gid is 1
	The effective gid is 1
14-6.
	# chgrp root i_am
	# ls -l i_am
	# chmod g+s i_am
	total 80
	-rwsr-sr-x 1 root  root   5600 Oct  2 19:47 i_am

	bash$ i_am
	The real uid is 201
	The effective uid is 0
	The real gid is 1
	The effective gid is 0
14-7. The find command has a switch that can very easily find all the setuid and setgid programs. Add the following to the fs_check program just before the diff command.
	find / -perm -4000 -print >> $SUMMARY_FILE
	find / -perm -2000 -print >> $SUMMARY_FILE

Section 15

1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9
15-1. The type of things you'll find in the kernel include device drivers, network code, memory management code, process management code, inter-process communication code, code to boot the system, file system code (for all the various file systems), character and block I/O code etc.

Many systems will divide the different sections into separate directories.

15-2. The following command will give a good indication though it is probably going to pick up a number of object files in addition.

	pol:/usr/src/linux# find . -name \* -print | wc -w
	   1108
	pol:/usr/src/linux#
15-3. On this particular system the MANPATH variable wasn't set but examining the manual page for the man command revealed that the manual pages (in one format) were stored in the directory /var/share/catman. Under this directory there were a number of directories corresponding to the various different sections of the manual.

Taking a listing of the contents of the correct directory gives a list of the system calls that are documented in the manual pages.

bash$ ls /var/share/catman/2
access.Z       getgroups.Z    msgop.Z        setpgid.Z      sys3b.Z
acct.Z         getmsg.Z       munmap.Z       setpgrp.Z      sysfs.Z
adjtime.Z      getpid.Z       nice.Z         setsid.Z       sysinfo.Z
alarm.Z        getrlimit.Z    open.Z         setuid.Z       termios.Z
brk.Z          getsid.Z       pause.Z        shmctl.Z       time.Z
chdir.Z        getuid.Z       pipe.Z         shmget.Z       times.Z
chmod.Z        intro.Z        plock.Z        shmop.Z        uadmin.Z
chown.Z        ioctl.Z        poll.Z         sigaction.Z    ulimit.Z
chroot.Z       kill.Z         priocntl.Z     sigaltstack.Z  umask.Z
close.Z        link.Z         priocntlset.Z  signal.Z       umount.Z
creat.Z        lseek.Z        profil.Z       sigpending.Z   uname.Z
dup.Z          memcntl.Z      ptrace.Z       sigprocmask.Z  unlink.Z
exec.Z         mincore.Z      putmsg.Z       sigsend.Z      ustat.Z
exit.Z         mkdir.Z        read.Z         sigsuspend.Z   utime.Z
fcntl.Z        mknod.Z        readlink.Z     stat.Z         vfork.Z
fork.Z         mmap.Z         rename.Z       statvfs.Z      wait.Z
fpathconf.Z    mount.Z        rmdir.Z        stime.Z        waitid.Z
fsync.Z        mprotect.Z     semctl.Z       swapctl.Z      waitpid.Z
getcontext.Z   msgctl.Z       semget.Z       symlink.Z      write.Z
getdents.Z     msgget.Z       semop.Z        sync.Z
15-4. to 15-6. Both are system specific tasks read your manual pages.

15-7.

	diff abc.doc def.doc > patch.file
	patch abc.doc < patch.file > newabc.doc
15-8. & 15-9. The process here will depend on your system.

Section 16

1 / 2 / 3 / 4 / 5 / 6 / 7 / 8
16-1. Questions for you to answer for your particular system. 16-2.
a) 0 5 * * * rm /tmp/*
b) No time specified so we'll stay with 5 am. (Sunday is 0 on this system)
0 5 * * 3 /root/weekly.job
c) 0 15,18,21 1-5 * * /root/summary
16-3. Again some questions for you to answer for your system.

16-4.

	0 7 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30 * *
	 /root/passwdck | mail root

	On some systems the redirection to the mail command is not necessary
	as the system automatically sends output of commands run by cron as mail.
16-5. & 16-6. Again questions for you to answer on your system but you should be able to follow the steps in the section and the documentation for you system.

16-7. Simply cat /etc/syslog.conf

16-8. *.emerg /dev/console

David Jones (author)
Chris Hanson (html 11/09/96)