summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2001-05-14 11:23:58 +0000
committermarkm <markm@FreeBSD.org>2001-05-14 11:23:58 +0000
commit8f01d4f9a21b42822e22a8a94f5d7baa665bd832 (patch)
tree8bff886b0f81c1fac698127dc43ca0d5625ad1f2 /lib
parentdb6c759b2bfe8ec70c6b73ef3453944939489372 (diff)
downloadFreeBSD-src-8f01d4f9a21b42822e22a8a94f5d7baa665bd832.zip
FreeBSD-src-8f01d4f9a21b42822e22a8a94f5d7baa665bd832.tar.gz
Bring in a few useful PAM modules.
pam_krb5 is a Kerberos 5 (Heimdal) authentication module. pam_nologin checks for /etc/nologin and does the "usual stuff" if it is found, otherwise it silently succeeds. pam_rootok silently succeeds if the user is root, otherwise it fails. pam_wheel silently succeeds if the user is a member of group "wheel" (or another nominated group), and fails otherwise. There is an issue with kerberosIV and kerberos5 - if both are being built, then static linking fails with duplicate symbols. This will take a bit of work to sort out in the kerberii.
Diffstat (limited to 'lib')
-rw-r--r--lib/libpam/libpam/Makefile7
-rw-r--r--lib/libpam/modules/Makefile7
-rw-r--r--lib/libpam/modules/pam_krb5/COPYRIGHT195
-rw-r--r--lib/libpam/modules/pam_krb5/Makefile44
-rw-r--r--lib/libpam/modules/pam_krb5/README72
-rw-r--r--lib/libpam/modules/pam_krb5/TODO16
-rw-r--r--lib/libpam/modules/pam_krb5/compat_heimdal.c141
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5.8191
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5.h23
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5_acct.c83
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5_auth.c505
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5_pass.c200
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5_sess.c28
-rw-r--r--lib/libpam/modules/pam_krb5/support.c185
-rw-r--r--lib/libpam/modules/pam_nologin/Makefile39
-rw-r--r--lib/libpam/modules/pam_rootok/Makefile39
-rw-r--r--lib/libpam/modules/pam_wheel/Makefile39
17 files changed, 1810 insertions, 4 deletions
diff --git a/lib/libpam/libpam/Makefile b/lib/libpam/libpam/Makefile
index f44f727..455a7d9 100644
--- a/lib/libpam/libpam/Makefile
+++ b/lib/libpam/libpam/Makefile
@@ -70,15 +70,18 @@ STATIC_MODULES+= ${MODOBJDIR}/pam_deny/libpam_deny.a
.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
STATIC_MODULES+= ${MODOBJDIR}/pam_kerberosIV/libpam_kerberosIV.a
.endif
-.if defined(MAKE_KERBEROS5__) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
-STATIC_MODULES+= ${MODOBJDIR}/pam_kerberos5/libpam_kerberos5.a
+.if defined(MAKE_KERBEROS5) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
+STATIC_MODULES+= ${MODOBJDIR}/pam_krb5/libpam_krb5.a
.endif
+STATIC_MODULES+= ${MODOBJDIR}/pam_nologin/libpam_nologin.a
STATIC_MODULES+= ${MODOBJDIR}/pam_opie/libpam_opie.a
STATIC_MODULES+= ${MODOBJDIR}/pam_permit/libpam_permit.a
STATIC_MODULES+= ${MODOBJDIR}/pam_radius/libpam_radius.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_rootok/libpam_rootok.a
STATIC_MODULES+= ${MODOBJDIR}/pam_skey/libpam_skey.a
STATIC_MODULES+= ${MODOBJDIR}/pam_tacplus/libpam_tacplus.a
STATIC_MODULES+= ${MODOBJDIR}/pam_unix/libpam_unix.a
+STATIC_MODULES+= ${MODOBJDIR}/pam_wheel/libpam_wheel.a
STATICOBJS+= pam_static_modules.o
CLEANFILES+= pam_static.o
diff --git a/lib/libpam/modules/Makefile b/lib/libpam/modules/Makefile
index 1b3635d..f722e7c 100644
--- a/lib/libpam/modules/Makefile
+++ b/lib/libpam/modules/Makefile
@@ -29,14 +29,17 @@ SUBDIR+= pam_deny
.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
SUBDIR+= pam_kerberosIV
.endif
-.if defined(MAKE_KERBEROS5__) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
-SUBDIR+= pam_kerberos5
+.if defined(MAKE_KERBEROS5) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
+SUBDIR+= pam_krb5
.endif
+SUBDIR+= pam_nologin
SUBDIR+= pam_opie
SUBDIR+= pam_permit
SUBDIR+= pam_radius
+SUBDIR+= pam_rootok
SUBDIR+= pam_skey
SUBDIR+= pam_tacplus
SUBDIR+= pam_unix
+SUBDIR+= pam_wheel
.include <bsd.subdir.mk>
diff --git a/lib/libpam/modules/pam_krb5/COPYRIGHT b/lib/libpam/modules/pam_krb5/COPYRIGHT
new file mode 100644
index 0000000..42fb642
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/COPYRIGHT
@@ -0,0 +1,195 @@
+pam_krb5:
+
+$FreeBSD$
+
+Copyright (c) Frank Cusack, 1999-2000.
+fcusack@fcusack.com
+All rights reserved
+
+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, and the entire permission notice in its entirety,
+ including the disclaimer of warranties.
+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.
+
+ALTERNATIVELY, this product may be distributed under the terms of
+the GNU Public License, in which case the provisions of the GPL are
+required INSTEAD OF the above restrictions. (This clause is
+necessary due to a potential bad interaction between the GPL and
+the restrictions contained in a BSD-style copyright.)
+
+THIS SOFTWARE IS PROVIDED ``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 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.
+
+---------------------------------------------------------------------------
+
+This software may contain code from Naomaru Itoi:
+
+PAM-kerberos5 module Copyright notice.
+Naomaru Itoi <itoi@eecs.umich.edu>, June 24, 1997.
+
+----------------------------------------------------------------------------
+COPYRIGHT (c) 1997
+THE REGENTS OF THE UNIVERSITY OF MICHIGAN
+ALL RIGHTS RESERVED
+
+PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS AND REDISTRIBUTE
+THIS SOFTWARE AND SUCH DERIVATIVE WORKS FOR ANY PURPOSE, SO LONG AS THE NAME
+OF THE UNIVERSITY OF MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY
+PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE WITHOUT SPECIFIC,
+WRITTEN PRIOR AUTHORIZATION. IF THE ABOVE COPYRIGHT NOTICE OR ANY OTHER
+IDENTIFICATION OF THE UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY
+PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST ALSO BE INCLUDED.
+
+THE SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE UNIVERSITY OF
+MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE
+UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABITILY AND FITNESS FOR A
+PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
+LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN
+CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+PAM-kerberos5 module is written based on PAM-kerberos4 module
+by Derrick J. Brashear and kerberos5-1.0pl1 by M.I.T. kerberos team.
+Permission to use, copy, modify, distribute this software is hereby
+granted, as long as it is granted by Derrick J. Brashear and
+M.I.T. kerberos team. Followings are their copyright information.
+----------------------------------------------------------------------------
+
+This software may contain code from Derrick J. Brashear:
+
+
+Copyright (c) Derrick J. Brashear, 1996. All rights reserved
+
+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, and the entire permission notice in its entirety,
+ including the disclaimer of warranties.
+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.
+
+ALTERNATIVELY, this product may be distributed under the terms of
+the GNU Public License, in which case the provisions of the GPL are
+required INSTEAD OF the above restrictions. (This clause is
+necessary due to a potential bad interaction between the GPL and
+the restrictions contained in a BSD-style copyright.)
+
+THIS SOFTWARE IS PROVIDED ``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 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.
+
+----------------------------------------------------------------------------
+
+This software may contain code from MIT Kerberos 5:
+
+Copyright Notice and Legal Administrivia
+----------------------------------------
+
+Copyright (C) 1996 by the Massachusetts Institute of Technology.
+
+All rights reserved.
+
+Export of this software from the United States of America may require
+a specific license from the United States Government. It is the
+responsibility of any person or organization contemplating export to
+obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission. M.I.T. makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+Individual source code files are copyright MIT, Cygnus Support,
+OpenVision, Oracle, Sun Soft, and others.
+
+Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
+and Zephyr are trademarks of the Massachusetts Institute of Technology
+(MIT). No commercial use of these trademarks may be made without
+prior written permission of MIT.
+
+"Commercial use" means use of a name in a product or other for-profit
+manner. It does NOT prevent a commercial firm from referring to the
+MIT trademarks in order to convey information (although in doing so,
+recognition of their trademark status should be given).
+
+The following copyright and permission notice applies to the
+OpenVision Kerberos Administration system located in kadmin/create,
+kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions
+of lib/rpc:
+
+ Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved
+
+ WARNING: Retrieving the OpenVision Kerberos Administration system
+ source code, as described below, indicates your acceptance of the
+ following terms. If you do not agree to the following terms, do not
+ retrieve the OpenVision Kerberos administration system.
+
+ You may freely use and distribute the Source Code and Object Code
+ compiled from it, with or without modification, but this Source
+ Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY,
+ INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR
+ FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER
+ EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY
+ FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING,
+ WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE
+ CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY
+ OTHER REASON.
+
+ OpenVision retains all copyrights in the donated Source Code. OpenVision
+ also retains copyright to derivative works of the Source Code, whether
+ created by OpenVision or by a third party. The OpenVision copyright
+ notice must be preserved if derivative works are made based on the
+ donated Source Code.
+
+ OpenVision Technologies, Inc. has donated this Kerberos
+ Administration system to MIT for inclusion in the standard
+ Kerberos 5 distribution. This donation underscores our
+ commitment to continuing Kerberos technology development
+ and our gratitude for the valuable work which has been
+ performed by MIT and the Kerberos community.
+
+
diff --git a/lib/libpam/modules/pam_krb5/Makefile b/lib/libpam/modules/pam_krb5/Makefile
new file mode 100644
index 0000000..43f3a77
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/Makefile
@@ -0,0 +1,44 @@
+# Copyright 2001 FreeBSD, Inc.
+# All rights reserved.
+#
+# 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.
+#
+# 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$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+LIB= pam_krb5
+SHLIB_NAME= pam_krb5.so
+SRCS= pam_krb5_auth.c pam_krb5_pass.c pam_krb5_acct.c \
+ pam_krb5_sess.c support.c compat_heimdal.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+CFLAGS+= -I${.CURDIR}/../../libpam
+DPADD+= ${LIBKRB5} ${LIBGSSAPI} ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} \
+ ${LIBCOM_ERR}
+LDADD+= -lkrb5 -lgssapi -lasn1 -lroken -lcrypto -lcrypt -lcom_err \
+ -L${.OBJDIR}/../../../../kerberos5/lib/libroken
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+MAN= pam_krb5.8
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_krb5/README b/lib/libpam/modules/pam_krb5/README
new file mode 100644
index 0000000..ee97421
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/README
@@ -0,0 +1,72 @@
+$FreeBSD$
+
+This is the README for pam_krb5, a PAM module which support Kerberos 5
+authentication.
+
+This software is Copyright (c) 1999-2000 Frank Cusack.
+All Rights Reserved.
+
+See the COPYRIGHT file, included with this distribution, for copyright
+and redistribution information.
+
+Author:
+Frank Cusack
+<fcusack@fcusack.com>
+
+
+I. Kerberos notes
+
+This PAM module requires the MIT 1.1+ release of Kerberos, or the Cygnus
+CNS distribution. It has not been tested against heimdal or any other
+Kerberos distributions.
+
+Unlike other PAM Kerberos 5 modules out there, this one does not
+use any private Kerberos interfaces. Thus, you need only the
+header files and libraries that are part of the Kerberos distribution.
+
+
+II. OS notes
+
+This software has been tested against Solaris 2.6. It should compile
+against Linux (distributions?) with minimal (if any) changes. Reports
+of OS [in]compatibilities are welcomed.
+
+dtlogin on Solaris doesn't support xrealm logins (probably a good thing).
+
+III. PAM notes/open issues
+
+auth module:
+When is pam_sm_setcred() ever called with flags other than PAM_ESTABLISH_CRED
+or PAM_DELETE_CRED?
+
+acct module:
+I believe this to be complete.
+
+session module:
+This is complete (both functions just return success).
+
+passwd module:
+When is pam_sm_chauthtok() ever called with flags other than
+PAM_UPDATE_AUTHTOK?
+
+
+IV. Usage
+
+Simply change /etc/pam.conf to include this module. Make sure to include
+the acct category whenever you use the auth category, or .k5login will
+not get checked.
+
+You probably want to make this module "sufficient", before your unix
+(or other) module(s).
+
+
+V. Acknowledgements
+
+Thanks to Naomaru Itoi <itoi@eecs.umich.edu>,
+Curtis King <curtis.king@cul.ca>, and Derrick Brashear <shadow@dementia.org>,
+all of whom have written and made available Kerberos 4/5 modules.
+Although no code in this module is directly from these author's modules,
+(except the get_user_info() routine in support.c; derived from whichever
+of these authors originally wrote the first module the other 2 copied from),
+it was extremely helpful to look over their code which aided in my design.
+
diff --git a/lib/libpam/modules/pam_krb5/TODO b/lib/libpam/modules/pam_krb5/TODO
new file mode 100644
index 0000000..1f0939f
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/TODO
@@ -0,0 +1,16 @@
+$FreeBSD$
+
+Things for 1.1, in no particular order:
+
+Check against Solaris 7, Solaris 8 beta. Check SEAM compatibility.
+Check against Linux (Redhat, others?).
+Check against HPUX.
+Fix PAM flags checking.
+Add more debugging for successful calls.
+Move "entry" debugging up.
+Check bounds on str* calls. [paranoia]
+
+Get defaults from krb5.conf?
+** Allow no-xrealm, this module typically used for local login **
+** Add notes about runtime text relocation on Solaris **
+
diff --git a/lib/libpam/modules/pam_krb5/compat_heimdal.c b/lib/libpam/modules/pam_krb5/compat_heimdal.c
new file mode 100644
index 0000000..fb4e102
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/compat_heimdal.c
@@ -0,0 +1,141 @@
+/*
+ * compat_heimdal.c
+ *
+ * Heimdal compatability layer.
+ *
+ * $FreeBSD$
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <krb5.h>
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include "pam_krb5.h"
+
+const char *
+compat_princ_component(krb5_context context, krb5_principal princ, int n)
+{
+ return princ->name.name_string.val[n];
+}
+
+void
+compat_free_data_contents(krb5_context context, krb5_data *data)
+{
+ krb5_xfree(data->data);
+}
+
+krb5_error_code
+compat_cc_next_cred(krb5_context context, const krb5_ccache id,
+ krb5_cc_cursor *cursor, krb5_creds *creds)
+{
+ return krb5_cc_next_cred(context, id, creds, cursor);
+}
+
+
+static krb5_error_code
+heimdal_pam_prompter(krb5_context context, void *data, const char *banner, int
+ num_prompts, krb5_prompt prompts[])
+{
+ int pam_prompts = num_prompts;
+ int pamret, i;
+
+ struct pam_message *msg;
+ struct pam_response *resp = NULL;
+ struct pam_conv *conv;
+ pam_handle_t *pamh = (pam_handle_t *) data;
+
+ if ((pamret = pam_get_item(pamh, PAM_CONV, (const void **) &conv)) != 0)
+ return KRB5KRB_ERR_GENERIC;
+
+ if (banner)
+ pam_prompts++;
+
+ msg = calloc(sizeof(struct pam_message) * pam_prompts, 1);
+ if (!msg)
+ return ENOMEM;
+
+ /* Now use pam_prompts as an index */
+ pam_prompts = 0;
+
+ if (banner) {
+ msg[pam_prompts].msg = malloc(strlen(banner) + 1);
+ if (!msg[pam_prompts].msg)
+ goto cleanup;
+ strcpy((char *) msg[pam_prompts].msg, banner);
+ msg[pam_prompts].msg_style = PAM_TEXT_INFO;
+ pam_prompts++;
+ }
+
+ for (i = 0; i < num_prompts; i++) {
+ msg[pam_prompts].msg = malloc(strlen(prompts[i].prompt) + 3);
+ if (!msg[pam_prompts].msg)
+ goto cleanup;
+ sprintf((char *) msg[pam_prompts].msg, "%s: ", prompts[i].prompt);
+ msg[pam_prompts].msg_style = prompts[i].hidden ? PAM_PROMPT_ECHO_OFF
+ : PAM_PROMPT_ECHO_ON;
+ pam_prompts++;
+ }
+
+ if ((pamret = conv->conv(pam_prompts, (const struct pam_message **) &msg,
+ &resp, conv->appdata_ptr)) != 0)
+ goto cleanup;
+
+ if (!resp)
+ goto cleanup;
+
+ /* Reuse pam_prompts as a starting index */
+ pam_prompts = 0;
+ if (banner)
+ pam_prompts++;
+
+ for (i = 0; i < num_prompts; i++, pam_prompts++) {
+ register int len;
+ if (!resp[pam_prompts].resp) {
+ pamret = PAM_AUTH_ERR;
+ goto cleanup;
+ }
+ len = strlen(resp[pam_prompts].resp); /* Help out the compiler */
+ if (len > prompts[i].reply->length) {
+ pamret = PAM_AUTH_ERR;
+ goto cleanup;
+ }
+ memcpy(prompts[i].reply->data, resp[pam_prompts].resp, len);
+ prompts[i].reply->length = len;
+ }
+
+cleanup:
+ /* pam_prompts is correct at this point */
+
+ for (i = 0; i < pam_prompts; i++) {
+ if (msg[i].msg)
+ free((char *) msg[i].msg);
+ }
+ free(msg);
+
+ if (resp) {
+ for (i = 0; i < pam_prompts; i++) {
+ /*
+ * Note that PAM is underspecified wrt free()'ing resp[i].resp.
+ * It's not clear if I should free it, or if the application
+ * has to. Therefore most (all?) apps won't free() it, and I
+ * can't either, as I am not sure it was malloc()'d. All PAM
+ * implementations I've seen leak memory here. Not so bad, IFF
+ * you fork/exec for each PAM authentication (as is typical).
+ */
+#if 0
+ if (resp[i].resp)
+ free(resp[i].resp);
+#endif /* 0 */
+ }
+ /* This does not lose resp[i].resp if the application saved a copy. */
+ free(resp);
+ }
+
+ return (pamret ? KRB5KRB_ERR_GENERIC : 0);
+}
+
+krb5_prompter_fct pam_prompter = heimdal_pam_prompter;
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5.8 b/lib/libpam/modules/pam_krb5/pam_krb5.8
new file mode 100644
index 0000000..7ef1211
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam_krb5.8
@@ -0,0 +1,191 @@
+.\"
+.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $
+.\" $FreeBSD$
+.TH pam_krb5 8 "15 Jan 1999"
+.SH NAME
+pam_krb5 \- Kerberos 5 PAM module
+.SH SYNOPSIS
+.LP
+.B /usr/lib/pam_krb5.so
+.LP
+.SH DESCRIPTION
+.IX "pam_krb5" "" "\fLpam_krb5\fP \(em Kerberos 5 PAM module"
+.PP
+The Kerberos 5 service module for PAM, typically
+.BR /usr/lib/pam_krb5.so ,
+provides functionality for three PAM categories:
+authentication,
+account management,
+and password management.
+It also provides null functions for session management.
+The
+.B pam_krb5.so
+module is a shared object
+that can be dynamically loaded to provide
+the necessary functionality upon demand.
+Its path is specified in the
+.SM PAM
+configuration file.
+.SH Kerberos 5 Authentication Module
+The Kerberos 5 authentication component
+provides functions to verify the identity of a user.
+(\f3pam_sm_authenticate(\|)\f1)
+and to set user specific credentials
+(\f3pam_sm_setcred(\|)\f1).
+.B pam_sm_authenticate(\|)
+converts the supplied username into a Kerberos principal,
+by appending the default local realm name.
+It also supports usernames with explicit realm names.
+If a realm name is supplied, then upon a sucessful return, it
+changes the username by mapping the principal name into a local username
+(calling \f3krb5_aname_to_localname()\f1). This typically just means
+the realm name is stripped.
+.LP
+It prompts the user for a password and obtains a new Kerberos TGT for
+the principal. The TGT is verified by obtaining a service
+ticket for the local host.
+.LP
+When prompting for the current password, the authentication
+module will use the prompt "Password for <principal>: ".
+.LP
+The
+.B pam_sm_setcred(\|)
+function stores the newly acquired credentials in a credentials cache,
+and sets the environment variable
+.B KRB5CCNAME
+appropriately.
+The credentials cache should be destroyed by the user at logout with
+.BR kdestroy (1) .
+.LP
+The following options may be passed to the authentication module:
+.TP 15
+.B debug
+.BR syslog (3)
+debugging information at
+.SB LOG_DEBUG
+level.
+.TP
+.B use_first_pass
+If the authentication module is not the first in the stack,
+and a previous module obtained the user's password, that password is
+used to authenticate the user. If this fails, the authentication
+module returns failure without prompting the user for a password.
+This option has no effect if the authentication module is
+the first in the stack, or if no previous modules obtained the
+user's password.
+.TP
+.B try_first_pass
+This option is similar to the
+.B use_first_pass
+option, except that if the previously obtained password fails, the
+user is prompted for another password.
+.TP
+.B forwardable
+Obtain forwardable Kerberos credentials for the user.
+.TP
+.B no_ccache
+Do not save the obtained credentials in a credentials cache. This is a
+useful option if the authentication module is used for services such
+as ftp or pop, where the user would not be able to destroy them. [This
+is not a recommendation to use the module for those services.]
+.TP
+.B ccache=<name>
+Use <name> as the credentials cache. <name> must be in the form
+.IR type:residual .
+The special tokens
+.BR %u ,
+to designate the decimal uid of the user;
+and
+.BR %p ,
+to designate the current process id; can be used in <name>.
+.SH Kerberos 5 Account Management Module
+The Kerberos 5 account management component
+provides a function to perform account management,
+.BR pam_sm_acct_mgmt(\|) .
+The function verifies that the authenticated principal is allowed
+to login to the local user account by calling
+.B krb5_kuserok()
+(which checks the user's \&.k5login file).
+.SH Kerberos 5 Password Management Module
+The Kerberos 5 password management component
+provides a function to change passwords
+(\f3pam_sm_chauthtok(\|)\f1). The username supplied (the
+user running the
+.BR passwd (1)
+command, or the username given as an argument) is mapped into
+a Kerberos principal name, using the same technique as in
+the authentication module. Note that if a realm name was
+explicitly supplied during authentication, but not during
+a password change, the mapping
+done by the password management module may not result in the
+same principal as was used for authentication.
+.LP
+Unlike when
+changing a unix password, the password management module will
+allow any user to change any principal's password (if the user knows
+the principal's old password, of course). Also unlike unix, root
+is always prompted for the principal's old password.
+.LP
+The password management module uses the same heuristics as
+.BR kpasswd (1)
+to determine how to contact the Kerberos password server.
+.LP
+The following options may be passed to the password management
+module:
+.TP 15
+.B debug
+.BR syslog (3)
+debugging information at
+.SB LOG_DEBUG
+level.
+.TP
+.B use_first_pass
+If the password management module is not the first in the stack,
+and a previous module obtained the user's old password, that password is
+used to authenticate the user. If this fails, the password
+management
+module returns failure without prompting the user for the old password.
+If successful, the new password entered to the previous module is also
+used as the new Kerberos password. If the new password fails,
+the password management module returns failure without
+prompting the user for a new password.
+.TP
+.B try_first_pass
+This option is similar to the
+.B use_first_pass
+option, except that if the previously obtained old or new passwords fail,
+the user is prompted for them.
+.SH Kerberos 5 Session Management Module
+The Kerberos 5 session management component
+provides functions to initiate
+(\f3pam_sm_open_session(\|)\f1)
+and terminate
+(\f3pam_sm_close_session(\|)\f1)
+sessions. Since session management is not defined under Kerberos 5,
+both of these functions simply return success. They are provided
+only because of the naming conventions for PAM modules.
+.SH ENVIRONMENT
+.TP "\w'.SM KRB5CCNAME\ \ 'u"
+.SM KRB5CCNAME
+Location of the credentials cache.
+.SH FILES
+.TP "\w'/tmp/krb5cc_[uid]\ \ 'u"
+/tmp/krb5cc_[uid]
+default credentials cache ([uid] is the decimal UID of the user).
+.TP
+~/\&.k5login
+file containing Kerberos principals that are allowed access.
+.SH SEE ALSO
+.BR kdestroy (1),
+.BR passwd (1),
+.BR pam (8),
+.BR syslog (3),
+.BR pam.conf (5).
+.SH NOTES
+Applications should not call
+.B pam_authenticate()
+more than once between calls to
+.B pam_start()
+and
+.B pam_end()
+when using the Kerberos 5 PAM module.
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5.h b/lib/libpam/modules/pam_krb5/pam_krb5.h
new file mode 100644
index 0000000..ff02373
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam_krb5.h
@@ -0,0 +1,23 @@
+/*
+ * pam_krb5.h
+ *
+ * $Id: pam_krb5.h,v 1.5 1999/01/19 23:43:10 fcusack Exp $
+ * $FreeBSD$
+ */
+
+int get_user_info(pam_handle_t *, char *, int, char **);
+int verify_krb_v5_tgt(krb5_context, krb5_ccache, char *, int);
+void cleanup_cache(pam_handle_t *, void *, int);
+
+krb5_prompter_fct pam_prompter;
+
+const char *compat_princ_component(krb5_context, krb5_principal, int);
+void compat_free_data_contents(krb5_context, krb5_data *);
+krb5_error_code compat_cc_next_cred(krb5_context, const krb5_ccache,
+ krb5_cc_cursor *, krb5_creds *);
+
+#ifndef ENCTYPE_DES_CBC_MD5
+#define ENCTYPE_DES_CBC_MD5 ETYPE_DES_CBC_MD5
+#endif
+
+
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5_acct.c b/lib/libpam/modules/pam_krb5/pam_krb5_acct.c
new file mode 100644
index 0000000..1a2910b
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam_krb5_acct.c
@@ -0,0 +1,83 @@
+/*
+ * pam_krb5_acct.c
+ *
+ * PAM account management functions for pam_krb5
+ *
+ * $FreeBSD$
+ */
+
+static const char rcsid[] = "$Id: pam_krb5_acct.c,v 1.3 1999/01/19 21:26:44 fcusack Exp $";
+
+#include <syslog.h> /* syslog */
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include <krb5.h>
+#include <com_err.h>
+#include "pam_krb5.h"
+
+/* A useful logging macro */
+#define DLOG(error_func, error_msg) \
+if (debug) \
+ syslog(LOG_DEBUG, "pam_krb5: pam_sm_acct_mgmt(%s %s): %s: %s", \
+ service, name, error_func, error_msg)
+
+/* Check authorization of user */
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ krb5_error_code krbret;
+ krb5_context pam_context;
+ krb5_ccache ccache;
+ krb5_principal princ;
+
+ char *service, *name;
+ int debug = 0;
+ int i, pamret;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ debug = 1;
+ }
+
+ /* Get username */
+ if (pam_get_item(pamh, PAM_USER, (const void **) &name)) {
+ return PAM_PERM_DENIED;;
+ }
+
+ /* Get service name */
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
+ if (!service)
+ service = "unknown";
+
+ DLOG("entry", "");
+
+ if (pam_get_data(pamh, "ccache", (const void **) &ccache)) {
+ /* User did not use krb5 to login */
+ DLOG("ccache", "not found");
+ return PAM_SUCCESS;
+ }
+
+ if ((krbret = krb5_init_context(&pam_context)) != 0) {
+ DLOG("krb5_init_context()", error_message(krbret));
+ return PAM_PERM_DENIED;;
+ }
+
+ if ((krbret = krb5_cc_get_principal(pam_context, ccache, &princ)) != 0) {
+ DLOG("krb5_cc_get_principal()", error_message(krbret));
+ pamret = PAM_PERM_DENIED;;
+ goto cleanup;
+ }
+
+ if (krb5_kuserok(pam_context, princ, name))
+ pamret = PAM_SUCCESS;
+ else
+ pamret = PAM_PERM_DENIED;
+ krb5_free_principal(pam_context, princ);
+
+cleanup:
+ krb5_free_context(pam_context);
+ DLOG("exit", pamret ? "failure" : "success");
+ return pamret;
+
+}
+
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5_auth.c b/lib/libpam/modules/pam_krb5/pam_krb5_auth.c
new file mode 100644
index 0000000..fd4270b
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam_krb5_auth.c
@@ -0,0 +1,505 @@
+/*
+ * pam_krb5_auth.c
+ *
+ * PAM authentication management functions for pam_krb5
+ *
+ * $FreeBSD$
+ */
+
+static const char rcsid[] = "$Id: pam_krb5_auth.c,v 1.18 2000/01/04 08:44:08 fcusack Exp $";
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h> /* PATH_MAX */
+#include <pwd.h> /* getpwnam */
+#include <stdio.h> /* tmpnam */
+#include <stdlib.h> /* malloc */
+#include <strings.h> /* strchr */
+#include <syslog.h> /* syslog */
+#include <unistd.h> /* chown */
+
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+#include <krb5.h>
+#include <com_err.h>
+#include "pam_krb5.h"
+
+extern krb5_cc_ops krb5_mcc_ops;
+
+/* A useful logging macro */
+#define DLOG(error_func, error_msg) \
+if (debug) \
+ syslog(LOG_DEBUG, "pam_krb5: pam_sm_authenticate(%s %s): %s: %s", \
+ service, name, error_func, error_msg)
+
+/* Authenticate a user via krb5 */
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ krb5_error_code krbret;
+ krb5_context pam_context;
+ krb5_creds creds;
+ krb5_principal princ;
+ krb5_ccache ccache, ccache_check;
+ krb5_get_init_creds_opt opts;
+
+ int pamret, i;
+ const char *name;
+ char *source_princ = NULL;
+ char *princ_name = NULL;
+ char *pass = NULL, *service = NULL;
+ char *prompt = NULL;
+ char cache_name[L_tmpnam + 8];
+ char lname[64]; /* local acct name */
+ struct passwd *pw;
+ uid_t ruid;
+
+ int debug = 0, try_first_pass = 0, use_first_pass = 0;
+ int forwardable = 0, reuse_ccache = 0, no_ccache = 0;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ debug = 1;
+ else if (strcmp(argv[i], "try_first_pass") == 0)
+ try_first_pass = 1;
+ else if (strcmp(argv[i], "use_first_pass") == 0)
+ use_first_pass = 1;
+ else if (strcmp(argv[i], "forwardable") == 0)
+ forwardable = 1;
+ else if (strcmp(argv[i], "reuse_ccache") == 0)
+ reuse_ccache = 1;
+ else if (strcmp(argv[i], "no_ccache") == 0)
+ no_ccache = 1;
+ }
+
+ /* Get username */
+ if ((pamret = pam_get_user(pamh, &name, "login: ")) != PAM_SUCCESS) {
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Get service name */
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
+ if (!service)
+ service = "unknown";
+
+ DLOG("entry", "");
+
+ if ((krbret = krb5_init_context(&pam_context)) != 0) {
+ DLOG("krb5_init_context()", error_message(krbret));
+ return PAM_SERVICE_ERR;
+ }
+ krb5_get_init_creds_opt_init(&opts);
+ memset(&creds, 0, sizeof(krb5_creds));
+ memset(cache_name, 0, sizeof(cache_name));
+ memset(lname, 0, sizeof(lname));
+
+ if (forwardable)
+ krb5_get_init_creds_opt_set_forwardable(&opts, 1);
+
+ /* For CNS */
+ if ((krbret = krb5_cc_register(pam_context, &krb5_mcc_ops, FALSE)) != 0) {
+ /* Solaris dtlogin doesn't call pam_end() on failure */
+ if (krbret != KRB5_CC_TYPE_EXISTS) {
+ DLOG("krb5_cc_register()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup3;
+ }
+ }
+
+ /* Get principal name */
+ /* This case is for use mainly by su.
+ If non-root is authenticating as "root", use "source_user/root". */
+ if (!strcmp(name, "root") && (ruid = getuid()) != 0) {
+ pw = getpwuid(ruid);
+ if (pw != NULL)
+ source_princ = (char *)malloc(strlen(pw->pw_name) + 6);
+ if (source_princ)
+ sprintf(source_princ, "%s/root", pw->pw_name);
+ } else {
+ source_princ = strdup(name);
+ }
+ if (!source_princ) {
+ DLOG("malloc()", "failure");
+ pamret = PAM_BUF_ERR;
+ goto cleanup2;
+ }
+
+ if ((krbret = krb5_parse_name(pam_context, source_princ, &princ)) != 0) {
+ DLOG("krb5_parse_name()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup3;
+ }
+
+ /* Now convert the principal name into something human readable */
+ if ((krbret = krb5_unparse_name(pam_context, princ, &princ_name)) != 0) {
+ DLOG("krb5_unparse_name()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+
+ /* Get password */
+ prompt = malloc(16 + strlen(princ_name));
+ if (!prompt) {
+ DLOG("malloc()", "failure");
+ pamret = PAM_BUF_ERR;
+ goto cleanup2;
+ }
+ (void) sprintf(prompt, "Password for %s: ", princ_name);
+
+ if (try_first_pass || use_first_pass)
+ (void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
+
+get_pass:
+ if (!pass) {
+ try_first_pass = 0;
+ if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF,
+ &pass)) != 0) {
+ DLOG("get_user_info()", pam_strerror(pamh, pamret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ /* We have to free pass. */
+ if ((pamret = pam_set_item(pamh, PAM_AUTHTOK, pass)) != 0) {
+ DLOG("pam_set_item()", pam_strerror(pamh, pamret));
+ free(pass);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ free(pass);
+ /* Now we get it back from the library. */
+ (void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
+ }
+
+ /* get a local account name for this principal */
+ if ((krbret = krb5_aname_to_localname(pam_context, princ,
+ sizeof(lname), lname)) == 0) {
+ DLOG("changing PAM_USER to", lname);
+ if ((pamret = pam_set_item(pamh, PAM_USER, lname)) != 0) {
+ DLOG("pam_set_item()", pam_strerror(pamh, pamret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ if ((pamret = pam_get_item(pamh, PAM_USER, (const void **) &name)
+ != 0)) {
+ DLOG("pam_get_item()", pam_strerror(pamh, pamret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ } else {
+ DLOG("krb5_aname_to_localname()", error_message(krbret));
+ /* Not an error. */
+ }
+
+ /* Verify the local user exists (AFTER getting the password) */
+ pw = getpwnam(name);
+ if (!pw) {
+ DLOG("getpwnam()", lname);
+ pamret = PAM_USER_UNKNOWN;
+ goto cleanup2;
+ }
+
+ /* Get a TGT */
+ if ((krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
+ pass, pam_prompter, pamh, 0, NULL, &opts)) != 0) {
+ DLOG("krb5_get_init_creds_password()", error_message(krbret));
+ if (try_first_pass && krbret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ pass = NULL;
+ goto get_pass;
+ }
+ pamret = PAM_AUTH_ERR;
+ goto cleanup2;
+ }
+
+ /* Generate a unique cache_name */
+ strcpy(cache_name, "MEMORY:");
+ (void) tmpnam(&cache_name[7]);
+
+ if ((krbret = krb5_cc_resolve(pam_context, cache_name, &ccache)) != 0) {
+ DLOG("krb5_cc_resolve()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup;
+ }
+ if ((krbret = krb5_cc_initialize(pam_context, ccache, princ)) != 0) {
+ DLOG("krb5_cc_initialize()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup;
+ }
+ if ((krbret = krb5_cc_store_cred(pam_context, ccache, &creds)) != 0) {
+ DLOG("krb5_cc_store_cred()", error_message(krbret));
+ (void) krb5_cc_destroy(pam_context, ccache);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup;
+ }
+
+ /* Verify it */
+ if (verify_krb_v5_tgt(pam_context, ccache, service, debug) == -1) {
+ (void) krb5_cc_destroy(pam_context, ccache);
+ pamret = PAM_AUTH_ERR;
+ goto cleanup;
+ }
+
+ /* A successful authentication, store ccache for sm_setcred() */
+ if (!pam_get_data(pamh, "ccache", (const void **) &ccache_check)) {
+ DLOG("pam_get_data()", "ccache data already present");
+ (void) krb5_cc_destroy(pam_context, ccache);
+ pamret = PAM_AUTH_ERR;
+ goto cleanup;
+ }
+ if ((pamret = pam_set_data(pamh, "ccache", ccache, cleanup_cache)) != 0) {
+ DLOG("pam_set_data()", pam_strerror(pamh, pamret));
+ (void) krb5_cc_destroy(pam_context, ccache);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup;
+ }
+
+cleanup:
+ krb5_free_cred_contents(pam_context, &creds);
+cleanup2:
+ krb5_free_principal(pam_context, princ);
+cleanup3:
+ if (prompt)
+ free(prompt);
+ if (princ_name)
+ free(princ_name);
+ if (source_princ)
+ free(source_princ);
+
+ krb5_free_context(pam_context);
+ DLOG("exit", pamret ? "failure" : "success");
+ return pamret;
+}
+
+
+
+/* redefine this for pam_sm_setcred() */
+#undef DLOG
+#define DLOG(error_func, error_msg) \
+if (debug) \
+ syslog(LOG_DEBUG, "pam_krb5: pam_sm_setcred(%s %s): %s: %s", \
+ service, name, error_func, error_msg)
+
+/* Called after a successful authentication. Set user credentials. */
+int
+pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+
+ krb5_error_code krbret;
+ krb5_context pam_context;
+ krb5_principal princ;
+ krb5_creds creds;
+ krb5_ccache ccache_temp, ccache_perm;
+ krb5_cc_cursor cursor;
+
+ int i, pamret;
+ char *name, *service = NULL;
+ char *cache_name = NULL, *cache_env_name;
+ struct passwd *pw = NULL;
+
+ int debug = 0;
+ uid_t euid;
+ gid_t egid;
+
+ if (flags == PAM_REINITIALIZE_CRED)
+ return PAM_SUCCESS; /* XXX Incorrect behavior */
+
+ if (flags != PAM_ESTABLISH_CRED && flags != PAM_DELETE_CRED)
+ return PAM_SERVICE_ERR;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ debug = 1;
+ else if (strcmp(argv[i], "no_ccache") == 0)
+ return PAM_SUCCESS;
+ else if (strstr(argv[i], "ccache=") == argv[i])
+ cache_name = (char *) &argv[i][7]; /* save for later */
+ }
+
+ /* Get username */
+ if (pam_get_item(pamh, PAM_USER, (const void **) &name)) {
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Get service name */
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
+ if (!service)
+ service = "unknown";
+
+ DLOG("entry", "");
+
+ if ((krbret = krb5_init_context(&pam_context)) != 0) {
+ DLOG("krb5_init_context()", error_message(krbret));
+ return PAM_SERVICE_ERR;
+ }
+
+ euid = geteuid(); /* Usually 0 */
+ egid = getegid();
+
+ /* Retrieve the cache name */
+ if ((pamret = pam_get_data(pamh, "ccache", (const void **) &ccache_temp))
+ != 0) {
+ /* User did not use krb5 to login */
+ DLOG("ccache", "not found");
+ pamret = PAM_SUCCESS;
+ goto cleanup3;
+ }
+
+ /* Get the uid. This should exist. */
+ pw = getpwnam(name);
+ if (!pw) {
+ DLOG("getpwnam()", name);
+ pamret = PAM_USER_UNKNOWN;
+ goto cleanup3;
+ }
+
+ /* Avoid following a symlink as root */
+ if (setegid(pw->pw_gid)) {
+ DLOG("setegid()", name); /* XXX should really log group name or id */
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup3;
+ }
+ if (seteuid(pw->pw_uid)) {
+ DLOG("seteuid()", name);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup3;
+ }
+
+ /* Get the cache name */
+ if (!cache_name) {
+ cache_name = malloc(64); /* plenty big */
+ if (!cache_name) {
+ DLOG("malloc()", "failure");
+ pamret = PAM_BUF_ERR;
+ goto cleanup3;
+ }
+ sprintf(cache_name, "FILE:/tmp/krb5cc_%d", pw->pw_uid);
+ } else {
+ /* cache_name was supplied */
+ char *p = calloc(PATH_MAX + 10, 1); /* should be plenty */
+ char *q = cache_name;
+ if (!p) {
+ DLOG("malloc()", "failure");
+ pamret = PAM_BUF_ERR;
+ goto cleanup3;
+ }
+ cache_name = p;
+
+ /* convert %u and %p */
+ while (*q) {
+ if (*q == '%') {
+ q++;
+ if (*q == 'u') {
+ sprintf(p, "%d", pw->pw_uid);
+ p += strlen(p);
+ } else if (*q == 'p') {
+ sprintf(p, "%d", getpid());
+ p += strlen(p);
+ } else {
+ /* Not a special token */
+ *p++ = '%';
+ q--;
+ }
+ q++;
+ } else {
+ *p++ = *q++;
+ }
+ }
+ }
+
+ if ((krbret = krb5_cc_resolve(pam_context, cache_name, &ccache_perm))
+ != 0) {
+ DLOG("krb5_cc_resolve()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup3;
+ }
+ if (flags == PAM_ESTABLISH_CRED) {
+ /* Initialize the new ccache */
+ if ((krbret = krb5_cc_get_principal(pam_context, ccache_temp, &princ))
+ != 0) {
+ DLOG("krb5_cc_get_principal()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup3;
+ }
+ if ((krbret = krb5_cc_initialize(pam_context, ccache_perm, princ)) != 0) {
+ DLOG("krb5_cc_initialize()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+
+ /* Prepare for iteration over creds */
+ if ((krbret = krb5_cc_start_seq_get(pam_context, ccache_temp, &cursor))
+ != 0) {
+ DLOG("krb5_cc_start_seq_get()", error_message(krbret));
+ (void) krb5_cc_destroy(pam_context, ccache_perm);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+
+ /* Copy the creds (should be two of them) */
+ while ((krbret = compat_cc_next_cred(pam_context, ccache_temp,
+ &cursor, &creds) == 0)) {
+ if ((krbret = krb5_cc_store_cred(pam_context, ccache_perm,
+ &creds)) != 0) {
+ DLOG("krb5_cc_store_cred()", error_message(krbret));
+ (void) krb5_cc_destroy(pam_context, ccache_perm);
+ krb5_free_cred_contents(pam_context, &creds);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ krb5_free_cred_contents(pam_context, &creds);
+ }
+ (void) krb5_cc_end_seq_get(pam_context, ccache_temp, &cursor);
+
+ if (strstr(cache_name, "FILE:") == cache_name) {
+ if (chown(&cache_name[5], pw->pw_uid, pw->pw_gid) == -1) {
+ DLOG("chown()", strerror(errno));
+ (void) krb5_cc_destroy(pam_context, ccache_perm);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ if (chmod(&cache_name[5], (S_IRUSR|S_IWUSR)) == -1) {
+ DLOG("chmod()", strerror(errno));
+ (void) krb5_cc_destroy(pam_context, ccache_perm);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ }
+ (void) krb5_cc_close(pam_context, ccache_perm);
+
+ cache_env_name = malloc(strlen(cache_name) + 12);
+ if (!cache_env_name) {
+ DLOG("malloc()", "failure");
+ (void) krb5_cc_destroy(pam_context, ccache_perm);
+ pamret = PAM_BUF_ERR;
+ goto cleanup2;
+ }
+
+ sprintf(cache_env_name, "KRB5CCNAME=%s", cache_name);
+ if ((pamret = pam_putenv(pamh, cache_env_name)) != 0) {
+ DLOG("pam_putenv()", pam_strerror(pamh, pamret));
+ (void) krb5_cc_destroy(pam_context, ccache_perm);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ } else {
+ /* flag == PAM_DELETE_CRED */
+ if ((krbret = krb5_cc_destroy(pam_context, ccache_perm)) != 0) {
+ /* log error, but otherwise ignore it */
+ DLOG("krb5_cc_destroy()", error_message(krbret));
+ }
+ goto cleanup3;
+ }
+
+cleanup2:
+ krb5_free_principal(pam_context, princ);
+cleanup3:
+ krb5_free_context(pam_context);
+ DLOG("exit", pamret ? "failure" : "success");
+ (void) seteuid(euid);
+ (void) setegid(egid);
+ return pamret;
+}
+
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5_pass.c b/lib/libpam/modules/pam_krb5/pam_krb5_pass.c
new file mode 100644
index 0000000..994c7f4
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam_krb5_pass.c
@@ -0,0 +1,200 @@
+/*
+ * pam_krb5_pass.c
+ *
+ * PAM password management functions for pam_krb5
+ *
+ * $FreeBSD$
+ */
+
+static const char rcsid[] = "$Id: pam_krb5_pass.c,v 1.3 1999/01/19 23:43:11 fcusack Exp $";
+
+#include <errno.h>
+#include <stdio.h> /* sprintf */
+#include <stdlib.h> /* malloc */
+#include <syslog.h> /* syslog */
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include <krb5.h>
+#include <com_err.h>
+#include "pam_krb5.h"
+
+/* A useful logging macro */
+#define DLOG(error_func, error_msg) \
+if (debug) \
+ syslog(LOG_DEBUG, "pam_krb5: pam_sm_chauthtok(%s %s): %s: %s", \
+ service, name, error_func, error_msg)
+
+/* Change a user's password */
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ krb5_error_code krbret;
+ krb5_context pam_context;
+ krb5_creds creds;
+ krb5_principal princ;
+ krb5_get_init_creds_opt opts;
+
+ int result_code;
+ krb5_data result_code_string, result_string;
+
+ int pamret, i;
+ char *name, *service = NULL, *pass = NULL, *pass2;
+ char *princ_name = NULL;
+ char *prompt = NULL;
+
+ int debug = 0;
+ int try_first_pass = 0, use_first_pass = 0;
+
+ if (!(flags & PAM_UPDATE_AUTHTOK))
+ return PAM_AUTHTOK_ERR;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ debug = 1;
+ else if (strcmp(argv[i], "try_first_pass") == 0)
+ try_first_pass = 1;
+ else if (strcmp(argv[i], "use_first_pass") == 0)
+ use_first_pass = 1;
+ }
+
+ /* Get username */
+ if ((pam_get_item(pamh, PAM_USER, (const void **) &name)) != 0) {
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Get service name */
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
+ if (!service)
+ service = "unknown";
+
+ DLOG("entry", "");
+
+ if ((krbret = krb5_init_context(&pam_context)) != 0) {
+ DLOG("krb5_init_context()", error_message(krbret));
+ return PAM_SERVICE_ERR;
+ }
+
+ if ((krbret = krb5_init_context(&pam_context)) != 0) {
+ DLOG("krb5_init_context()", error_message(krbret));
+ return PAM_SERVICE_ERR;
+ }
+ krb5_get_init_creds_opt_init(&opts);
+ memset(&creds, 0, sizeof(krb5_creds));
+
+ /* Get principal name */
+ if ((krbret = krb5_parse_name(pam_context, name, &princ)) != 0) {
+ DLOG("krb5_parse_name()", error_message(krbret));
+ pamret = PAM_USER_UNKNOWN;
+ goto cleanup3;
+ }
+
+ /* Now convert the principal name into something human readable */
+ if ((krbret = krb5_unparse_name(pam_context, princ, &princ_name)) != 0) {
+ DLOG("krb5_unparse_name()", error_message(krbret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+
+ /* Get password */
+ prompt = malloc(16 + strlen(princ_name));
+ if (!prompt) {
+ DLOG("malloc()", "failure");
+ pamret = PAM_BUF_ERR;
+ goto cleanup2;
+ }
+ (void) sprintf(prompt, "Password for %s: ", princ_name);
+
+ if (try_first_pass || use_first_pass)
+ (void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
+
+get_pass:
+ if (!pass) {
+ try_first_pass = 0;
+ if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF,
+ &pass)) != 0) {
+ DLOG("get_user_info()", pam_strerror(pamh, pamret));
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ /* We have to free pass. */
+ if ((pamret = pam_set_item(pamh, PAM_AUTHTOK, pass)) != 0) {
+ DLOG("pam_set_item()", pam_strerror(pamh, pamret));
+ free(pass);
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup2;
+ }
+ free(pass);
+ /* Now we get it back from the library. */
+ (void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
+ }
+
+ if ((krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
+ pass, pam_prompter, pamh, 0, "kadmin/changepw", &opts)) != 0) {
+ DLOG("krb5_get_init_creds_password()", error_message(krbret));
+ if (try_first_pass && krbret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ pass = NULL;
+ goto get_pass;
+ }
+ pamret = PAM_AUTH_ERR;
+ goto cleanup2;
+ }
+
+ /* Now get the new password */
+ free(prompt);
+ prompt = "Enter new password: ";
+ if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF, &pass))
+ != 0) {
+ DLOG("get_user_info()", pam_strerror(pamh, pamret));
+ prompt = NULL;
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup;
+ }
+ prompt = "Enter it again: ";
+ if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF, &pass2))
+ != 0) {
+ DLOG("get_user_info()", pam_strerror(pamh, pamret));
+ prompt = NULL;
+ pamret = PAM_SERVICE_ERR;
+ goto cleanup;
+ }
+ prompt = NULL;
+
+ if (strcmp(pass, pass2) != 0) {
+ DLOG("strcmp()", "passwords not equal");
+ pamret = PAM_AUTHTOK_ERR;
+ goto cleanup;
+ }
+
+ /* Change it */
+ if ((krbret = krb5_change_password(pam_context, &creds, pass,
+ &result_code, &result_code_string, &result_string)) != 0) {
+ DLOG("krb5_change_password()", error_message(krbret));
+ pamret = PAM_AUTHTOK_ERR;
+ goto cleanup;
+ }
+ if (result_code) {
+ DLOG("krb5_change_password() (result_code)", "");
+ pamret = PAM_AUTHTOK_ERR;
+ goto cleanup;
+ }
+
+ if (result_string.data)
+ free(result_string.data);
+ if (result_code_string.data)
+ free(result_code_string.data);
+
+cleanup:
+ krb5_free_cred_contents(pam_context, &creds);
+cleanup2:
+ krb5_free_principal(pam_context, princ);
+cleanup3:
+ if (prompt)
+ free(prompt);
+ if (princ_name)
+ free(princ_name);
+
+ krb5_free_context(pam_context);
+ DLOG("exit", pamret ? "failure" : "success");
+ return pamret;
+}
+
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5_sess.c b/lib/libpam/modules/pam_krb5/pam_krb5_sess.c
new file mode 100644
index 0000000..b2df064
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam_krb5_sess.c
@@ -0,0 +1,28 @@
+/*
+ * pam_krb5_sess.c
+ *
+ * PAM session management functions for pam_krb5
+ * (null functions)
+ *
+ * $FreeBSD$
+ */
+
+static const char rcsid[] = "$Id: pam_krb5_sess.c,v 1.3 1999/01/19 20:49:44 fcusack Exp $";
+
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+/* Initiate session management */
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+/* Terminate session management */
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
diff --git a/lib/libpam/modules/pam_krb5/support.c b/lib/libpam/modules/pam_krb5/support.c
new file mode 100644
index 0000000..8e1aecd
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/support.c
@@ -0,0 +1,185 @@
+/*
+ * support.c
+ *
+ * Support functions for pam_krb5
+ *
+ * $FreeBSD$
+ */
+
+static const char rcsid[] = "$Id: support.c,v 1.8 2000/01/04 09:50:03 fcusack Exp $";
+
+#include <errno.h>
+#include <stdio.h> /* BUFSIZ */
+#include <stdlib.h> /* malloc */
+#include <string.h> /* strncpy */
+#include <syslog.h> /* syslog */
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include <krb5.h>
+#include <com_err.h>
+#include "pam_krb5.h"
+
+/*
+ * Get info from the user. Disallow null responses (regardless of flags).
+ * response gets allocated and filled in on successful return. Caller
+ * is responsible for freeing it.
+ */
+int
+get_user_info(pam_handle_t *pamh, char *prompt, int type, char **response)
+{
+ int pamret;
+ struct pam_message msg;
+ const struct pam_message *pmsg;
+ struct pam_response *resp = NULL;
+ struct pam_conv *conv;
+
+ if ((pamret = pam_get_item(pamh, PAM_CONV, (const void **) &conv)) != 0)
+ return pamret;
+
+ /* set up conversation call */
+ pmsg = &msg;
+ msg.msg_style = type;
+ msg.msg = prompt;
+
+ if ((pamret = conv->conv(1, &pmsg, &resp, conv->appdata_ptr)) != 0)
+ return pamret;
+
+ /* Caller should ignore errors for non-response conversations */
+ if (!resp)
+ return PAM_CONV_ERR;
+
+ if (!(resp->resp && resp->resp[0])) {
+ free(resp);
+ return PAM_AUTH_ERR;
+ }
+
+ *response = resp->resp;
+ free(resp);
+ return pamret;
+}
+
+/*
+ * This routine with some modification is from the MIT V5B6 appl/bsd/login.c
+ * Modified by Sam Hartman <hartmans@mit.edu> to support PAM services
+ * for Debian.
+ *
+ * Verify the Kerberos ticket-granting ticket just retrieved for the
+ * user. If the Kerberos server doesn't respond, assume the user is
+ * trying to fake us out (since we DID just get a TGT from what is
+ * supposedly our KDC). If the host/<host> service is unknown (i.e.,
+ * the local keytab doesn't have it), and we cannot find another
+ * service we do have, let her in.
+ *
+ * Returns 1 for confirmation, -1 for failure, 0 for uncertainty.
+ */
+int
+verify_krb_v5_tgt(krb5_context context, krb5_ccache ccache,
+ char * pam_service, int debug)
+{
+ char phost[BUFSIZ];
+ char *services [3];
+ char **service;
+ krb5_error_code retval = -1;
+ krb5_principal princ;
+ krb5_keyblock * keyblock = 0;
+ krb5_data packet;
+ krb5_auth_context auth_context = NULL;
+
+ packet.data = 0;
+
+ /*
+ * If possible we want to try and verify the ticket we have
+ * received against a keytab. We will try multiple service
+ * principals, including at least the host principal and the PAM
+ * service principal. The host principal is preferred because access
+ * to that key is generally sufficient to compromise root, while the
+ * service key for this PAM service may be less carefully guarded.
+ * It is important to check the keytab first before the KDC so we do
+ * not get spoofed by a fake KDC.*/
+ services [0] = "host";
+ services [1] = pam_service;
+ services [2] = NULL;
+ for ( service = &services[0]; *service != NULL; service++ ) {
+ if ((retval = krb5_sname_to_principal(context, NULL, *service, KRB5_NT_SRV_HST,
+ &princ)) != 0) {
+ if (debug)
+ syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
+ "krb5_sname_to_principal()", error_message(retval));
+ return -1;
+ }
+
+ /* Extract the name directly. */
+ strncpy(phost, compat_princ_component(context, princ, 1), BUFSIZ);
+ phost[BUFSIZ - 1] = '\0';
+
+ /*
+ * Do we have service/<host> keys?
+ * (use default/configured keytab, kvno IGNORE_VNO to get the
+ * first match, and ignore enctype.)
+ */
+ if ((retval = krb5_kt_read_service_key(context, NULL, princ, 0,
+ 0, &keyblock)) != 0)
+ continue;
+ break;
+ }
+ if (retval != 0 ) { /* failed to find key */
+ /* Keytab or service key does not exist */
+ if (debug)
+ syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
+ "krb5_kt_read_service_key()", error_message(retval));
+ retval = 0;
+ goto cleanup;
+ }
+ if (keyblock)
+ krb5_free_keyblock(context, keyblock);
+
+ /* Talk to the kdc and construct the ticket. */
+ retval = krb5_mk_req(context, &auth_context, 0, *service, phost,
+ NULL, ccache, &packet);
+ if (auth_context) {
+ krb5_auth_con_free(context, auth_context);
+ auth_context = NULL; /* setup for rd_req */
+ }
+ if (retval) {
+ if (debug)
+ syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
+ "krb5_mk_req()", error_message(retval));
+ retval = -1;
+ goto cleanup;
+ }
+
+ /* Try to use the ticket. */
+ retval = krb5_rd_req(context, &auth_context, &packet, princ,
+ NULL, NULL, NULL);
+ if (retval) {
+ if (debug)
+ syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
+ "krb5_rd_req()", error_message(retval));
+ retval = -1;
+ } else {
+ retval = 1;
+ }
+
+cleanup:
+ if (packet.data)
+ compat_free_data_contents(context, &packet);
+ krb5_free_principal(context, princ);
+ return retval;
+
+}
+
+
+/* Free the memory for cache_name. Called by pam_end() */
+void
+cleanup_cache(pam_handle_t *pamh, void *data, int pam_end_status)
+{
+ krb5_context pam_context;
+ krb5_ccache ccache;
+
+ if (krb5_init_context(&pam_context))
+ return;
+
+ ccache = (krb5_ccache) data;
+ (void) krb5_cc_destroy(pam_context, ccache);
+ krb5_free_context(pam_context);
+}
diff --git a/lib/libpam/modules/pam_nologin/Makefile b/lib/libpam/modules/pam_nologin/Makefile
new file mode 100644
index 0000000..f6911b7
--- /dev/null
+++ b/lib/libpam/modules/pam_nologin/Makefile
@@ -0,0 +1,39 @@
+# Copyright 2001 Mark R V Murray
+# All rights reserved.
+#
+# 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.
+#
+# 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$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+.PATH: ${PAMDIR}/modules/pam_nologin
+
+LIB= pam_nologin
+SHLIB_NAME= pam_nologin.so
+SRCS= pam_nologin.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_rootok/Makefile b/lib/libpam/modules/pam_rootok/Makefile
new file mode 100644
index 0000000..c04afb8
--- /dev/null
+++ b/lib/libpam/modules/pam_rootok/Makefile
@@ -0,0 +1,39 @@
+# Copyright 2001 Mark R V Murray
+# All rights reserved.
+#
+# 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.
+#
+# 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$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+.PATH: ${PAMDIR}/modules/pam_rootok
+
+LIB= pam_rootok
+SHLIB_NAME= pam_rootok.so
+SRCS= pam_rootok.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_wheel/Makefile b/lib/libpam/modules/pam_wheel/Makefile
new file mode 100644
index 0000000..96cea74
--- /dev/null
+++ b/lib/libpam/modules/pam_wheel/Makefile
@@ -0,0 +1,39 @@
+# Copyright 2001 Mark R V Murray
+# All rights reserved.
+#
+# 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.
+#
+# 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$
+
+PAMDIR= ${.CURDIR}/../../../../contrib/libpam
+
+.PATH: ${PAMDIR}/modules/pam_wheel
+
+LIB= pam_wheel
+SHLIB_NAME= pam_wheel.so
+SRCS= pam_wheel.c
+CFLAGS+= -Wall
+CFLAGS+= -I${PAMDIR}/libpam/include
+INTERNALLIB= yes
+INTERNALSTATICLIB=yes
+
+.include <bsd.lib.mk>
OpenPOWER on IntegriCloud