exploring the users "as whom" processes operate


The exercise to perform

Log in as root via ssh. Since you'll log in more than once, we'll name this "terminal 1" to distinguish it from the subsequent login terminals you'll get. Create new user accounts "tom" "dick" and "harry" having "password" as their password. Create tom for example, by:

useradd tom
passwd tom

(If the useradd command informs you the user already exists, that's fine just set the password.) Get the following files into your current directory:

  fork9a.c
  ids.c

Get them from the source indicated by your instructor.

Examine the source code for both. fork9a.c is a super-simple shell that asks the user for a command, then fork/exec's it. ids.c shows how to get the real and effective user id's for a process and print them. Also, whenever it runs it first prints on screen what user is running it. 

Compile these:

  gcc  fork9a.c  -o  dshell
  gcc  ids.c  -o  ids

Make sure the resulting binaries are world-executable:

  chmod  o+x dshell  ids

and copy them into /usr/local/bin, where they will be accessible to other users:

cp  dshell  /usr/local/bin
cp  ids  /usr/local/bin

Login a second time via ssh, this time as user tom. We'll dub the resulting terminal "terminal 2." In this terminal too a shell is running, offering a command prompt. This shell process must have a PID (process id number) and an associated user. Use the ps command to reveal information about tom's shell:

  ps -ef       (if the information scrolls off the screen,  "ps -ef | more" will contain it one screenful at a time)

The name of the usual shell program, which should appear in the output, is "bash." From the output 1) verify tom is the user for this process, 2) identify the terminal with which it is associated for output purposes (might be something like pts/2), 3) identify and write down its PID.

Login a third time via ssh, this time as user dick. We'll call his terminal "terminal 3." It too holds a running shell. Use the ps command to reveal information about dick's shell:

  ps -ef

From the output 1) verify dick is the user for this process, 2) verify it is associated with terminal 3 (maybe pts/3), 3) identify and write down its PID. Note that tom's earlier bash process is still visible, along with dick's.

Construct a process family tree. Have dick run:

  ps  -ef  --header  |  less

You will see (scroll to the bottom of the output) 4 processes by dick and 2 by tom. For each, write its PID and the command/program of which it is an instance. Note that not only the PID but also the PPID (parent process' s id) is shown. Using that, find the parent processes for each of tom's and dick's processes, and then the parent process for each of those. Trace the process genaeology back to the common, first process. What is that "original" process in linux called? Write a process genaeology family tree:

Each box represents a process. In each box write 1) the PID, 2) the command that the process is running, 3) the name of the user as whom it's doing so. When finished, look at a similar representation of the same information by having root run the following command in his terminal 1:

  pstree  -pu

Study the pstree information in terminal 1 and the ps information in terminal 3 side by-side. Understand the mechanism they depict of successive process launches and consequent parent-child relationships, user identities that inhere to each process, and inheritance of those identities by default. Note the exceptions to that default, where a child does not have the same UID as its parent. When finished quit out of "less" (lowercase q keystroke).


Become tom, by going to terminal 2 where tom is running a shell. There, run dshell. From within dshell, run /usr/local/bin/ids.
Become dick, by going to terminal 3 where dick is running a shell. There, run dshell. From within dshell, run /usr/local/bin/ids.

When "dshell" shows you its process user ids (real and effective), where did they come from? That is, if they're 505, why 505? When "ids" shows you its process user ids, where did it get them (same question)? The process user ids of a process derive from where?

Using the su command

As dick, terminate dshell (ctrl-C). Rerun it, but this time run it through the "su" command which lets you determine a user id for the process other than your own. Run dshell as follows:

  su tom -c dshell

(you will have to give tom's password). Again run /usr/local/bin/ids from within dshell and pay attention to the user ids shown. Now terminate dshell running by dick but as tom, and run it by dick as root:

  su -c dshell

If you omit a user specification, "root" is the user as whom the command will be run by default. Again run /usr/local/bin/ids from within dshell and pay attention to the user ids shown. Now terminate dshell running by disk but as root. Run simply:

  su

If you omit the program specification, bash is the program that will be run by default. The result is a "root shell." After observing the root shell by giving the root user's password, return to dick's shell by "exit"ing.

Using the SUID permission on executable files

Return to terminal 1 where the shell is running as root. Execute the following:

  ls  -l  /usr/local/bin/ids
  chown  harry  /usr/local/bin/ids
  chmod  +s  /usr/local/bin/ids
  ls  -l  /usr/local/bin/ids

Return to terminal 3 where the shell is running as dick. Execute:

  ids

Note the difference between the real and effective user ids reported. /usr/local/bin/ids is said to be "set UID" to its owner, and its owner is harry.

Using sudo

As root, start a few "sleep" processes in the background and then observe their presence:

sleep 1000 &
sleep 2000 &
sleep 3000 &
ps -ef
jobs

Switch to terminal 2 in order to be tom. There, try to kill the sleep processes that user root just started:

killall sleep

It didn't work. Try it another way, through sudo:

sudo killall sleep

Give tom's password when prompted. Still didn't work. It needs to be configured in order to work. Switch back to terminal 1 in order to be root. There, add the following line to the file /etc/sudoers:

tom  ALL=(root)  /usr/bin/killall  sleep

You can add this line using an editor, like vi. If you don't know how to use the rather unwieldy vi, this command will append the line:

echo "tom  ALL=(root)  /usr/bin/killall  sleep"  >>  /etc/sudoers

Return to terminal 2 and again as tom try:

sudo killall sleep

When prompted for a password, give tom's not root's. Return to terminal 1 and as root:

jobs

Where are the sleep processes? Did it work?

When finished be sure to go to each of your 3 terminals and log out:

exit

 

Questions:

1. In the above process diagram you found there are 2 parent-child pairs in which the child has a UID that isn't the same as the parent's. One of them appears in this list. Which one is it?
 a. a-b
 b. b-c
 c. d-f
 d. f-h
 e. e-g

2. In box h of the diagram what is the command you wrote?
 a. su           
 b. ps
 c. ssh
 d. bash
 e. less

3. In box h of the diagram what is the username you wrote?
 a. tom          
 b. dick
 c. harry
 d. root