<?xml version="1.0" standalone="no"?>

<!--
  OpenAFS 1.4.x installation guide on Debian GNU

  http://techpubs.spinlocksolutions.com/dklar/afs.xml
  http://techpubs.spinlocksolutions.com/dklar/afs.html
  http://techpubs.spinlocksolutions.com/dklar/afs.tgz

  (C) 2008-2010 Davor Ocelic, docelic@spinlocksolutions.com

  SPINLOCK, http://www.spinlocksolutions.com/ - advanced
  infrastructure-based Unix solutions for commercial and
  education sectors.


 This documentation is free; you can redistribute it and/or modify
 it under the terms of the &GNU; General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 It is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.


  To build the HTML version of the article, download
  http://techpubs.spinlocksolutions.com/dklar/afs.tgz , 
  save the following as Makefile and run 'make afs.html':

%.html: %.xml
	xsltproc -o $@ \
	-stringparam html.stylesheet DKLAR.css \
	/usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl $<

-->

<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
	"docbook/docbookx.dtd"[ 

	<!ENTITY DEB "<ulink url='http://www.debian.org/'>Debian GNU</ulink>">
	<!ENTITY GNU "<ulink url='http://www.gnu.org/'>GNU</ulink>">
	<!ENTITY KRB "<ulink url='http://web.mit.edu/kerberos/'>MIT Kerberos</ulink>">
	<!ENTITY LDA "<ulink url='http://www.openldap.org/'>OpenLDAP</ulink>">
	<!ENTITY AFS "<ulink url='http://www.openafs.org/'>OpenAFS</ulink>">
	<!ENTITY MLS "<ulink url='https://lists.openafs.org/mailman/listinfo/'>https://lists.openafs.org/mailman/listinfo</ulink>">
	<!ENTITY DOC "<ulink url='http://docs.openafs.org/'>http://docs.openafs.org/</ulink>">
	<!ENTITY ARL "<ulink url='http://www.stacken.kth.se/project/arla/'>Arla - alternative AFS client</ulink>">
	<!ENTITY GCO "<ulink url='http://www.central.org/'>GRAND.CENTRAL.ORG - community resource for users of the AFS distributed file system</ulink>">
	<!ENTITY RAD "<ulink url='http://www.freeradius.org/'>FreeRADIUS</ulink>">
	<!ENTITY DLH "<ulink url='http://colt.projectgamma.com/debian-ldap-howto/'>Debian-LDAP Howto</ulink>">
	<!ENTITY PAM "<ulink url='http://www.kernel.org/pub/linux/libs/pam/'>Linux-PAM</ulink>">
	<!ENTITY PSY "<ulink url='http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-configuration-file.html'>PAM Configuration File Syntax</ulink>">
	<!ENTITY NSS "<ulink url='http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html'>NSS</ulink>">
	<!ENTITY NSA "<ulink url='http://www.megacz.com/software/libnss-afs.html'>libnss-afs</ulink>">
	<!ENTITY ANG "<ulink url='http://techpubs.spinlocksolutions.com/adduser-ng/'>adduser-ng</ulink>">
	<!ENTITY SUN "<ulink url='http://www.sun.com/'>Sun Microsystems</ulink>">
	<!ENTITY HDL "<ulink url='http://www.pdc.kth.se/heimdal/'>Heimdal Kerberos</ulink>">
	<!ENTITY DOCBK "<ulink url='http://www.docbook.org/'>DocBook</ulink>">
	<!ENTITY SL "<ulink url='http://www.spinlocksolutions.com/'>Spinlock Solutions</ulink>">
	<!ENTITY HCP "<ulink url='http://www.hcoop.net/'>HCoop</ulink>">
	<!ENTITY HCL "<ulink url='http://www.hcoop.net/'>HCoop - Internet Hosting Cooperative</ulink>">
	<!ENTITY SHELL_GLOBBING "<ulink url='http://tldp.org/LDP/abs/html/globbingref.html'>shell globbing</ulink>">
	<!ENTITY GECOS "<ulink url='http://en.wikipedia.org/wiki/Gecos_field'>GECOS</ulink>">
	<!ENTITY GSOC "<ulink url='http://www.openafs.org/pages/gsoc.html'>Google Summer of Code</ulink>">
	<!ENTITY KRBC "<ulink url='http://www.kerberos.org/'>Kerberos consortium</ulink>">

	<!ENTITY DKLAR_DEB "<ulink url='http://techpubs.spinlocksolutions.com/dklar/debian.html'>Debian GNU Guide</ulink>">
	<!ENTITY DKLAR_KRB "<ulink url='http://techpubs.spinlocksolutions.com/dklar/kerberos.html'>MIT Kerberos 5 Guide</ulink>">
	<!ENTITY DKLAR_LDA "<ulink url='http://techpubs.spinlocksolutions.com/dklar/ldap.html'>OpenLDAP Guide</ulink>">
	<!ENTITY DKLAR_AFS "<ulink url='http://techpubs.spinlocksolutions.com/dklar/afs.html'>OpenAFS Guide</ulink>">
	<!ENTITY DKLAR_RAD "<ulink url='http://techpubs.spinlocksolutions.com/dklar/radius.html'>FreeRADIUS Guide</ulink>">

]>


<article id='debian-afs'>

<articleinfo>

	<!--
	<mediaobject>
		<imageobject><imagedata fileref="images/logo-debian.png"
			format="JPG" width="120px" scalefit="1" /></imageobject>
	</mediaobject>
	-->

	<title>Debian GNU: Setting up OpenAFS 1.4.x</title>
	<titleabbrev>debian-afs</titleabbrev>

	<copyright>
		<year>2008-2010</year>
		<holder>Davor Ocelic</holder>
	</copyright>

	<authorgroup>
		<author>
			<firstname>Davor</firstname><surname>Ocelic</surname>
			<email>docelic@spinlocksolutions.com</email>
			<affiliation><ulink url="http://www.spinlocksolutions.com/">SPINLOCK</ulink> &mdash; advanced GNU/Linux and Unix solutions for commercial and education sectors.</affiliation>
		</author>
	</authorgroup>

	<legalnotice>
		<para>
		Last update: Apr 13, 2010. — Improve some descriptions and examples, correct few typos
		</para>

		<para>
		This documentation is free; you can redistribute it and/or modify
		it under the terms of the &GNU; General Public License as published by
		the Free Software Foundation; either version 2 of the License, or
		(at your option) any later version.
		</para><para>
		It is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.
		</para>
	</legalnotice>

	<abstract>
		<para>
		The purpose of this article is to give you a straight-forward,
		Debian-friendly way of installing and configuring OpenAFS 1.4.x, 
		the recommended production version of OpenAFS for UNIX.
		</para><para>
		By the end of this guide, you will have a functional OpenAFS installation
		that will complete our solution for secure, centralized network logins
		with shared home directories.
		</para>
		<para>
		This article is part of &SL;'s practical 5-piece introductory series
		to infrastructure-based Unix networks,
		containing &DKLAR_DEB;,  &DKLAR_KRB;,  &DKLAR_LDA;,  &DKLAR_AFS; and
		&DKLAR_RAD;.
		</para>
	</abstract>

</articleinfo>


<section id="intro">
<title>Introduction</title>
<para>
AFS distributed filesystem is a service that has been traditionally
captivating system administrators' and advanced users' interest, but its
high entry barrier and infrastructure requirements have been
preventing many from using it.
</para><para>
AFS has already been the topic of numerous publications.
Here, we will present only the necessary summary; enough information
to establish the context and to achieve practical results.
</para><para>
You do not need to follow any external links; however, the links have
been provided both throughout the article and listed all together at
the end, to serve as pointers to more precise technical treatment of
individual topics.
</para>
<para>
AFS was started at Carnegie Mellon University in the early 1980s, in
order to easily share file data between people and departments. The 
system became known as the Andrew File System, or AFS, in recognition
of Andrew Carnegie and Andrew Mellon, the primary benefactors of CMU.
Later, AFS was supported and
developed as a product by Transarc Corporation (now IBM Pittsburgh Labs).
IBM branched the source of the AFS product, and made a copy of the source
available for community development and maintenance. They called the release
OpenAFS, which is practically the only "variant" of AFS used today for new
installations.
</para>
<para>
The amount of important information related to AFS is magnitudes 
larger than that of, say, Kerberos or LDAP.
It isn't possible to write a practical OpenAFS Guide without skipping
some of the major AFS concepts and taking
shortcuts in reaching the final objective.  However, this injustice
will be compensated by hooking you up with the whole OpenAFS idea, helping you
achieve practical results quickly, and setting you underway
to expanding your OpenAFS knowledge further using other quality resources.
</para><para>
AFS relies on Kerberos for authentication. A working Kerberos environment
is the necessary prerequisite, and the instructions on setting it up are
found in another article from the series, the &DKLAR_KRB;.
</para><para>
Furthermore,
in a centralized network login solution, user metadata (Unix user and group
IDs, &GECOS; information, home directories, preferred shells, etc.) need to
be shared in a network-aware way as well. This
metadata can be served using LDAP or <literal>libnss-afs</literal>.
In general, LDAP is standalone and flexible, and covered in another
article from the series, the &DKLAR_LDA;.
<literal>libnss-afs</literal> is simple, depends on the use of AFS, and
is covered in this Guide.
</para>

<section id="intro-afs">
<title>The role of AFS within a network</title>
<para>
	<inlinemediaobject>
		<imageobject><imagedata fileref="images/logo-openafs.jpg"
			format="JPG" width="120px" scalefit="1" /></imageobject>
	</inlinemediaobject>
	AFS' primary purpose is to serve files over the network in a robust, 
	efficient, reliable and fault-tolerant way.
	</para><para>
	Its secondary purpose may be to serve user meta information through
	<literal>libnss-afs</literal>, unless you choose &LDA; for the
	purpose as explained in another article from the series, the
	&DKLAR_LDA;.
</para>
<para>
	While the idea of a distributed file system is not unique,
	let's quickly identify some of the AFS specifics:
</para>
	<itemizedlist>
	<listitem><para>
	AFS offers a client-server architecture for transparent file
	access in a common namespace (<filename class='directory'>/afs/</filename>)
	anywhere on the network. This principle has been nicely illustrated by one
	of the early AFS slogans "Where ever you go, there  you are!".
	</para></listitem>
	<listitem><para>
	AFS uses Kerberos 5 as an authentication mechanism, and without a valid
	Kerberos ticket and an AFS token, it is virtually impossible to gain any
	privileged access to the AFS data space, even if you happen to be the
	server or network administrator.
	</para></listitem>
	<listitem><para>
	User's AFS identity is not in any way related to traditional system
	usernames or other data; AFS Protection Database (PTS) is a stand-alone
	database of AFS usernames and groups. However,
	since Kerberos 5 is used as an authentication mechanism, provision
	is made to automatically "map" Kerberos principal names onto PTS entries.
	</para></listitem>
	<listitem><para>
	AFS does not "export" existing data partitions to the network in a way
	that NFS does. AFS requires partitions to be dedicated to AFS use only.
	On AFS partitions, one creates "volumes" which represent basic
	client-accessible units and hold files and directories. These volumes and
	volume quotas are "virtual" entities, they do not affect physical disk
	partitions and disk blocks like system partitions do.
	</para></listitem>
	<listitem><para>
	AFS volumes reside on AFS server partitions. Each AFS server can have up to
	256 partitions of arbitrary size and unlimited number of volumes on them.
	A volume cannot span multiple partitions &mdash; the size of the partition
	implies the maximum data size contained in any of its volumes. (If AFS
	partitions composed of multiple physical partitions are a requirement,
	Logical Volume Manager or other OS-level functionality can be used to
	construct such partitions.)
	</para></listitem>
	<listitem><para>
	To become conveniently accessible, AFS volumes are usually "mounted"
	somewhere in
	the AFS namespace (<filename class='directory'>/afs/</filename>).
	These "mounts" are handled internally in AFS &mdash; they are not affected
	by client or server reboots and they do not correspond to
	Unix mount points. The only Unix mount point defined in AFS is for the
	<filename class='directory'>/afs/</filename> directory itself.
	</para></listitem>
	<listitem><para>
	AFS supports a far more elaborate and convenient permissions system
	(AFS ACL) than the traditional Unix "rwx" modes. These ACLs are
	set on directories and apply to all contained files. Each directory
	can hold up to 20 ACL entries.
	The ACLs may refer to users and groups, and even "supergroups"
	(groups within groups) to a maximum depth of 5.
	IP-based ACLs are available as well, for the rare
	cases where you might have no other option; they work on the
	principle of adding IPs to groups, and then using group names in ACL
	rules. Newly-created directories automatically inherit ACL list of the
	parent directory.

	</para><para>
	As of summer 2008, there have been plans to support file-based ACLs as
	well, as part of the &GSOC; initiative, but this has not yet become a
	usable functionality. (Actually, the implementation was supposedly
	working, but the project went nowhere trying to provide compatibility
	for old AFS clients).
	</para></listitem>
	<listitem><para>
	AFS is available for a broad range of architectures and software platforms.
	You can obtain an up-to-date AFS release for all Linux platforms, Microsoft
	Windows, IBM AIX, HP/UX, SGI Irix, MacOS X and Sun Solaris.
	</para></listitem>
	<listitem><para>
	OpenAFS comes in two main releases, 1.4.x and 1.5.x. The 1.4 "maintenance"
	release is the recommended production version for Unix and MacOS platforms.
	The 1.5 "features" release is the recommended production version for
	Microsoft Windows. The client versions are completely interoperable and
	you can freely mix 1.4 and 1.5 clients.
	</para>
	<para>
	Actually, OpenAFS 1.5 client functionality is pretty stable on all platforms
	and 1.5 clients should start getting deployed in non-critical environments.
	Debian OpenAFS 1.5 packages are soon to be available in the "experimental"
	branch; as that happens, this Guide will be updated to include 1.5 instructions.
	</para>
	</listitem>
	<listitem><para>
	The OpenAFS website and documentation may  seem out of date at first,
	but they do contain all the information you need.
	<!--
	As of summer 2008, 
	however, there have been plans to re-design the OpenAFS website as part
	of the &GSOC; initiative.
	-->
	</para></listitem>
	<listitem><para>
	AFS is enterprise-grade and mature. Books about AFS written 10 or
	15 years ago are still authoritative today,
	plus/minus the inevitable architectural changes and improvements.
	</para></listitem>
	</itemizedlist>

<para>
	You can find the complete AFS documentation at the &AFS; website.
	After grasping the basic concepts, your most helpful resources
	will be quick <literal>help</literal> options supported in all commands,
	such as in <command>fs help</command>, <command>vos help</command>,
	<command>pts help</command> or <command>bos help</command> and
	the Unix manpages.
</para>

</section>

</section>

<section>
<title>Glue layer: integrating AFS with system software</title>

<section><title>PAM</title>
<para>
	On all GNU/Linux-based platforms, &PAM; is available for service-specific
	authentication configuration. &PAM; is an implementation of PAM
	("<literal>Pluggable Authentication Modules</literal>") from &SUN;.
	</para><para>
	Network services, instead of having hard-coded authentication interfaces
	and decision methods, invoke PAM through a standard, pre-defined interface.
	It is then up to PAM to perform any and all authentication-related
	work, and report the result back to the application.
	</para><para>
	Exactly how PAM reaches the decision is none of the service's business.
	In traditional set-ups, that is most often done by asking and verifying
	usernames and passwords. In advanced networks, that could be 
	Kerberos tickets and AFS tokens.
	</para><para>
	PAM will allow for inclusion of OpenAFS into the authentication path
	of all services. After typing in your password, it will be possible to
	verify the password against the Kerberos database and automatically 
	obtain the Kerberos ticket and AFS token, without having to run
	<command>kinit</command> and <command>aklog</command> manually.
	</para><para>
	You can find the proper introduction (and complete documentation)
	on the &PAM; website. Pay special attention to the &PSY; page.
	Also take a look at the 
	<citerefentry>
		<refentrytitle>Linux-PAM</refentrytitle>
		<manvolnum>7</manvolnum>
	</citerefentry>
	and
	<citerefentry>
		<refentrytitle>pam</refentrytitle>
		<manvolnum>7</manvolnum>
	</citerefentry>
	manual pages.
</para>
</section>

</section>

<section id="conventions">
<title>Conventions</title>
<para>
It's quite disappointing when you are not able to follow the instructions
found in the documentation. Let's agree on a few points before going down
to work:
</para>

<itemizedlist>
<listitem><para>
	Our platform of choice, where we will demonstrate a practical setup,
	will be &DEB;.
</para></listitem>
<listitem><para>
	Install <application>sudo</application>. Sudo is a program that will allow
	you to carry out system administrator tasks from your normal user account.
	All the examples in this article requiring root privileges use
	<application>sudo</application>, so you will be able to copy-paste them
	to your shell.
<programlisting>
su -c 'apt-get install sudo'
</programlisting>
If asked for a password, type in the root user's password.
	</para><para>
	To configure sudo, add the following line to your
	<filename>/etc/sudoers</filename>, replacing <literal>$USERNAME</literal>
	with your login name:
<programlisting>
$USERNAME ALL=(ALL) NOPASSWD: ALL
</programlisting>
</para></listitem>
<listitem><para>
	Debian packages installed during the procedure
	will ask us a series of questions through the so-called
	<emphasis>debconf</emphasis> interface. To configure debconf to a 
	known state, run:
<programlisting>
sudo dpkg-reconfigure debconf
</programlisting>
When asked, answer <emphasis>interface</emphasis>=<literal>Dialog</literal>
and <emphasis>priority</emphasis>=<literal>low</literal>.
</para></listitem>
<listitem><para>
	Monitoring log files is crucial in detecting problems. The straight-forward,
	catch-all routine to this is opening a terminal and running:
<programlisting>
cd /var/log; sudo tail -F daemon.log sulog user.log auth.log debug kern.log syslog dmesg messages \
  kerberos/{krb5kdc,kadmin,krb5lib}.log openafs/{Bos,File,Pt,Salvage,VL,Volser}Log
</programlisting>
	</para><para>
	The command will keep printing log messages to the screen as they arrive.
</para></listitem>
<listitem><para>
	Our test system will be called <literal>monarch.spinlock.hr</literal> and
	have an IP address of <literal>192.168.7.12</literal>. Both the server and
	the client will be installed on the same machine. However, to differentiate
	between client and server roles, the client will be referred to as
	<literal>monarch.spinlock.hr</literal> and the server as
	<literal>afs1.spinlock.hr</literal>. The following addition will be 
	made to <filename>/etc/hosts</filename> to completely support this
	scheme:
<screen>
<replaceable>192.168.7.12</replaceable>	<replaceable>monarch.spinlock.hr</replaceable> <replaceable>monarch</replaceable> krb1.<replaceable>spinlock.hr</replaceable> krb1 ldap1.<replaceable>spinlock.hr</replaceable> ldap1 afs1.<replaceable>spinlock.hr</replaceable> afs1
</screen>
</para></listitem>
<!--
<listitem><para>
Finally, a word on colors:
	<itemizedlist>
		<listitem><para>
			<userinput>White-on-black</userinput> signifies the system commands
			you need to run, or the answers you need to type in.
		</para></listitem>
		<listitem><para>
			<replaceable>Italic light-blue</replaceable>,
			<userinput><replaceable>on any background</replaceable></userinput>,
			signifies parts of system commands
			or answers that you should adjust to match your environment. For example,
			you will probably want to always replace say,
			<replaceable>SPINLOCK.HR</replaceable>, with your own domain name
			in uppercase.
		</para></listitem>
		<listitem><para>
<screen>Normal text on gray background, with a teal stripe to the left
presents output of a real shell session, or the contents of
a file. Parts of the input carrying special meaning are depicted using the
rules above, such as <userinput><replaceable>SPINLOCK.HR</replaceable></userinput>.
</screen>
		</para></listitem>
		<listitem><para>
		Text in an <literal>orange-like color</literal> signifies literal values
		that are, for a reason, worth of emphasizing in the context of text flow.
		</para></listitem>
		<listitem><para>
		Text in the <errortext>red color</errortext> signifies exact error
		text as reported from applications. With the exception of
		system-specific values printed in error messages,
		this text could be taken verbatim and looked up on Web
		search engines.
		</para></listitem>
	</itemizedlist>
</para></listitem>
-->
</itemizedlist>

</section>


<section id="afs"><title>OpenAFS installation</title>

<para>
The only meaningful way to access data in AFS is through an AFS
client. That means you will need the OpenAFS client installed and
the kernel module built and running on all AFS systems,
including servers.
</para>
<para>
Since the AFS client is mandatory and it depends
on the kernel module, the whole installation procedure
of an OpenAFS server will consist of the OpenAFS kernel module,
OpenAFS client and OpenAFS server, in that order.
</para>
<para>
Great, so let's roll.
</para>

<section id="afs-kbuild"><title>OpenAFS kernel module</title>

<para>
Building the OpenAFS kernel module today is very simple. There are basically
two methods available: the module-assistant (older) and DKMS (newer).
Both of them offer an extremely simple and elegant way to not have to deal
with any of the complexities behind the scenes.
</para>

<para>
Note that 
Debian versions up to and including Debian "lenny" contain the old OpenAFS 1.4.7
packages.
You can check what versions of OpenAFS are available in your Debian setup by
running <command>apt-cache show openafs-client | grep Version:</command>.
</para>
<para>
If possible, upgrade to Debian testing or unstable to be sure you are using
the newest packages.
If you can't do that on a production machine,
you can still use the 1.4.7 packages, but note that they only support
module-assistant, not DKMS-based kernel module.
</para>
<note>
<para>
You will be able to play around and test OpenAFS 1.4.7
just as usual, but it is strongly suggested that you always
keep your production servers up to date with the latest 1.4.x releases.
<!-- TODO show how: uncomment the text below, just place it in some
separate section or something to be well organized -->
</para>
</note>
<!--
<para>
Maybe the best thing you can do is continue using what ever stable version
of Debian you use, but locally build the
newer OpenAFS packages.
</para>
<para>
If you feel a little adventurous and want to try that out, 
simply run the following commands:
<programlisting>
sudo sh -c "echo deb-src http://ftp.us.debian.org/debian/ testing main >> /etc/apt/sources.list"

sudo apt-get update
sudo aptitude build-dep openafs

cd /usr/local/src
sudo apt-get source openafs
cd openafs-*dfsg

sudo su
export CONCURRENCY_LEVEL=<replaceable>number_of_processor_cores_on_machine</replaceable>
dpkg-buildpackage
logout # (Switch from root back to normal user account)
</programlisting>
</para>
<para>
When the process finishes, you'll end up with the latest .deb packages generated
in the parent directory (<command>cd ..</command>). Do not install any of the
packages yet, we'll come to that in the following sections.
</para>
-->

<section id="afs-kbuild-dkms"><title>OpenAFS kernel module with DKMS</title>
<para>
DKMS is a framework for generating Linux kernel modules. It can rebuild
modules
automatically as the new kernel version is installed. This mechanism was
invented for Linux by the Dell Linux Engineering Team back in 2003, but it started
seeing widespread use only relatively recently.
</para>
<para>
To get the OpenAFS module going with DKMS, here's what you do:
</para>

<para>
<programlisting>
sudo apt-get install build-essential dkms linux-headers-`uname -r`
sudo apt-get install openafs-modules-dkms
</programlisting>
</para>
<para>
It's that easy, and you're done. What's best, this method is maintenance-free
&mdash; provided that there are no
compile-time errors, the OpenAFS module will be automatically compiled
when needed for all kernel versions you happen to be running, be it
upgrades or downgrades.
</para>

</section>

<section id="afs-kbuild-ma"><title>OpenAFS kernel module with module-assistant</title>
<para>
To get it going with module-assistant, here's what you do:
</para>
<para>
<programlisting>
sudo apt-get install module-assistant
sudo m-a prepare openafs
sudo m-a a-i openafs
</programlisting>
<para>
Similarly as for the DKMS approach, you're already done.
Although, with just one difference:
module-assistant does not provide support for rebuilding the kernel module
automatically on kernel change, so you'll need to manually run
<command>sudo m-a a-i openafs</command> every time you 
boot into a new kernel version.
</para>

</para>

<!--
<note><para>
As the Linux kernel source may change a lot even between two minor stable
revisions, it <emphasis>sometimes</emphasis> happens that the OpenAFS
module source included in Debian does not compile cleanly out of the box.
A simple solution for when it happens is to downgrade your kernel to a
version supported by OpenAFS, until the updated module source is available.
</para></note>
-->
</section>

</section>

<section id="afs-install-client"><title>OpenAFS client</title>
<para>

After the kernel module is installed, we can proceed with installing
the OpenAFS client:

<programlisting>
sudo apt-get install openafs-{client,krb5}
</programlisting>

Debconf answers for reference:

<screen>
AFS cell this workstation belongs to: <userinput><replaceable>spinlock.hr</replaceable></userinput>
# (Your domain name in lowercase, matching the Kerberos realm in uppercase)

Size of AFS cache in kB? <userinput><replaceable>4000000</replaceable></userinput>
# (Default value is 50000 for 50 MB, but you can greatly increase the
# size on modern systems to a few gigabytes, with 20000000 (20 GB) being
# the upper reasonable limit)

Run Openafs client now and at boot? <userinput>No</userinput>
# (It is important to say NO at this point, or the client will try to 
# start without the servers in place for the cell it belongs to!)

Look up AFS cells in DNS? <userinput>Yes</userinput>

Encrypt authenticated traffic with AFS fileserver? <userinput>No</userinput>
# (OpenAFS client can encrypt the communication with the fileserver. The
# performance hit is not too great to refrain from using encryption, but
# generally, disable it on local and trusted-connection clients, and enable
# it on clients using remote/insecure channels)

Dynamically generate the contents of /afs? <userinput>Yes</userinput>

Use fakestat to avoid hangs when listing /afs? <userinput>Yes</userinput>

DB server host names for your home cell: <userinput><replaceable>afs1</replaceable></userinput>
# (Before continuing, make sure you've edited your DNS configuration or 
# /etc/hosts file as mentioned above in the section "Conventions", and that
# the command 'ping afs1' really does successfully ping your server)
</screen>
</para>

<!--
-->

<section id="afs-cfg-cache"><title>Client AFS cache</title>
<para>
OpenAFS cache directory on AFS clients is
<filename class='directory'>/var/cache/openafs/</filename>. As we've said,
this includes your AFS servers too, as they will all have the AFS client software
installed.
</para><para>
<emphasis role='bold'>The cache directory must be on an Ext2 or Ext3
filesystem partition</emphasis>. Ext4 may work too, but as they'd say, YMMV.
So when you're using the Ext filesystem for <filename class='directory'>/var/cache/openafs/</filename>,
you just have to ensure there's enough disk space on the partition.
</para>
<caution>
<para>
OpenAFS does not handle insufficient space on the cache gracefully. It is absolutely
important that you DO NOT run out of the data space assigned to the OpenAFS cache.
</para>
</caution>

<para>
In case you're using a different filesystem than Ext for
<filename class='directory'>/var/cache/openafs/</filename>,
then you'll need to mount an Ext partition or file onto
it &mdash; this is a requirement and there are no two ways to
go about it.
</para>

<!--
<para>
If you have a partition available, create an Ext filesystem on it and
add it to <filename>/etc/fstab</filename> as usual:

<programlisting>
sudo mkfs.ext3 /dev/<replaceable>my-partition</replaceable>
sudo sh -c "echo '/dev/<replaceable>my-partition</replaceable> /var/cache/openafs ext3 defaults 0 2' >> /etc/fstab"
</programlisting>

</para><para>
If you don't have a partition available, you can create partition in a file;
here's an example for the default size of 50 MB (which you should adjust
according to "AFS cache size" value above):

<programlisting>
cd /var/cache
sudo dd if=/dev/zero of=openafs.img bs=1M count=50   # (50 MB partition)
sudo mkfs.ext3 openafs.img
sudo sh -c "echo '/var/cache/openafs.img /var/cache/openafs ext3 defaults,loop 0 2' >> /etc/fstab"
sudo tune2fs -c 0 -i 0 -m 0 /var/cache/openafs.img
</programlisting>

To verify that the Ext cache partition is created successfully and can be
mounted, run:
<programlisting>
sudo mount /var/cache/openafs
</programlisting>

</para>
-->

</section>

</section>

<section id="afs-install-server"><title>OpenAFS server</title>

<para>
Now that the kernel module and AFS client are ready, we can proceed with the last 
step &mdash; installing the OpenAFS server.
</para>

<para>

<programlisting>
sudo apt-get install openafs-{fileserver,dbserver}
</programlisting>

Debconf answers for reference:

<screen>
Cell this server serves files for: <userinput><replaceable>spinlock.hr</replaceable></userinput>
</screen>

</para>
<para>
That one was easy, wasn't it? Let's follow with the configuration part of the work
we have to do to get it running:
</para>

<section id="afs-cfg-krbprinc"><title>AFS key (the Kerberos principal)</title>
<para>
As Kerberos introduces mutual authentication of users and services, we
need to create a Kerberos principal for our AFS service.
</para>
<para>
Strictly speaking, in Kerberos you would typically create
one key per-host per-service, but since
OpenAFS uses a single key for the entire cell, we must create just
one key, and that key will be shared by all cell servers.
</para><para>
(The transcript below assumes you've set up Kerberos and the Kerberos
policy named "<literal>service</literal>" as explained in the &DKLAR_KRB;;
if you did not, do so right now as Kerberos is the necessary prerequisite.)

<screen>
<userinput>sudo rm -f /tmp/afs.keytab</userinput>

<userinput>sudo kadmin.local</userinput>

Authenticating as principal root/admin@<replaceable>SPINLOCK.HR</replaceable> with password.

kadmin.local:  <userinput>addprinc -policy service -randkey -e des-cbc-crc:normal afs/<replaceable>spinlock.hr</replaceable></userinput>
Principal "afs@<replaceable>SPINLOCK.HR</replaceable>" created.

kadmin.local:  <userinput>ktadd -k /tmp/afs.keytab -e des-cbc-crc:normal afs/<replaceable>spinlock.hr</replaceable></userinput>
Entry for principal afs with kvno 2, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/tmp/afs.keytab.

kadmin.local:  <userinput>quit</userinput>
</screen>

Once the key's been created and exported to file
<filename>/tmp/afs.keytab</filename> as shown, we need to load it
into the AFS KeyFile. Note that the number "<literal>2</literal>" in the
following command is the key version number, which has to match KVNO reported
in the 'ktadd' step above.

<programlisting>
sudo asetkey add 2 /tmp/afs.keytab afs/<replaceable>spinlock.hr</replaceable>
</programlisting>

To verify the key has been loaded and that there is only one key in 
the AFS KeyFile, run <command>bos listkeys</command>:

<screen>
<userinput>sudo bos listkeys afs1 -localauth</userinput>

key <replaceable>2</replaceable> has cksum <replaceable>2035850286</replaceable>
Keys last changed on <replaceable>Tue Jun 24 14:04:02 2008</replaceable>.
All done.
</screen>

</para>
<para>
Now that's nice!
</para>
<para>
(On a side note,
you can also remove a key from they KeyFile.
In case there's something wrong and you want to do that,
run <command>bos help</command> for a list of available commands
and <command>bos help removekey</command> for the specific
command you'll want to use.)
</para>
</section>

<section id="afs-cfg-weak-crypto"><title>AFS enctype DES</title>
<para>
AFS uses a single-DES Kerberos key, which is considered to be
"weak crypto" by newer versions of Kerberos. Specifically, in Kerberos
version 1.7 it is still allowed by default, but can be disabled by 
specifying "<literal>allow_weak_crypto = false</literal>" in
<filename>/etc/krb5.conf</filename>. In Kerberos 1.8, it is
disabled by default and must be explicitly enabled.
</para>
<para>
Enabling "weak crypto" for OpenAFS is done according to the following
rules:
</para>
<para>
If the machine is a <emphasis role='bold'>Kerberos KDC
server</emphasis> running Kerberos >= 1.7, then weak_crypto must be explicitly allowed,
or the server will not offer single-DES to clients.
(To allow it, edit <filename>/etc/krb5.conf</filename>,
section "<literal>[libdefaults]</literal>", and explicitly set
"<literal>allow_weak_crypto = true</literal>".
Remember to restart krb5-kdc with <command>sudo invoke-rc.d krb5-kdc restart</command>).
</para>
<para>
If the machine is a Krb/AFS <emphasis role='bold'>client</emphasis>,
then weak_crypto may need to be enabled, depending
on the versions of Kerberos and OpenAFS installed on it:
	<itemizedlist>
		<listitem><para>
			<emphasis>Kerberos &lt;= 1.6</emphasis>: no adjustment necessary
		</para></listitem>
		<listitem><para>
			<emphasis>Kerberos 1.7 OR pre-releases of Kerberos 1.8 OR OpenAFS &lt; 1.4.12</emphasis>:
			edit <filename>/etc/krb5.conf</filename>,
			section "<literal>[libdefaults]</literal>", and explicitly set
			"<literal>allow_weak_crypto = true</literal>":
<screen>
[libdefaults]
  ...
  allow_weak_crypto = true
  ...
</screen>

(Remember to restart krb5-kdc with <command>sudo invoke-rc.d krb5-kdc restart</command>.)

		</para></listitem>
		<listitem><para>
			<emphasis>Kerberos &gt;= 1.8 (NOT 1.8 pre-releases) AND OpenAFS &gt;= 1.4.12</emphasis>: no adjustment necessary
		</para><para>
			(MIT Kerberos added a hook to let OpenAFS selectively enable weak crypto for <command>aklog</command>,
			and OpenAFS 1.4.12 uses that hook.)
		</para></listitem>
	</itemizedlist>
</para>
<note><para>
Things regarding AFS use of "weak" keys are changing for the better, the "strong" AES encryption already
works, but is not yet part of a standard release. This guide will be updated as soon as things
become usable out of the box.
</para></note>
</section>

<section id="afs-cfg-partitions"><title>AFS (vice) partitions</title>
<para>
As we've hinted in the introduction, AFS works by using its own dedicated
partitions. Each server can have up to 256 partitions which should be 
mounted to directories named <filename class='directory'>/vicepXX/</filename>,
where "XX" is the partition "number" going from 'a' to 'z' and from
'aa' to 'iv'.
</para><para>
In a simple scenario, we will have only one partition
<filename class='directory'>/vicepa/</filename>. While different
underlying filesystems are supported, we will assume 
<filename class='directory'>/vicepa/</filename> has been formatted
as some version of the Ext filesystem (4, 3 or 2).<sbr/>
</para><para>
In case you do not have a separate partition ready, simply
creating the directory <filename class='directory'>/vicepa/</filename>
in your root partition will do.
Creating <filename class='directory'>/vicepa/</filename> in your existing
partition is possible because AFS does not use its own low-level format for
the partitions &mdash; it saves data to vice partitions on a filesystem
level. (As said in the introduction, that data is structured in a way
meaningful only to AFS, but it <emphasis>is</emphasis> there in the
filesystem, and you are able to browse around it using
<command>cd</command> and <command>ls</command>).
</para>

<!--
<para>
If you have a partition available, create an Ext filesystem on it and
add it to <filename>/etc/fstab</filename> as usual:

<programlisting>
sudo mkfs.ext3 /dev/<replaceable>my-vicepa</replaceable>
sudo sh -c "echo '/dev/<replaceable>my-vicepa</replaceable> /vicepa ext3 defaults,noatime 0 2' >> /etc/fstab"
</programlisting>

</para><para>
If you don't have a partition available, you can create partition in a file;
here's an example of a 100 MB partition:

<programlisting>
cd /
sudo dd if=/dev/zero of=vicepa.img bs=1M count=100
sudo mkfs.ext3 vicepa.img
sudo sh -c "echo '/vicepa.img /vicepa ext3 defaults,noatime,loop 0 2' >> /etc/fstab"
sudo tune2fs -c 0 -i 0 -m 0 /vicepa.img
</programlisting>

To verify that the cache partition is created successfully and can be mounted,
run:
<programlisting>
sudo mkdir -p /vicepa
sudo mount /vicepa
</programlisting>

</para>
-->
</section>

<section id="afs-newcell"><title>Creating a new cell</title>
<para>
Now that we've installed the software components that make up the 
OpenAFS server and that we've taken care of the pre-configuration
steps, we can create an actual AFS cell.
</para>

<important><para>
The <command>afs-newcell</command> script,
which is used to create a new cell, needs 
a simple fix in version <literal>1.4.7.dfsg1-2</literal> before it can
be used to create a new cell (a bug about it has been open under
<ulink url="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=488152">BTS #488152</ulink>).
</para><para>
Russ Allbery has promptly fixed the problem as usual, but to make sure there
is no problem in your version of the script, the following oneliner can be ran on any
version of <command>afs-newcell</command> without adverse effects:
<programlisting>
sudo perl -pi -e 's/(-time never -general)(?! -localauth)/$1 -localauth/' /usr/sbin/afs-newcell
</programlisting>
</para></important>
<para>
Let's run <literal>afs-newcell</literal>:
</para>

<para>
<screen>
<userinput>sudo afs-newcell</userinput>

                            Prerequisites

In order to set up a new AFS cell, you must meet the following:

1) You need a working Kerberos realm with Kerberos4 support.  You
   should install Heimdal with KTH Kerberos compatibility or MIT
   Kerberos 5.

2) You need to create the single-DES AFS key and load it into
   /etc/openafs/server/KeyFile.  If your cell's name is the same as
   your Kerberos realm then create a principal called afs.  Otherwise,
   create a principal called afs/cellname in your realm.  The cell
   name should be all lower case, unlike Kerberos realms which are all
   upper case.  You can use asetkey from the openafs-krb5 package, or
   if you used AFS3 salt to create the key, the bos addkey command.

3) This machine should have a filesystem mounted on /vicepa.  If you
   do not have a free partition, then create a large file by using dd
   to extract bytes from /dev/zero.  Create a filesystem on this file
   and mount it using -oloop.

4) You will need an administrative principal created in a Kerberos
   realm.  This principal will be added to susers and
   system:administrators and thus will be able to run administrative
   commands.  Generally the user is a root or admin instance of some
   administrative user.  For example if jruser is an administrator then
   it would be reasonable to create jruser/admin (or jruser/root) and
   specify that as the user to be added in this script.

5) The AFS client must not be running on this workstation.  It will be
   at the end of this script.

Do you meet these requirements? [y/n] <userinput>y</userinput>

If the fileserver is not running, this may hang for 30 seconds.
/etc/init.d/openafs-fileserver stop

What administrative principal should be used? <userinput>root/admin</userinput>

/etc/openafs/server/CellServDB already exists, renaming to .old
/etc/init.d/openafs-fileserver start
Starting OpenAFS BOS server: bosserver.
bos adduser afs.<replaceable>spinlock.hr</replaceable> root -localauth

Creating initial protection database.  This will print some errors
about an id already existing and a bad ubik magic.  These errors can
be safely ignored.

pt_util: /var/lib/openafs/db/prdb.DB0: Bad UBIK_MAGIC. Is 0 should be 354545
Ubik Version is: 2.0

bos create afs1.<replaceable>spinlock.hr</replaceable> ptserver simple /usr/lib/openafs/ptserver -localauth
bos create afs1.<replaceable>spinlock.hr</replaceable> vlserver simple /usr/lib/openafs/vlserver -localauth
bos create afs1.<replaceable>spinlock.hr</replaceable> fs fs -cmd '/usr/lib/openafs/fileserver -p 23 -busyat 600 \
  -rxpck 400 -s 1200 -l 1200 -cb 65535 -b 240 -vc 1200' -cmd /usr/lib/openafs/volserver \
  -cmd /usr/lib/openafs/salvager -localauth
bos setrestart afs1.<replaceable>spinlock.hr</replaceable> -time never -general -localauth
Waiting for database elections: done.
vos create afs1.<replaceable>spinlock.hr</replaceable> a root.afs -localauth
Volume 536870915 created on partition /vicepa of afs.<replaceable>spinlock.hr</replaceable>
/etc/init.d/openafs-client force-start
Starting AFS services: afsd.
afsd: All AFS daemons started.

Now, get tokens as root/admin in the <replaceable>spinlock.hr</replaceable> cell.
Then, run afs-rootvol to create the root volume.
</screen>

Now that our AFS cell is created, remember we've said volumes are the basic
units accessible by AFS clients?
By convention, each AFS cell creates the
first volume called <literal>root.afs</literal>.
</para>
<note>
	<para>
		Well, strictly speaking, files in a volume can
		legitimately be accessed without mounting a volume. It's not as convenient, so you
		will almost always want to mount the volume first, but keep in mind that unmounting
		a volume does not equal making the files inaccessible &mdash; a volume becomes
		really inaccessible only if you clear its toplevel ACL.
	</para>
</note>

<para>
According to the advice printed at the end of <command>afs-newcell</command>
run, we need to first obtain the AFS administrator token:

<screen>
<userinput>sudo su</userinput> # (We want to switch to the root user)

<userinput>kinit root/admin</userinput>

Password for root/admin@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>

<userinput>aklog</userinput>
</screen>

When running <command>aklog</command>, you might see the following error:

<screen>
<errortext>
aklog: Couldn't get hcoop.net AFS tickets:
aklog: unknown RPC error (-1765328184) while getting AFS tickets
</errortext>
</screen>

It simply means that you did not enable option "<literal>allow_weak_crypto</literal>" in Kerberos config;
see <xref linkend="afs-cfg-weak-crypto"/> above for a solution to the problem.
</para>

<para>
To verify that you hold the Kerberos ticket and AFS token, you may run the following:

<screen>
<userinput>klist -5f</userinput>

Ticket cache: FILE:/tmp/krb5cc_1116
Default principal: root/admin@<replaceable>SPINLOCK.HR</replaceable>

Valid starting     Expires            Service principal
02/09/10 17:18:18  02/10/10 03:18:18  krbtgt/<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>
renew until 02/10/10 17:18:16, Flags: FPRIA
02/09/10 17:18:18  02/10/10 03:18:18  afs/<replaceable>spinlock.hr</replaceable>@<replaceable>SPINLOCK.HR</replaceable>
renew until 02/10/10 17:18:16, Flags: FPRAT

<userinput>tokens</userinput>

Tokens held by the Cache Manager:

User's (AFS ID 1) tokens for afs@<replaceable>spinlock.hr</replaceable> [Expires Feb 10 03:18]
   --End of list--
</screen>


</para>

<para>
Now, with a successful kinit and aklog in place, we can run <command>afs-rootvol</command>:

<screen>
<userinput>afs-rootvol</userinput>

                            Prerequisites

In order to set up the root.afs volume, you must meet the following
pre-conditions:

1) The cell must be configured, running a database server with a
   volume location and protection server.  The afs-newcell script will
   set up these services.

2) You must be logged into the cell with tokens in for a user in
   system:administrators and with a principal that is in the UserList
   file of the servers in the cell.

3) You need a fileserver in the cell with partitions mounted and a
   root.afs volume created.  Presumably, it has no volumes on it,
   although the script will work so long as nothing besides root.afs
   exists.  The afs-newcell script will set up the file server.

4) The AFS client must be running pointed at the new cell.
Do you meet these conditions? (y/n) <userinput>y</userinput>

You will need to select a server (hostname) and AFS partition on which to
create the root volumes.

What AFS Server should volumes be placed on? <userinput>afs1</userinput>
What partition? [a] <userinput>a</userinput>

vos create afs1 a root.cell -localauth
Volume 536870918 created on partition /vicepa of afs1
fs sa /afs system:anyuser rl
fs mkm /afs/<replaceable>spinlock.hr</replaceable> root.cell -cell <replaceable>spinlock.hr</replaceable> -fast || true
fs mkm /afs/grand.central.org root.cell -cell grand.central.org -fast || true
.....
.....
.....
.....
.....
fs sa /afs/<replaceable>spinlock.hr</replaceable> system:anyuser rl
fs mkm /afs/.<replaceable>spinlock.hr</replaceable> root.cell -cell <replaceable>spinlock.hr</replaceable> -rw
fs mkm /afs/.root.afs root.afs -rw
vos create afs1 a user -localauth
Volume 536870921 created on partition /vicepa of afs1
fs mkm /afs/<replaceable>spinlock.hr</replaceable>/user user 
fs sa /afs/<replaceable>spinlock.hr</replaceable>/user system:anyuser rl
vos create afs1 a service -localauth
Volume 536870924 created on partition /vicepa of afs1
fs mkm /afs/<replaceable>spinlock.hr</replaceable>/service service 
fs sa /afs/<replaceable>spinlock.hr</replaceable>/service system:anyuser rl
ln -s <replaceable>spinlock.hr</replaceable> /afs/spinlock
ln -s .<replaceable>spinlock.hr</replaceable> /afs/.spinlock
vos addsite afs1 a root.afs -localauth
Added replication site afs /vicepa for volume root.afs1
vos addsite afs1 a root.cell -localauth
Added replication site afs1 /vicepa for volume root.cell
vos release root.afs -localauth
Released volume root.afs successfully
vos release root.cell -localauth
Released volume root.cell successfully
</screen>
<para>
With this, plus/minus the stuff we'll cover in the following chapters, your cell should be up and running.
</para>

<emphasis role='bold'>So &mdash; woohoo! You've got yourself one
<emphasis>helluva</emphasis> OpenAFS cell!</emphasis>
</para>
</section>

</section>

<section id="afs-pcfg"><title>Post-configuration</title>
<para>
If you remember, during the AFS installation phase, we've answered "No"
to the question "Run OpenAFS client now and at boot?". AFS init script
is such that it just won't run the client as long as the client startup
is disabled in the config file &mdash; even if you invoke 
<userinput>sudo invoke-rc.d openafs-client start</userinput> manually
(you'd have to invoke <userinput>sudo invoke-rc.d openafs-client force-start</userinput>,
but this is not what happens during regular boot).
So we have to enable the client in
<filename>/etc/openafs/afs.conf.client</filename> by replacing
<literal>AFS_CLIENT=false</literal> with <literal>AFS_CLIENT=true</literal>:


<programlisting>
sudo perl -pi -e's/AFS_CLIENT=false/AFS_CLIENT=true/' /etc/openafs/afs.conf.client
sudo invoke-rc.d openafs-client restart
</programlisting>

</para><para>
Now let's drop any tokens or tickets that we may have initialized,
to continue with a clean slate:

<programlisting>
unlog; kdestroy
</programlisting>

All set. At this point, you have the complete OpenAFS environment working. The following
sections provide a lot of different extra information about AFS and its usage, but your
installation and configuration part has been completed.
</para>
</section>

</section>

<section id="afs-concepts"><title>OpenAFS concepts</title>

<section id="afs-access"><title>File layout</title>
<para>
While the whole point of AFS is in accessing files from remote workstations,
remember that all AFS servers are also regular AFS clients and you can use
them to browse the files just as fine. So let's explain
the AFS directory structure a bit and then use our just-installed machine to
look at the actual contents of the 
<filename class='directory'>/afs/</filename> directory.
</para><para>
As we've hinted in <xref linkend="intro"/>, AFS uses a global namespace. That
means all AFS sites are instantly accessible from
<filename class='directory'>/afs/</filename> as if they were local
directories, and all files have a unique AFS path. For example, file 
<filename>/afs/<replaceable>spinlock.hr</replaceable>/service/test</filename> will always be
<filename>/afs/<replaceable>spinlock.hr</replaceable>/service/test</filename>, no matter the
client, operating system, local policy, connection type
or geographical location.
</para><para>
In order to avoid clashes in this global AFS namespace, by convention, each
cell's "AFS root" starts with
<filename class='directory'>/afs/<replaceable>domain.name</replaceable>/</filename>.
</para>
<para>
Beneath it, AFS automatically creates two directories, 
<filename class='directory'>common/</filename> and 
<filename class='directory'>user/</filename>. The latter is where the
users' home directories should go, usually hashed to two levels,
such as <filename class='directory'>/afs/<replaceable>spinlock.hr</replaceable>/user/r/ro/root/</filename>.
</para>

</section>

<section id="afs-basic"><title>File listing and information</title>
<para>
Let's list <filename class='directory'>/afs/</filename>
directory contents to verify what we've just said about AFS cells
and their mount points:

<screen>
<userinput>cd /afs</userinput>

<userinput>ls | head</userinput>
1ts.org
acm-csuf.org
acm.uiuc.edu
ams.cern.ch
andrew.cmu.edu
anl.gov
asu.edu
athena.mit.edu
atlass01.physik.uni-bonn.de
atlas.umich.edu

<userinput>ls | wc -l</userinput>

189
</screen>

The 189 directories were automatically created by the
<command>afs-rootvol</command> script, but you can create additional
and remove existing mount points (AFS mount points) at will.
</para><para>
With the above said, we can predict that AFS has created our own directory in 
<filename class='directory'>/afs/<replaceable>spinlock.hr</replaceable>/</filename>. This directory is only visible automatically within the local cell
and is not seen by the world in <userinput>ls /afs</userinput> listing (because you have
not asked for its inclusion in the global "CellServDB" file).
Its default invisibility, however, does not make it inaccessible &mdash; supposing that
you have a functioning network link, and that your cell name and server
hostnames are known, your cell is reachable from the Internet).
</para><para>
Now that we're in AFS land, 
we can quickly get some more AFS-specific information on 
<filename class='directory'>/afs/<replaceable>spinlock.hr</replaceable>/</filename>:
<!--
Pay special attention to how we specify file paths &mdash; often times
seemingly insignificant variations (like a trailing slash after directory name)
make a difference between the expected output and an error:
-->

<screen>
<userinput>fs lsm /afs/<replaceable>spinlock.hr</replaceable></userinput>

'/afs/<replaceable>spinlock.hr</replaceable>' is a mount point for volume '#<replaceable>spinlock.hr</replaceable>:root.cell'

<userinput>fs lv /afs/<replaceable>spinlock.hr</replaceable></userinput>

File /afs/<replaceable>spinlock.hr</replaceable> (536870919.1.1) contained in volume 536870919
Volume status for vid = 536870919 named root.cell.readonly
Current disk quota is 5000
Current blocks used are 4
The partition has 763818364 blocks available out of 912596444
</screen>

The output above is showing a cell setup with 1 TB of AFS storage &mdash; the block size in OpenAFS is 1 KB.

</para>
<note>
<para>
<emphasis role='bold'>Most</emphasis> of the AFS
<command>fs</command> subcommands operate only on directory names that do not end with a
dot (".") or a slash ("/"). For example, the above <command>fs lsm /afs/<replaceable>spinlock.hr</replaceable></command>
would not work if it was called with <literal>/afs/spinlock.hr/</literal>. Likewise, it is not possible to call
<userinput>fs lsm .</userinput> or <userinput>fs lsm ./</userinput>; use <userinput>fs lsm $PWD</userinput> for that.
</para>
</note>
</section>

<section id="afs-rwpaths"><title>Read and write file paths</title>
<para>
Each time you mount a volume, you can mount it read-write or read-only.
</para><para>
Read-write mounts are simple &mdash; reads and writes are done through
the same filesystem path, such as 
<filename>/afs/<replaceable>spinlock.hr</replaceable>/common/testfile</filename>,
and are always served by the AFS server on which the volume resides.
</para><para>
Read-only mounts make things interesting &mdash; volumes may have up to
8 read-only replicas and clients will retrieve files from the "best" source.
However, that brings two specifics:<sbr/>
First, as the read-only mount is read-only by definition, there exists a
different file path (prefixed with a dot),
such as <filename>/afs/.<replaceable>spinlock.hr</replaceable>/common/testfile</filename>,
for accessing the data in a read-write fashion.<sbr/>
Second, any change of data in the read-write tree won't show up in the read-only tree
until you "release" volume contents with the <command>vos release</command> command.
</para><para>
As said, read-write paths for read-only mounts are prefixed by a leading dot.
Let's verify this:

<screen>
<userinput>fs lsm /afs/<replaceable>spinlock.hr</replaceable></userinput>

'/afs/<replaceable>spinlock.hr</replaceable>' is a mount point for volume '#<replaceable>spinlock.hr</replaceable>:root.cell'

<userinput>fs lsm /afs/.<replaceable>spinlock.hr</replaceable></userinput>

'/afs/.<replaceable>spinlock.hr</replaceable>' is a mount point for volume '%<replaceable>spinlock.hr</replaceable>:root.cell'
</screen>
</para>
</section>

<section id="afs-rw"><title>File reading and writing</title>
<para>
Equipped with the above information, let's visit 
<filename class='directory'>/afs/<replaceable>spinlock.hr</replaceable>/</filename>,
look around, and then try to read and write files.
</para><para>

<screen>
<userinput>cd /afs/<replaceable>spinlock.hr</replaceable></userinput>

<userinput>ls -al</userinput>

total 14
drwxrwxrwx 2 root root 2048 2008-06-25 02:05 .
drwxrwxrwx 2 root root 8192 2008-06-25 02:05 ..
drwxrwxrwx 2 root root 2048 2008-06-25 02:05 service
drwxrwxrwx 2 root root 2048 2008-06-25 02:05 user

<userinput>echo TEST > testfile</userinput>

-bash: testfile: Read-only file system

<userinput>cd /afs/.<replaceable>spinlock.hr</replaceable></userinput>

<userinput>echo TEST > testfile</userinput>

-bash: testfile: Permission denied
</screen>

Good. Let's list access permissions (AFS ACL) for the directory, and
then obtain AFS admin privileges that will allow us to write files.
Note that we first establish our Kerberos identity using
<command>kinit</command>, and then obtain the matching AFS token
using <command>aklog</command>. <command>Aklog</command> obtains a token
automatically and without further prompts, on the basis of the existing
Kerberos ticket.

<screen>
<userinput>cd /afs/.<replaceable>spinlock.hr</replaceable></userinput>

<userinput>fs la .</userinput>

Access list for . is
Normal rights:
  system:administrators rlidwka
  system:anyuser rl

<userinput>kinit root/admin; aklog</userinput>

Password for root/admin@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>

<userinput>klist -5</userinput>

Ticket cache: FILE:/tmp/krb5cc_0
Default principal: root/admin@<replaceable>SPINLOCK.HR</replaceable>

Valid starting     Expires            Service principal
06/29/08 19:38:05  06/30/08 05:38:05  krbtgt/<replaceable>SPINLOCK.HR</replaceable>@<replaceable>SPINLOCK.HR</replaceable>
        renew until 06/30/08 19:38:05
06/29/08 19:38:12  06/30/08 05:38:05  afs@<replaceable>SPINLOCK.HR</replaceable>
        renew until 06/30/08 19:38:05

<userinput>tokens</userinput>

Tokens held by the Cache Manager:

User's (AFS ID 1) tokens for afs@<replaceable>spinlock.hr</replaceable> [Expires Jun 30 05:38]
   --End of list--
</screen>

At this point, writing the file succeeds:

<screen>

<userinput>echo TEST > testfile</userinput>

<userinput>cat testfile</userinput>

TEST

<userinput>rm testfile</userinput>
</screen>

</para>

</section>

<section>
<title>Creating users</title>

<para>
As we've seen in previous chapters, to obtain read or write privilege in AFS,
you authenticate to Kerberos using 
<command>kinit</command> and then to AFS using <command>aklog</command>.
</para>
<para>
We're dealing with two separate authentication databases here 
&mdash; the Kerberos database and the AFS "Protection Database" or PTS.
</para>
<para>
That means all users have to exist in both Kerberos and AFS if they
want to access AFS data space in an authenticated fashion. The only reason
we did not have to add <literal>root/admin</literal> user to AFS PTS is
because this was done automatically by the virtue of
<command>afs-newcell</command>.
</para>
<para>
So let's add a regular AFS user. We're going to add user
"<literal>mirko</literal>", which should already exist in Kerberos if you've
followed the &DKLAR_KRB;, section
"<ulink url="http://techpubs.spinlocksolutions.com/dklar/kerberos.html#krb-adduser-ticket">Creating first unprivileged principal</ulink>".
Make sure you hold the administrator Kerberos ticket and AFS token,
and then execute:

<screen>
<userinput>pts createuser <replaceable>mirko</replaceable> <replaceable>20000</replaceable></userinput>

User <replaceable>mirko</replaceable> has id <replaceable>20000</replaceable>
</screen>

You will notice that Kerberos and AFS do not require any use of
<command>sudo</command>. (Actually, we do use sudo to invoke Kerberos'
<userinput>sudo kadmin.local</userinput>, but that's only because we want
to access the local Kerberos database directly on a file level).
Kerberos and AFS privileges are determined solely by tickets and
tokens one has obtained, and have nothing to do with traditional 
Unix privileges nor are tied to certain usernames or IDs.
</para>
</section>

<section>
<title>Creating and mounting volumes</title>

<para>
Now that we have a regular user "<replaceable>mirko</replaceable>" created
in both Kerberos and AFS, we want to create an AFS data volume that will
correspond to this user and be "mounted" in the location of the
user's home directory in AFS.
</para>
<para>
This is an establish AFS practice &mdash; that
every user gets a separate volume, mounted in the AFS space as their home directory.
Depending on specific uses, further volumes might also be created for the user
and mounted somewhere under their toplevel home directory.
</para>
<para>
Make sure you still hold the administrator Kerberos ticket and AFS token,
and then execute:

<screen>
<userinput>vos create afs1 a user.<replaceable>mirko</replaceable> <replaceable>200000</replaceable></userinput>

Volume <replaceable>536997357</replaceable> created on partition /vicepa of afs1

<userinput>vos examine user.<replaceable>mirko</replaceable></userinput>

user.<replaceable>mirko</replaceable>                        <replaceable>536997357</replaceable> RW          2 K  On-line
    afs1.<replaceable>spinlock.hr</replaceable> /vicepa 
    RWrite  <replaceable>536997357</replaceable> ROnly          0 Backup          0 
    MaxQuota     <replaceable>200000</replaceable> K 
    Creation    Sun Jun 29 18:06:43 2008
    Copy        Sun Jun 29 18:06:43 2008
    Backup      Never
    Last Update Never

    RWrite: <replaceable>536997357</replaceable>
    number of sites -> 1
       server afs1.<replaceable>spinlock.hr</replaceable> partition /vicepa RW Site 
</screen>

Having the volume, let's mount it to a proper location. We will use
a "hashed" directory structure with two sublevels, so that the person's home
directory will be in <literal>/afs/<replaceable>spinlock.hr</replaceable>/user/<replaceable>p</replaceable>/<replaceable>pe</replaceable>/<replaceable>person</replaceable>/</literal>
(instead of directly in <literal>user/<replaceable>person</replaceable>/</literal>).
Follow this AFS convention and you will be able to use
<literal>libnss-afs</literal> and 3rd party management scripts without
modification.

<screen>
<userinput>cd /afs/<replaceable>spinlock.hr</replaceable>/user</userinput>

<userinput>mkdir -p <replaceable>m</replaceable>/<replaceable>mi</replaceable></userinput>

<userinput>fs mkm <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable> user.<replaceable>mirko</replaceable> -rw</userinput>
</screen>

Let's view volume and directory information:
<screen>
<userinput>fs lsm <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable></userinput>

'<replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable>' is a mount point for volume '#user.<replaceable>mirko</replaceable>'

<userinput>fs lv <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable></userinput>

File <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable> (<replaceable>536997357.1.1</replaceable>) contained in volume <replaceable>536997357</replaceable>
Volume status for vid = <replaceable>536997357</replaceable> named user.<replaceable>mirko</replaceable>
Current disk quota is <replaceable>200000</replaceable>
Current blocks used are 2
The partition has 85448567 blocks available out of 140861236
</screen>

</para>

</section>

<section>
<title>Setting permissions</title>

<para>
Let's view the permissions on the new directory and allow user full
access:

<screen>
<userinput>fs la <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable></userinput>

Access list for <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable> is
Normal rights:
  system:administrators rlidwka

<userinput>fs sa  <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable> <replaceable>mirko</replaceable> all</userinput>

<userinput>fs la !:2</userinput>

Access list for <replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable> is
Normal rights:
  system:administrators rlidwka
  mirko rlidwka
</screen>

</para>
<para>
(On a side note, the "!:2" above is a Bash construct that will insert the 3rd word from the previous line.)
</para>
<para>

Now switch to user <replaceable>mirko</replaceable> and verify you've got
access to the designated home directory:

<screen>
<userinput>unlog; kdestroy</userinput>

<userinput>kinit <replaceable>mirko</replaceable>; aklog</userinput>

Password for <replaceable>mirko</replaceable>@<replaceable>SPINLOCK.HR</replaceable>: <userinput><replaceable>PASSWORD</replaceable></userinput>

<userinput>cd /afs/<replaceable>spinlock.hr</replaceable>/user/<replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable></userinput>

<userinput>echo IT WORKS > test</userinput>

<userinput>cat test</userinput>

IT WORKS
</screen>

</para>
</section>

<section id="afs-quota"><title>Volume quotas</title>

<para>
AFS volumes have a concept of "volume quota", or the maximum amount of data
you can put on them before reaching the limit. It's important to know that
AFS volumes do not take a predefined amount of disk space as physical disk
partitions do; you can create thousands of volumes, and they only take as
much space as there is actual data on them. Likewise, AFS volume quotas
are just limits that do not affect volume size except "capping" the
maximum size of data a volume can store.
</para>

<para>
Let's list volume data size quota and increase it from the default 5 MB
to 100 MB:
</para>

<screen>
<userinput>cd /afs/.<replaceable>spinlock.hr</replaceable></userinput>

<userinput>fs lq</userinput>

Volume Name                   Quota      Used %Used   Partition
root.cell                      5000        28    1%         38% 

<userinput>fs sq . 100000</userinput>

<userinput>fs lq</userinput>

Volume Name                   Quota      Used %Used   Partition
root.cell.readonly           100000        28    1%         38% 
</screen>

</section>

</section>

<section>
<title>Serving metadata</title>
<para>
The material covered so far in the &DKLAR_KRB; and this
&DKLAR_AFS; has gotten us to a point where we can create users in Kerberos
and AFS, create and mount users' data volumes,
authenticate using <command>kinit</command> and <command>aklog</command>,
and read and write files in the users' volumes with full permissions.
</para><para>
In other words, it smells as if we're a step away from our goal &mdash;
a true networked and secure solution for centralized logins with exported
home directories.
</para><para>
There's one final thing missing, and it's the support for serving
user "metadata". As explained in <xref linkend="intro"/>, metadata will come
from either LDAP or <literal>libnss-afs</literal>.
</para><para>
If you've followed and implemented the setup described in the &DKLAR_LDA;,
you already have the metadata taken care of. However, let's say a few words
about it anyway to broaden our horizons.
</para><para>
Metadata is the information traditionally found in 
system files
<filename>/etc/passwd</filename>, 
<filename>/etc/group</filename> and
<filename>/etc/shadow</filename>.
</para>
<para>
Metadata necessary for a successful user login includes four elements:
Unix user ID, Unix group ID, home directory and the desired shell.
</para><para>
But let's take a look at the complete list of standard user 
metadata, nothing the software components able to
handle them:

<itemizedlist>
	<listitem><para>
	Username (all)
	</para></listitem>
	<listitem><para>
	Password (Kerberos or LDAP &mdash; but storing passwords in LDAP is out of our scope)
	</para></listitem>
	<listitem><para>
	User ID (LDAP or <literal>libnss-afs</literal>)
	</para></listitem>
	<listitem><para>
	Group ID and group membership (LDAP)
	</para></listitem>
	<listitem><para>
	&GECOS; information (LDAP)
	</para></listitem>
	<listitem><para>
	Home directory (LDAP or <literal>libnss-afs</literal>)
	</para></listitem>
	<listitem><para>
	Preferred shell (LDAP or <literal>libnss-afs</literal>)
	</para></listitem>
	<listitem><para>
	Group membership (LDAP)
	</para></listitem>
	<listitem><para>
	Password aging (Kerberos)
	</para></listitem>
</itemizedlist>

</para><para>
You may notice LDAP seems like a "superset" of 
<literal>libnss-afs</literal>. And it really is, which can be an
advantage or a disadvantage, depending on the situation. Here's why:
</para><para>
LDAP is a standalone solution that can be used to create network
infrastructures based on the "magic trio" &mdash; Kerberos, LDAP
and AFS. It is flexible and can serve arbitrary user and
system information besides the necessary metadata.
Can you think of a few examples
how this would be useful? For example, on a lower level, 
you could use LDAP to store extra group membership information or
per-user host access information; on a higher level, you could use LDAP
to store a person's image, birth date, or a shared calendar available to
all user applications. However, this flexibility comes at a cost of
administering yet another separate database (Kerberos, AFS and LDAP all
have their own database, and you have to keep them in sync).
</para><para>
<literal>libnss-afs</literal>, on the other hand, is an AFS-dependent module
that serves the 
metadata out of the AFS PTS database. It is simple, and limited.
Structure of the PTS is such that
you can only save certain information in there, and nothing else. For
fields that cannot be represented in PTS, <literal>libnss-afs</literal>
outputs a "one size fits all" default value. For example, as there is
no space for &GECOS; information in the PTS, everyone's GECOS is set to
their username; as there is no group ID, everyone's group ID is set to group
<literal>65534 (nogroup)</literal>, and as there is no home directory,
everyone's homedir is set to <filename>/afs/<replaceable>cell.name</replaceable>/user/<replaceable>u</replaceable>/<replaceable>us</replaceable>/<replaceable>user</replaceable>/</filename>.
<literal>libnss-afs</literal> may suit those who prefer simplified
administration over flexibility.
</para><para>
In this Guide, both LDAP and <literal>libnss-afs</literal> approach will be
explained. Moving from <literal>libnss-afs</literal>
to LDAP is easy; if in doubt, pick <literal>libnss-afs</literal> as a simpler
start-up solution.
</para>

<section>
<title>Metadata via LDAP</title>
<para>
A complete LDAP setup is explained in another article from the series,
the &DKLAR_LDA;. If you have followed and implemented the procedure,
especially the part about modifying <filename>/etc/nsswitch.conf</filename>,
then there's only one thing that should be done here &mdash;
you should modify users' entries in LDAP to make their 
home directories point to AFS instead of to
<filename class='directory'>/home/</filename>.
</para><para>
Actually, you can symlink
<filename class='directory'>/home/</filename>
to AFS, and then no change in LDAP will be necessary. One benefit of
this approach is that <filename class='directory'>/home/</filename> looks
familiar to everyone. One drawback is that you need to symlink that
directory to AFS on all machines where users will be logging in.
</para><para>

To create the symlinks, use:

<programlisting>
sudo mv /home /home,old
sudo ln -sf /afs/.<replaceable>spinlock.hr</replaceable>/user /home
sudo ln -sf /afs/<replaceable>spinlock.hr</replaceable>/user /rhome
</programlisting>

To literally change users' home directories in LDAP (to point to
<filename class='directory'>/afs/<replaceable>spinlock.hr</replaceable>/user/<replaceable>u</replaceable>/<replaceable>us</replaceable>/<replaceable>user</replaceable>/</filename>),
construct a LDIF file and use <command>ldapmodify</command> to
apply the LDIF file.
</para><para>
Here's an example for user <literal>mirko</literal> (which should already exist
in your LDAP directory if you've followed the &DKLAR_LDA; Guide). Save the
following as <filename>/tmp/homechange.ldif</filename>:

<screen>
dn: uid=<replaceable>mirko</replaceable>,ou=people,dc=<replaceable>spinlock</replaceable>,dc=<replaceable>hr</replaceable>
changetype: modify
replace: homeDirectory
homeDirectory: /afs/<replaceable>spinlock.hr</replaceable>/user/<replaceable>m</replaceable>/<replaceable>mi</replaceable>/<replaceable>mirko</replaceable>
</screen>

And apply using:

<programlisting>
ldapmodify -c -x -D cn=admin,dc=<replaceable>spinlock</replaceable>,dc=<replaceable>hr</replaceable> -W -f /tmp/homechange.ldif
</programlisting>
</para>
</section>

<section>
<title>Metadata via libnss-afs</title>
<para>
As said, &NSA; is an AFS-dependent approach to
serving metadata, so it only makes sense to describe it in the context of
the &DKLAR_AFS;.
</para>
<para>
Adam Megacz created <literal>libnss-afs</literal> on the basis of Frank
Burkhardt's <literal>libnss-ptdb</literal>, which in turn was created on
the basis of Todd M. Lewis' <literal>nss_pts</literal>.
The primary motivation for <literal>libnss-afs</literal> has been the use
at &HCP;, the first non-profit corporation offering public AFS hosting
and accounts.
</para>
<para>
Good. Let's move onto the technical setup:
</para>
<para>
<literal>libnss-afs</literal> must run in
combination with <command>nscd</command> and cache the replies from the
AFS <literal>ptserver</literal>, so
let's install <command>nscd</command>:

<screen>
<userinput>sudo apt-get install nscd</userinput>
</screen>

Once nscd is installed, edit its config file, <filename>/etc/nscd.conf</filename> to include the following:

<screen>
enable-cache hosts no
persistent passwd no
persistent groups no
persistent hosts  no
</screen>

(Note that all of the above lines already exist in <filename>/etc/nscd.conf</filename>, although the
formatting of the file is a bit strange and finding them is an exercise for your eyes. So you should
not be adding the above lines in there, but just locating them in the config file and turning
the appropriate "yes" to "no".)
</para><para>
Then, restart nscd as usual with <command>sudo invoke-rc.d nscd restart</command>.
</para>
<para>

<literal>libnss-afs</literal> homepage is on &NSA;, and the software can be downloaded as <ulink url="http://git.megacz.com/?p=libnss-afs.git;a=snapshot;h=refs/heads/stable;sf=tgz">Gitweb tarball</ulink>. Once the tarball is unpacked, Debian package can be built and installed by cd-ing into the <filename class='directory'>libnss-afs/</filename> directory and running:

<screen>
<userinput>sudo apt-get install libopenafs-dev</userinput>

<userinput>sudo dpkg-buildpackage</userinput>

<userinput>sudo dpkg -i ../libnss-afs*deb</userinput>
</screen>
</para>
<para>

After <literal>libnss-afs</literal> is installed, let's modify the
existing lines in <literal>/etc/nsswitch.conf</literal> to look like
the following:

<screen>
passwd:  afs files
group:   afs files
shadow:  files
</screen>
</para>
</section>

<section>
<title>Metadata test</title>

<para>
We are ready to test metadata retrieval:
<screen>
<userinput>sudo nscd -i passwd</userinput>

<userinput>id <replaceable>mirko</replaceable></userinput>

uid=20000(mirko) gid=65534(nogroup) groups=65534(nogroup)

<userinput>getent passwd <replaceable>mirko</replaceable></userinput>

mirko:x:20000:65534:mirko:/afs/hcoop.net/user/m/mi/mirko:/bin/bash
</screen>
</para>
</section>

</section>


<section>
<title>PAM configuration</title>
<para>

The final step in this article pertains to integrating OpenAFS into
the system authentication procedure. We want Kerberos ticket and OpenAFS
token to be issued for users as they log in, without the need to run
<command>kinit</command> and <command>aklog</command> manually after login.
</para><para>
Let's install the necessary OpenAFS PAM module:
<programlisting>
sudo apt-get install libpam-afs-session
</programlisting>
</para>

<para>
To minimize the chance of locking yourself out of the system during PAM
configuration phase, ensure right now that you have at least one root
terminal window open and a copy of the files available
<emphasis>before</emphasis> starting on PAM configuration changes.
To do so, execute the following in a cleanly started shell and leave
the terminal open:

<programlisting>
sudo su -
cd /etc
cp -a pam.d pam.d,orig
</programlisting>
</para>

<note><para>
If you break logins with an invalid PAM configuration, the above
will allow you to simply revert to a known-good state by using the open
root terminal and executing:

<programlisting>
cp -a pam.d,orig/* pam.d/
</programlisting>
</para></note>

<para>
After you've edited your PAM configuration as shown below,
restart the services you will be connecting to. This isn't strictly
necessary, but it ensures that the services will re-read the PAM
configuration and not use any cached information.
</para>

<section><title>/etc/pam.d/common-auth</title><para>
<screen>
auth    sufficient        pam_unix.so nullok_secure
auth    sufficient        pam_krb5.so use_first_pass
auth    optional          pam_afs_session.so program=/usr/bin/aklog
auth    required          pam_deny.so
</screen>
</para></section>

<section><title>/etc/pam.d/common-session</title><para>
<screen>
session required pam_limits.so
session optional pam_krb5.so
session optional pam_unix.so
session optional pam_afs_session.so program=/usr/bin/aklog
</screen>
</para></section>

</section>

<!--
<section>
<title>Administration overhead</title>
<para>
There's a definite administration overhead involved in running an AFS
cell. Besides the knowledge required to run the whole chain, there
are also 3 or 4 databases that, even though separate, need to be
appropriately synchronized:
</para>
<para>
There's the Kerberos database of principals that has to be
maintained using Kerberos-specific tools.
<sbr/>
There's the AFS Protection Database of users that has to be
maintained using AFS-specific tools.
<sbr/>
There's the LDAP database of entries that has to be
maintained using LDAP-specific tools.
<sbr/>
There are also the standard Unix password files, 
<filename>/etc/passwd</filename>, <filename>/etc/group</filename> and
<filename>/etc/shadow</filename> that still have to be maintained
using traditional tools for
local system users such as <literal>root</literal>, 
<literal>daemon</literal>, <literal>bin</literal>, 
<literal>sys</literal> etc.
</para>
<para>
Regardless of the benefits on the grand scale, it means
adding users becomes a complex and error prone operation
on a per-user level.
</para>
<para>
For example, you might think automating user creation would be easy, as
all one would have to do in a KRB/AFS/libnss-afs setup would come down to:
<programlisting>
/usr/sbin/kadmin.local -q 'addprinc -policy user <replaceable>USERNAME</replaceable>'
pts createuser <replaceable>USERNAME</replaceable>
</programlisting>

Soon, however, you figure out there's more to be done &mdash; a home
directory should be created for a 
user, <filename class='directory'>/etc/skel/</filename> files copied over,
his shell changed and so on. In an instant, you're missing the whole
Debian <command>adduser</command> set of tools.
</para>
<para>
To that effect, I've taken the existing Debian <literal>adduser</literal>
suite and completely rewrote it to both solve a number of its shortcomings,
and to introduce modular approach that understands Kerberos, LDAP
and AFS natively.
</para>
<para>
The new <literal>adduser-ng</literal> suite can be downloaded from
&ANG; website, with the ready-made configuration matching our setup
provided in the following subsection.
</para>

<section>
<title>Adduser-ng configuration</title>
<para>
</para>
</section>
</section>
-->


<section>
<title>Conclusion</title>

<para>DONATE_LINK</para>

<para>
At this point, you have a functional AFS site. Users, once created
in the system, can log in and access their files anywhere on the network.
</para><para>
You can rely on either system login or manually running
<command>kinit; aklog</command> in obtaining Kerberos
ticket and AFS token.
</para><para>
Once the token is obtained, you can access the protected
AFS data space. 
</para>
<para>
<emphasis role='bold'>With a good foundation we've built, for further
information on AFS, please refer to other available resources:</emphasis>

<itemizedlist>
	<listitem><para>
	Official documentation: &DOC;
	</para></listitem>
	<listitem><para>
	Mailing lists: &MLS; (OpenAFS-info in particular)
	</para></listitem>
	<listitem><para>
	IRC: channel #OpenAFS at the FreeNode network (irc.freenode.net)
	</para></listitem>
</itemizedlist>
</para>
<para>
For commercial consultation and infrastructure-based networks containing
AFS, contact &SL; or organizations listed on the
<ulink url="http://openafs.org/support.html">OpenAFS support page</ulink>.
</para>
</section>

<section>
<title>Links</title>

<para>
Platforms:<sbr/>
	&GNU;                              <sbr/>
	&DEB;                              <sbr/><sbr/>

AFS:<sbr/>
	&AFS;                              <sbr/>
	&DOC;                              <sbr/>
	&MLS;                              <sbr/>
	&GCO;                              <sbr/>
	&GSOC; AFS projects                <sbr/>
	&ARL;                              <sbr/><sbr/>

Public access AFS accounts:<sbr/>
	&HCL;                              <sbr/><sbr/>

Glue layer:<sbr/>
	&PAM;                              <sbr/>
	&PSY;                              <sbr/>
	&NSS;                              <sbr/>
	&NSA;                              <sbr/><sbr/>

Related infrastructural technologies:<sbr/>
	&KRB;                              <sbr/>
	&LDA;                              <sbr/>
	&RAD;                              <sbr/><sbr/>

Adduser-ng suite:<sbr/>
	&ANG;                              <sbr/><sbr/>

Commercial support:<sbr/>
	&SL;                               <sbr/>
<ulink url="http://openafs.org/support.html">OpenAFS support organizations</ulink><sbr/><sbr/>


Misc:<sbr/>
	&DOCBK;                            <sbr/>
</para>
</section>

</article>

