As desirable as enforcing file access permissions are on a Linux system, there are valid reasons for needing to bypass the checking. Several users run the same program to generate project files that must be accessible to all; a printer queue is hung and the sysadmin has given a local user authority to restart the printer daemon; an ordinary user wants to mount an NFS hierarchy from a file server; a mail delivery program must be able to write into mail files writable only by the mail recipient; and finally, a local user is empowered to perform designated sysadmin functions but the real sysadmin does not want to grant blanket permission to alter everything on the system.
Below we will look at common methods of working around the Linux file access permissions scheme and point out some short-comings of each technique. All these methods "work", in the sense that they function correctly but incur unnecessary security risks. In the next section, we show how sudo(8) controls most of these risks.
One technique, used since UNIX™ systems began, is for the user to temporarily assume the privileges of the superuser account. The su(1) changes the identification for the current user by substituting user credentials.
$ id uid=500(reynolds) gid=500(reynolds) groups=500(reynolds) $ su -c id Password: uid=0(root) gid=0(root) groups=0(root),1(bin)...
Example 3. Traditional Approach Using su(1)
There are some problems with this approach:
The superuser password is compromised.
Once anyone other than the system administrator knows the superuser password, everyone will know it. He that wishes to keep a secret must keep it a secret that he has a secret to keep. Promises not to tell are not sufficient security.
There is no audit trail.
With a superuser shell, a user can do anything that the root account can do. We must trust[4]the user to access only the files and programs they claimed to need.
Another technology, used by the su(1) program, takes advantage of a neat feature.
Normally, the files accessible to an application or shell depend on who is executing that program. Recall those credentials mentioned earlier? An application executes using the credentials of the user who runs the program.
Stop, wait, there's more!
Files have access permissions but since a program is stored in a file, the program has file access permissions, too.
By setting a special flag, called the set user id
bit or setuid(2)
, we can cause the
system to check "credentials" made from the program file
access permissions, instead of using the credentials for the user
running the application[5].
This ability to use the credentials of an application, instead of those of the user, can be a great boon to multiuser applications such as databases or email delivery agents. The feature has its proper use on a Linux system.
As useful as it is, one must resist the temptation to make a shell
program, such as /bin/bash
, or a shell script, such
as /usr/local/bin/run_as_root
, be set user ID to
root.
If this were to be done, then any user running that script or application would be able to access any file that the root account could access.
Again, the objections to this method a similar to those we mentioned for the su(1) program: no control, and no traceability.