diff --git a/en_US.ISO8859-1/articles/pam/Makefile b/en_US.ISO8859-1/articles/pam/Makefile
index 27aeb7f607..059a7db3ed 100644
--- a/en_US.ISO8859-1/articles/pam/Makefile
+++ b/en_US.ISO8859-1/articles/pam/Makefile
@@ -1,16 +1,21 @@
# $FreeBSD$
DOC?= article
FORMATS?= html
INSTALL_COMPRESSED?=gz
INSTALL_ONLY_COMPRESSED?=
JADEFLAGS+= -V %generate-article-toc%
-SRCS= article.sgml
+SRCS= article.sgml pam_app.c
+
+CLEANFILES+= pam_app.c
+
+pam_app.c: su.c
+ perl -ne 'print unless m|^[/ ]\*|' su.c >${.TARGET}
DOC_PREFIX?= ${.CURDIR}/../../..
.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/en_US.ISO8859-1/articles/pam/article.sgml b/en_US.ISO8859-1/articles/pam/article.sgml
index 6e201c18cd..fb72382d8a 100644
--- a/en_US.ISO8859-1/articles/pam/article.sgml
+++ b/en_US.ISO8859-1/articles/pam/article.sgml
@@ -1,876 +1,871 @@
%man;
- %freebsd;
- %newsgroups;
-
-%authors;
- %mailing-lists;
-
-
]>
Pluggable Authentication Modules$FreeBSD$This article describes the underlying principles and
mechanisms of the Pluggable Authentication Modules (PAM)
library, and explains how to configure PAM, how to integrate
PAM into applications, and how to write PAM modules.Dag-ErlingSmørgravContributed by IntroductionThe Pluggable Authentication Modules (PAM) library is a
generalized API for authentication-related services which allows
a system administrator to add new authentication methods simply
by installing new PAM modules, and to modify authentication
policies by editing configuration files.PAM was defined and developed in 1995 by Vipin Samar and
Charlie Lai of Sun Microsystems, and has not changed much since.
In 1997, the Open Group published the X/Open Single Sign-on
(XSSO) preliminary specification, which standardized the PAM API
and added extensions for single (or rather integrated) sign-on.
At the time of this writing, this specification has not yet been
adopted as a standard.Although this article focuses on FreeBSD's implementation of
PAM, which is based on Linux-PAM, most of it should be
applicable to most other operating systems which implement PAM,
including Solaris.TrademarksSun, Sun Microsystems and Solaris are trademarks or
registered trademarks of Sun Microsystems, Inc.UNIX and The Open Group are trademarks or registered
trademarks of The Open Group.All other brand or product names mentioned in this
document may be trademarks or registered trademarks of their
respective owners.Terms and conventionsDefinitionsThe terminology surrounding PAM is rather confused.
Neither Samar and Lai's original paper nor the XSSO
specification made any attempt at formally defining terms for
the various actors and entities involved in PAM, and the terms
that they do use (but do not define) are sometimes misleading
and ambiguous. The first attempt at establishing a consistent
and unambiguous terminology was a whitepaper written by Andrew
G. Morgan (author of Linux-PAM) in 1999. While Morgan's
choice of terminology was a huge leap forward, it is in this
author's opinion by no means perfect. What follows is an
attempt, heavily inspired by Morgan, to define precise and
unambiguous terms for all actors and entities involved in
PAM.accountThe set of credentials the applicant is requesting
from the arbitrator.applicantThe user or entity requesting authentication.arbitratorThe user or entity who has the privileges necessary
to verify the applicant's credentials and the authority
to grant or deny the request.chainA sequence of modules that will be invoked in
response to a PAM request. The chain includes
information about the order in which to invoke the
modules, what arguments to pass to them, and how to
interpret the results.clientThe application responsible for initiating an
authentication request on behalf of the applicant and
for obtaining the necessary authentication information
from him.facilityOne of the four basic groups of functionality
provided by PAM: authentication, account management,
session management and authentication token
update.moduleA collection of one or more related functions
implementing a particular authentication facility,
gathered into a single (normally dynamically loadable)
binary file and identified by a single name.policyThe complete set of configuration statements
describing how to handle PAM requests for a particular
service. A policy normally consists of four chains, one
for each facility, though some services do not use all
four facilities.serverThe application acting on behalf of the arbitrator
to converse with the client, retrieve authentication
information, verify the applicant's credentials and
grant or deny requests.serviceA class of servers providing similar or related
functionality and requiring similar authentication. PAM
policies are defined on a per-service basis, so all
servers that claim the same service name will be subject
to the same policy.sessionThe context within which service is rendered to the
applicant by the server. One of PAM's four facilities,
session management, is concerned exclusively with
setting up and tearing down this context.tokenA chunk of information associated with the account,
such as a password or passphrase, which the applicant
must provide to prove his identity.transactionA sequence of requests from the same applicant to
the same instance of the same server, beginning with
authentication and session set-up and ending with
session tear-down.Usage examplesThis section aims to illustrate the meanings of some of
the terms defined above by way of a handful of simple
examples.Client and server are oneThis simple example shows alice
&man.su.1;'ing to root.&prompt.user; whoami
alice
&prompt.user; ls -l `which su`
-r-sr-xr-x 1 root wheel 10744 Dec 6 19:06 /usr/bin/su
&prompt.user; su -
Password: xi3kiune
&prompt.root; whoami
root
The applicant is alice.The account is root.The &man.su.1; process is both client and
server.The authentication token is
xi3kiune.The arbitrator is root, which is
why &man.su.1; is setuid root.Client and server are separateThe example below shows eve try to
initiate an &man.ssh.1; connection to
login.example.com, ask to log in as
bob, and succeed. Bob should have chosen
a better password!&prompt.user; whoami
eve
&prompt.user; ssh bob@login.example.com
bob@login.example.com's password: god
Last login: Thu Oct 11 09:52:57 2001 from 192.168.0.1
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD 4.4-STABLE (LOGIN) #4: Tue Nov 27 18:10:34 PST 2001
Welcome to FreeBSD!
&prompt.user;The applicant is eve.The client is Eve's &man.ssh.1; process.The server is the &man.sshd.8; process on
login.example.comThe account is bob.The authentication token is
god.Although this is not shown in this example, the
arbitrator is root.Sample policyThe following is FreeBSD's default policy for
sshd:sshd auth required pam_nologin.so no_warn
sshd auth required pam_unix.so no_warn try_first_pass
sshd account required pam_unix.so
sshd session required pam_permit.so
sshd password required pam_permit.soThis policy applies to the sshd
service (which is not necessarily restricted to the
&man.sshd.8; server.)auth, account,
session and
password are facilities.pam_nologin.so,
pam_unix.so and
pam_permit.so are modules. It is
clear from this example that
pam_unix.so and
pam_permit.so provide at least two
facilities each.ConventionsThis section has not yet been written.PAM EssentialsFacilities and
primitivesThe PAM API offers six different authentication primitives
grouped in four facilities, which are described below.authAuthentication. This facility
concerns itself with authenticating the applicant and
establishing the account credentials. It provides two
primitives:pam_authenticate
authenticates the applicant, usually by requesting
an authentication token and comparing it with a
value stored in a database or obtained from an
authentication server.pam_setcred establishes
account credentials such as user ID, group
membership and resource limits.accountAccount management. This
facility handles non-authentication-related issues of
account availability, such as access restrictions based
on the time of day or the server's work load. It
provides a single primitive:pam_acct_mgmt verifies that
the requested account is available.sessionSession management. This
facility handles tasks associated with session set-up
and tear-down, such as login accounting. It provides
two primitives:pam_open_session performs
tasks associated with session set-up: add an entry
in the utmp and
wtmp databases, start an SSH
agent, etc.pam_close_session performs
tasks associated with session tear-down: add an
entry in the utmp and
wtmp databases, stop the SSH
agent, etc.passwordPassword management. This
facility is used to change the authentication token
associated with an account, either because it has
expired or because the user wishes to change it. It
provides a single primitive:pam_chauthtok changes the
authentication token, optionally verifying that it
is sufficiently hard to guess, has not been used
previously, etc.ModulesModules are a very central concept in PAM; after all,
they are the M in PAM. A PAM
module is a self-contained piece of program code that
implements the primitives in one or more facilities for one
particular mechanism; possible mechanisms for the
authentication facility, for instance, include the UNIX
password database, NIS, LDAP and Radius.FreeBSD groups all facilities for the same mechanism in
one module called
pam_mechanism.so (e.g.
pam_unix.so.) The original PAM
implementation, on the other hand, had separate modules for
each facility, called
pam_mechanism_facility.so
(e.g. pam_unix_auth.so.)Chains and
policiesWhen a server initiates a PAM transaction, the PAM library
tries to load a policy for the service specified in the
pam_start call. The policy specifies how
authentication requests should be processed, and is defined in
a configuration file. This is the other central concept in
PAM: the possibility for the admin to tune the system security
policy (in the wider sense of the word) simply by editing a
text file.A policy consists of four chains, one for each of the four
PAM facilities. Each chain is a sequence of configuration
statements, each specifying a module to invoke, some
(optional) parameters to pass to the module, and a control
flag that describes how to interpret the return code from the
module.Understanding the control flags is essential to
understanding PAM configuration files. There are four
different control flags:requiredSuccess is required, but the chain continues no
matter what this module returns, so that later modules
can override it.requisiteA negative result from this module will immediately
terminate the chain and deny the request.sufficientA positive result from this module will immediately
terminate the chain and grant the request. On failure,
the chain continues.optionalA negative result from this module will be
ignored.When a server invokes one of the six PAM primitives, PAM
retrieves the chain for the facility the primitive belongs to,
and invokes each of the modules listed in the chain, in the
order they are listed, until it reaches the end, or determines
that no further processing is necessary (either because a
sufficient module succeeded, or because a
requisite module failed.) The request is
granted if and only if at least one module was invoked, and
all non-optional modules succeeded.Note that it is possible, though not very common, to have
the same module listed several times in the same chain. For
instance, a module that looks up user names and passwords in a
directory server could be invoked multiple times with
different parameters specifying different directory servers to
contact. PAM treat different occurrences of the same module
in the same chain as different, unrelated modules.TransactionsThe lifecycle of a typical PAM transaction is described
below. Note that if this any of these steps fails, the server
should report a suitable error message to the client and abort
the transaction.If necessary, the server obtains arbitrator
credentials through a mechanism independent of
PAM—most commonly by virtue of having been started
by root, or of being setuid
root.The server calls pam_start to
initialize the PAM library and specify its service name
and the target account, and register a suitable
conversation function.The server obtains various information relating to the
transaction (such as the applicant's user name and the
name of the host the client runs on) and submits it to PAM
using pam_set_item.The server calls pam_authenticate
to authenticate the applicant.The server calls pam_acct_mgmt to
verify that the requested account is available and valid.
The pam_acct_mgmt function will
return PAM_NEW_AUTHTOK_REQD if the
account's password has expired.If the previous step returned
PAM_NEW_AUTHTOK_REQD, the server now
calls pam_chauthtok to force the
client to change the authentication token for the
requested account.Now that the applicant has been properly
authenticated, the server calls
pam_setcred to establish the
credentials of the requested account. It is able to do
this because it acts on behalf of the arbitrator, and
holds the arbitrator's credentials.Once the correct credentials have been established,
the server calls pam_open_session to
set up the session.The server now performs whatever service the client
requested—for instance, provide the applicant with a
shell.Once the server is done serving the client, it alls
pam_close_session to tear down the
session.Finally, the server calls pam_end
to notify the PAM library that it is done and that it can
release whatever resources it has allocated in the course
of the transaction.PAM ConfigurationLocation of configuration filesThe traditional PAM configuration file is
/etc/pam.conf. This file contains all
the PAM policies for your system. Each line of the file
describes one step in a chain, as shown below:login auth required pam_nologin.so no_warnThe fields are, in order: service name, facility name,
control flag, module name, and module arguments. Any
additional fields are interpreted as additional module
arguments.A separate chain is constructed for each service /
facility pair, so while the order in which lines for the same
service and facility appear is significant, the order in which
the individual services and facilities are listed is
not—except that entries for the other
service, which serves as a fall-back, should come last. The
examples in the original PAM paper grouped configuration lines
by facility, and Solaris' stock pam.conf
still does that, but Linux-PAM (and hence FreeBSD) groups
configuration lines by service. Either way is fine; either
way makes equal sense.Linux-PAM offers an alternate configuration mechanism,
where policies are contained in separate files, named for the
service they apply to, in /etc/pam.d/,
with only four fields instead of five—the service name
field is omitted. In FreeBSD 5.0, starting from mid-January
2002, this is the preferred mechanism. Note, however, that if
/etc/pam.conf exists, and contains
configuration statements for services which do not have a
specific policy in /etc/pam.d/, it will
be used as a fall-back for these services.The great advantage of /etc/pam.d/
over /etc/pam.conf is that it is possible
to use the same policy for multiple services by linking each
service name to a same policy file. For instance, to use the
same policy for the su and
sudo services, one could do as
follows:&prompt.root; cd /etc/pam.d
&prompt.root; ln -s su sudoThis works because the service name is determined from the
file name rather than specified in the policy file, so the
same file can be used for arbitrary services.One other advantage is that third-party software can
easily install policies for their services without the need to
edit /etc/pam.conf.Whether you use /etc/pam.conf or
/etc/pam.d/, the policy for the special
service other is used as a fall-back for
any service that does not have its own policy.Breakdown of a configuration lineAs explained in ,
each line in /etc/pam.conf consists of four
or more fields: the service name, the facility name, the control
flag, the module name, and zero or more module arguments.The service name is generally (though not always) the name
of the application the statement applies to. If you are
unsure, refer to the individual application's documentation to
determine what service name it uses.Note that if you use /etc/pam.d/
instead of /etc/pam.conf, the service
name is specified by the name of the policy file, and omitted
from the actual configuration lines, which then start with the
facility name.The facility is one of the four facility keywords
described in the
section.Likewise, the control flag is one of the four keywords
described in the section,
describing how to interpret the return code from the module.
Linux-PAM supports an alternate syntax that lets you specify
the action to associate with each possible return code, but
this should be avoided as it is non-standard and requires very
detailed knowledge of the PAM library to use properly.PoliciesThis section has not yet been written.PAM ModulesThis section has not yet been written.PAM Application ProgrammingThis section has not yet been written.PAM Module ProgrammingThis section has not yet been written.Sample PAM applicationThe following is a minimal implementation of &man.su.1;
- using PAM. The conversation function has been omitted for
- simplicity.
+ using PAM. Note that it uses the Linux-PAM-specific
+ misc_conv conversation function, which is
+ prototyped in security/pam_misc.h.
- &pam-sample-app;
+Sample PAM moduleThis section has not yet been written.Further ReadingThis is a list of documents relevant to PAM and related
issues. It is by no means complete.
Making Login Services Independent of Authentication
Technologies—the original PAM whitepaper from
Sun.
PAM Administration—an introduction to
configuring and using PAM, from Sun. X/Open
Single Sign-on Preliminary Specification (OpenGroup
members can get the PDF; others will have to register to
download the text version, or buy the paper version.)
Pluggable Authentication Modules—a whitepaper
by Andrew G. Morgan, author of Linux-PAM.
diff --git a/en_US.ISO8859-1/articles/pam/pam-sample-app.sgml b/en_US.ISO8859-1/articles/pam/su.c
similarity index 50%
rename from en_US.ISO8859-1/articles/pam/pam-sample-app.sgml
rename to en_US.ISO8859-1/articles/pam/su.c
index 7e778f999d..8523123986 100644
--- a/en_US.ISO8859-1/articles/pam/pam-sample-app.sgml
+++ b/en_US.ISO8859-1/articles/pam/su.c
@@ -1,146 +1,138 @@
-
-
-#include <sys/param.h>
-#include <sys/wait.h>
-
-#include <err.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include <security/pam_appl.h>
-
-extern int
-converse(int n,
- const struct pam_message **msg,
- struct pam_response **resp,
- void *data);
+/*-
+ * Copyright (c) 2002 Networks Associates Technologies, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by ThinkSec AS and
+ * NAI Labs, the Security Research Division of Network Associates, Inc.
+ * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
+ * DARPA CHATS research program.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
static pam_handle_t *pamh;
static struct pam_conv pamc;
static void
usage(void)
{
fprintf(stderr, "Usage: su [login [args]]\n");
exit(1);
}
static int
check(char *func, int pam_err)
{
if (pam_err == PAM_SUCCESS || pam_err == PAM_NEW_AUTHTOK_REQD)
return pam_err;
openlog("su", LOG_CONS, LOG_AUTH);
syslog(LOG_ERR, "%s(): %s", func, pam_strerror(pamh, pam_err));
errx(1, "Sorry.");
}
int
main(int argc, char *argv[])
{
char hostname[MAXHOSTNAMELEN];
const char *user, *tty;
int o, status;
pid_t pid;
while ((o = getopt(argc, argv, "h")) != -1)
switch (o) {
case 'h':
default:
usage();
}
argc -= optind;
argv += optind;
- if (argc > 0)
+ if (argc > 0)
user = *argv;
else
user = "root";
/* initialize PAM */
- pamc.conv = &converse;
- pam_start("su", user, &pamc, &pamh);
+ pamc.conv = &misc_conv;
+ pam_start("su", user, &pamc, &pamh);
/* set some items */
gethostname(hostname, sizeof hostname);
check("pam_set_item", pam_set_item(pamh, PAM_RHOST, hostname));
user = getlogin();
check("pam_set_item", pam_set_item(pamh, PAM_RUSER, user));
tty = ttyname(STDERR_FILENO);
check("pam_set_item", pam_set_item(pamh, PAM_TTY, tty));
/* authenticate the applicant */
check("pam_authenticate", pam_authenticate(pamh, 0));
if (check("pam_acct_mgmt", pam_acct_mgmt(pamh, 0)) ==
PAM_NEW_AUTHTOK_REQD)
check("pam_chauthtok",
pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK));
/* establish the requested credentials */
check("pam_setcred", pam_setcred(pamh, PAM_ESTABLISH_CRED));
/* authentication succeeded; open a session */
check("pam_open_session", pam_open_session(pamh, 0));
switch ((pid = fork())) {
case -1:
err(1, "fork()");
case 0:
/* child: start a shell */
*argv = "/bin/sh";
execvp(*argv, argv);
err(1, "execvp()");
default:
/* parent: wait for child to exit */
- waitpid(pid, &status, 0);
+ waitpid(pid, &status, 0);
if (WIFEXITED(status))
status = WEXITSTATUS(status);
else
status = 1;
}
/* close the session and release PAM resources */
check("pam_close_session", pam_close_session(pamh, 0));
check("pam_end", pam_end(pamh, 0));
exit(status);
-}
+}