mirror of https://github.com/tLDP/LDP
506 lines
19 KiB
XML
506 lines
19 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<chapter id="phase6">
|
|
<title>Enabling Multiple Users</title>
|
|
|
|
<sect1>
|
|
<title>Analysis</title>
|
|
|
|
<para>Up to now the system has been operating in single-user mode. There
|
|
is no login process and anyone who boots the system goes straight into a
|
|
shell with root privileges. Obviously, this is not the normal operating
|
|
mode for most GNU/Linux distributions. Most systems feature multi-user
|
|
capability where many users can access the system simultaneously with
|
|
different privilege levels. These multi-user systems also support virtual
|
|
consoles so that the keyboard and video display can be multiplexed between
|
|
several terminal sessions. So in this phase we would like to add the
|
|
following enhancements to the system:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Enable multi-user capability.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Create multiple, virtual consoles.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
<sect1>
|
|
<title>Design</title>
|
|
|
|
<sect2>
|
|
<title>The login process</title>
|
|
|
|
<para>The From-Powerup-To-BASH-Prompt-HOWTO does a good job of outlining
|
|
the steps in the login process. Basically it works like this.</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>The <command>init</command> daemon starts a
|
|
<command>getty</command> process on the terminal.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The <command>getty</command> program displays the contents of
|
|
<filename>/etc/issue</filename> and prompts for a user name.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>When the user name is entered, control is handed off to the
|
|
<command>login</command> program.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The <command>login</command> program asks for a password and
|
|
verifies the credentials using <filename>/etc/passwd</filename>,
|
|
<filename>/etc/group</filename> and possibly
|
|
<filename>/etc/shadow</filename>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>If everything is okay the user's shell is started.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Obtaining source code</title>
|
|
|
|
<para>The <command>getty</command> and <command>login</command> programs
|
|
were already installed as part of the util-linux package so there is no
|
|
need to download any new source code.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Creating support files</title>
|
|
|
|
<sect3>
|
|
<title>Device nodes</title>
|
|
|
|
<para>Details about virtual console device files can be found in the
|
|
Linux kernel source code file called <filename>devices.txt</filename>
|
|
in the <filename>Documentation</filename> directory. We will need to
|
|
create <filename>tty1</filename> through <filename>tty6</filename> for
|
|
each of the virtual consoles as well as <filename>tty0</filename> and
|
|
<filename>tty</filename> to represent the current virtual
|
|
console.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>/etc/issue</title>
|
|
|
|
<para>The <filename>/etc/issue</filename> file is pretty easy to
|
|
construct. It can contain any text we want displayed on the screen
|
|
prior to the login prompt. It could be something friendly like
|
|
"Welcome to Pocket Linux", something menacing like "Authorized users
|
|
only!" or something informational like "Connected to tty1 at 9600bps".
|
|
The agetty(8) manpage explains how to display information like tty
|
|
line and baud rate using escape codes.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>/etc/passwd</title>
|
|
|
|
<para>The format of <filename>/etc/passwd</filename> can be obtained
|
|
by reading the passwd(5) manpage. We can easily create a user account
|
|
by adding a line like "root::0:0:superuser:/root:/bin/sh" to the
|
|
file.</para>
|
|
|
|
<para>Maintaining passwords will be somewhat challenging because of
|
|
the system being loaded into ramdisk. Any changes to
|
|
<filename>/etc/passwd</filename> will be lost when the system is
|
|
shutdown. So to make things easy, we will create all users with null
|
|
passwords.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>/etc/group</title>
|
|
|
|
<para>The structure of <filename>/etc/group</filename> is available
|
|
from the group(5) manpage. A line of "root::0:root" would define a
|
|
group called "root" with no password, a group id of zero and the user
|
|
root assigned to it as the only member.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>Conventions</title>
|
|
|
|
<para>User and group names and id's are generally not chosen at
|
|
random. Most Linux systems have very similar looking
|
|
<filename>/etc/passwd</filename> and <filename>/etc/group</filename>
|
|
files. Definitions for commonly used user id and group id assignments
|
|
may be found in one of several places:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>The <filename>/etc/passwd</filename> and
|
|
<filename>/etc/group</filename> files on any popular GNU/Linux
|
|
distribution.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The Debian Policy Manual -- available online at <ulink
|
|
url="http://www.debian.org/doc/debian-policy">http://www.debian.org/doc/debian-policy</ulink>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The Linux Standard Base specification -- downloadable in
|
|
many formats from <ulink
|
|
url="http://www.linuxbase.org/spec/index.shtml">http://www.linuxbase.org/spec/index.shtml</ulink>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Essential System Administration, 3rd Edition by Aeleen
|
|
Frisch -- available at libraries, bookstores or directly from
|
|
O'Reilly Publishing at <ulink
|
|
url="http://www.oreilly.com/">http://www.oreilly.com/</ulink>.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Dependencies</title>
|
|
|
|
<para>Running <command>ldd</command> on the <filename>login</filename>
|
|
program from util-linux will reveal that it is linked to the libraries
|
|
<filename>libcrypt.so.1</filename>, <filename>libc.so.6</filename> and
|
|
<filename>ld-linux.so.2</filename>. In addition to these libraries there
|
|
is another, unseen dependency on <filename>libnss_files.so.2</filename>
|
|
and the configuration file
|
|
<filename>/etc/nsswitch.conf</filename>.</para>
|
|
|
|
<para>The name service switch library
|
|
<filename>libnss_files.so.2</filename> and
|
|
<filename>nsswitch.conf</filename> are required for
|
|
<filename>libc.so.6</filename>, and consequently the
|
|
<filename>login</filename> program, to access the
|
|
<filename>/etc/passwd</filename> file. Without libnss and its
|
|
configuration file, all logins will mysteriously fail. More information
|
|
about glibc's use of the name service switch libraries can be found at
|
|
<ulink
|
|
url="http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html">http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html</ulink>.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Assigning ownership and permissions</title>
|
|
|
|
<para>Previously, with the single user system, there was no need to
|
|
worry about permissions when installing directories, files and device
|
|
nodes. The shell was effectively operating as root, so everything was
|
|
accessible. Things become more complex with the addition of multiple
|
|
user capability. Now we need to make sure that every user has access to
|
|
what they need and at the same time gets blocked from what they do not
|
|
need.</para>
|
|
|
|
<para>A good guideline for assigning ownership and permissions would be
|
|
to give the minimum level of access required. Take the
|
|
<filename>/bin</filename> directory as an example. The Filesystem
|
|
Hierarchy (FHS) document says, "<filename>/bin</filename> contains
|
|
commands that may be used by both the system administrator and by
|
|
users". From that statement we can infer that <filename>/bin</filename>
|
|
should have read and execute permission for everyone. On the other hand,
|
|
the <filename>/boot</filename> directory contains files for the boot
|
|
loader. Chances are good that regular users will not need to access
|
|
anything in the <filename>/boot</filename> directory. So the minimum
|
|
level of access would be read permission for the root user and other
|
|
administrators who are members of the root group. Normal users would
|
|
have no permissions assigned on the <filename>/boot</filename>
|
|
directory.</para>
|
|
|
|
<para>Most of the time we can assign similar permissions to all the
|
|
commands in a directory, but there are some programs that prove to be
|
|
exceptions to the rule. The <command>su</command> command is a good
|
|
example. Other commands in the /bin directory have a minimum requirement
|
|
of read and execute, but the <command>su</command> command needs to be
|
|
setuid root in order to run correctly. Since it is a setuid binary, it
|
|
might not be a good idea to allow just anyone to run it. Ownership of
|
|
0:0 (root user, root group) and permissions of rwsr-x--- (octal 4750)
|
|
would be a good fit for <command>su</command>.</para>
|
|
|
|
<para>The same logic can be applied to other directories and files in
|
|
the root filesystem using the following steps:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>Assign ownership to the root user and root group.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Set the most restrictive permissions possible.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Adjust ownership and permissions on an "as needed"
|
|
basis.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1>
|
|
<title>Construction</title>
|
|
|
|
<sect2>
|
|
<title>Verify presence of getty and login</title>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> ls ~/staging/sbin/getty
|
|
<prompt>bash#</prompt> ls ~/staging/bin/login</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Modify inittab for multi-user mode</title>
|
|
|
|
<para>Modify <filename>~/staging/etc/inittab</filename> by changing the
|
|
default runlevel and adding <command>getty</command> entries as shown
|
|
below.</para>
|
|
|
|
<para><programlisting># /etc/inittab - init daemon configuration file
|
|
#
|
|
# Default runlevel
|
|
id:2:initdefault:
|
|
#
|
|
# System initialization
|
|
si:S:sysinit:/etc/init.d/rc S
|
|
#
|
|
# Runlevel scripts
|
|
r0:0:wait:/etc/init.d/rc 0
|
|
r1:1:respawn:/bin/sh
|
|
r2:2:wait:/etc/init.d/rc 2
|
|
r3:3:wait:/etc/init.d/rc 3
|
|
r4:4:wait:/etc/init.d/rc 4
|
|
r5:5:wait:/etc/init.d/rc 5
|
|
r6:6:wait:/etc/init.d/rc 6
|
|
#
|
|
# Spawn virtual terminals
|
|
1:235:respawn:/sbin/getty 38400 tty1 linux
|
|
2:235:respawn:/sbin/getty 38400 tty2 linux
|
|
3:235:respawn:/sbin/getty 38400 tty3 linux
|
|
4:235:respawn:/sbin/getty 38400 tty4 linux
|
|
5:235:respawn:/sbin/getty 38400 tty5 linux
|
|
6:2345:respawn:/sbin/getty 38400 tty6 linux
|
|
#
|
|
# end of /etc/inittab</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Create tty devices</title>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> cd ~/staging/dev
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty0 c 4 0
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty1 c 4 1
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty2 c 4 2
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty3 c 4 3
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty4 c 4 4
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty5 c 4 5
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty6 c 4 6
|
|
<prompt>bash#</prompt> mknod ~/staging/dev/tty c 5 0</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Create support files in /etc</title>
|
|
|
|
<sect3>
|
|
<title>/etc/issue</title>
|
|
|
|
<para>Create the file <filename>~/staging/etc/issue</filename> using
|
|
the example below or design a customized message.</para>
|
|
|
|
<para><programlisting>Connected to \l at \b bps.</programlisting></para>
|
|
|
|
<para>Be sure that "\l" is a lowercase letter L and not the number
|
|
one.</para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>/etc/passwd</title>
|
|
|
|
<para>Use a text editor to create a minimal passwd file conforming to
|
|
the Linux Standards Base (LSB) document. Save the file as
|
|
<filename>~/staging/etc/passwd</filename></para>
|
|
|
|
<para><programlisting>root::0:0:Super User:/root:/bin/sh
|
|
bin:x:1:1:Legacy UID:/bin:/bin/false
|
|
daemon:x:2:2:Legacy UID:/sbin:/bin/false</programlisting></para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>/etc/group</title>
|
|
|
|
<para>Use a text editor to create an LSB conforming group file and
|
|
save it as <filename>~/staging/etc/group</filename></para>
|
|
|
|
<para><programlisting>root::0:root
|
|
bin:x:1:root,bin,daemon
|
|
daemon:x:2:root,bin,daemon</programlisting></para>
|
|
</sect3>
|
|
|
|
<sect3>
|
|
<title>/etc/nsswitch.conf</title>
|
|
|
|
<para>Create the following file and save it as
|
|
<filename>~/staging/etc/nsswitch.conf</filename></para>
|
|
|
|
<para><programlisting>passwd: files
|
|
group: files</programlisting></para>
|
|
</sect3>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Copy required libraries</title>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> cp /lib/libnss_files.so.2 ~/staging/lib
|
|
bash# strip --strip-unneeded ~/staging/lib/*</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Set directory and file permissions</title>
|
|
|
|
<para>Set minimal privileges on all files and directories under
|
|
<filename>~/staging</filename>. Everything is owned by the root user and
|
|
the root group. Permissions are read-write for the owner and read-only
|
|
for the group. Exceptions to the blanket permissions are handled case by
|
|
case.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> cd ~/staging
|
|
<prompt>bash#</prompt> chown -R 0:0 ~/staging/*
|
|
<prompt>bash#</prompt> chmod -R 640 ~/staging/*</programlisting></para>
|
|
|
|
<para>Set execute permission on all directories. (Note the capital
|
|
"X")</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod -R +X ~/staging/*</programlisting></para>
|
|
|
|
<para>Files in <filename>/bin</filename> are read and execute for all,
|
|
but <filename>su</filename> is an exception.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 755 ~/staging/bin/*
|
|
<prompt>bash#</prompt> chmod 4750 ~/staging/bin/su</programlisting></para>
|
|
|
|
<para>Files in <filename>/dev</filename> have various permissions. Disk
|
|
devices should be accessible to administrators only. Other files like
|
|
<filename>/dev/null</filename> should have full privileges granted to
|
|
everyone.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 660 ~/staging/dev/fd0 dev/ram0
|
|
<prompt>bash#</prompt> chmod 666 ~/staging/dev/null
|
|
<prompt>bash#</prompt> chmod 622 ~/staging/dev/console
|
|
<prompt>bash#</prompt> chmod 600 ~/staging/dev/initctl
|
|
<prompt>bash#</prompt> chmod 622 ~/staging/dev/tty
|
|
<prompt>bash#</prompt> chmod 622 ~/staging/dev/tty?</programlisting></para>
|
|
|
|
<para>The <filename>passwd</filename> and <filename>group</filename>
|
|
files must be world readable.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 644 ~/staging/etc/passwd
|
|
<prompt>bash#</prompt> chmod 644 ~/staging/etc/group</programlisting></para>
|
|
|
|
<para>The scripts in <filename>/etc/init.d</filename> are read and
|
|
execute for administrators.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 750 ~/staging/etc/init.d/*</programlisting></para>
|
|
|
|
<para>Libraries need read and execute permissions for everyone.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 755 ~/staging/lib/*</programlisting></para>
|
|
|
|
<para>Only root should have access to the <filename>/root</filename>
|
|
directory.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 700 ~/staging/root</programlisting></para>
|
|
|
|
<para>Make files in <filename>/sbin</filename> read and execute for
|
|
administrators.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 750 ~/staging/sbin/*</programlisting></para>
|
|
|
|
<para>Temp should be read-write for all with the sticky bit set.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> chmod 1777 ~/staging/tmp</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Create the root disk image</title>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> cd /
|
|
<prompt>bash#</prompt> dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
|
|
<prompt>bash#</prompt> mke2fs -m0 /dev/ram7 4096
|
|
<prompt>bash#</prompt> mount /dev/ram7 /mnt
|
|
<prompt>bash#</prompt> cp -dpR ~/staging/* /mnt
|
|
<prompt>bash#</prompt> umount /dev/ram7
|
|
<prompt>bash#</prompt> dd if=/dev/ram7 of=~/phase6-image bs=1k count=4096
|
|
<prompt>bash#</prompt> gzip -9 ~/phase6-image</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Copy the image to diskette</title>
|
|
|
|
<para>Insert the diskette labeled "root disk" into drive fd0.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> dd if=~/phase6-image.gz of=/dev/fd0 bs=1k</programlisting></para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1>
|
|
<title>Implementation</title>
|
|
|
|
<sect2>
|
|
<title>System Startup</title>
|
|
|
|
<para>If everything goes well, the virtual console display should look
|
|
similar to the following example:</para>
|
|
|
|
<para><screen>Connected to tty1 at 38400 bps.
|
|
gnu-linux login:</screen></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Add a new user to the system</title>
|
|
|
|
<para>Log in as root.</para>
|
|
|
|
<para>Create a new, unprivileged user and new group by appending a line
|
|
to the <filename>/etc/passwd</filename> and
|
|
<filename>/etc/group</filename> files, respectively. Be sure to use a
|
|
double greater-than (>>) to avoid accidentally overwriting the
|
|
files.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> echo "floyd::501:500:User:/home/floyd:/bin/sh" >>/etc/passwd
|
|
<prompt>bash#</prompt> echo "users::500:" >>/etc/group
|
|
<prompt>bash#</prompt> mkdir /home/floyd
|
|
<prompt>bash#</prompt> chown floyd.users /home/floyd
|
|
<prompt>bash#</prompt> chmod 700 /home/floyd</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Test the new user's ability to use the system</title>
|
|
|
|
<para>Switch to virtual terminal tty2 by pressing
|
|
<keycap>ALT</keycap>+<keycap>F2</keycap>.</para>
|
|
|
|
<para>Log in as floyd.</para>
|
|
|
|
<para>Try the following commands and verify that they work.</para>
|
|
|
|
<para><programlisting><prompt>bash$</prompt> pwd
|
|
<prompt>bash$</prompt> ls -l /
|
|
<prompt>bash$</prompt> cat /etc/passwd</programlisting></para>
|
|
|
|
<para>Try the following commands and verify that they do not
|
|
work.</para>
|
|
|
|
<para><programlisting><prompt>bash$</prompt> ls /root
|
|
<prompt>bash$</prompt> /sbin/shutdown -h now
|
|
<prompt>bash$</prompt> su -</programlisting></para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>System shutdown</title>
|
|
|
|
<para>Switch back to tty1 where root is logged in.</para>
|
|
|
|
<para><programlisting><prompt>bash#</prompt> shutdown -h now</programlisting></para>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter> |