aboutsummaryrefslogtreecommitdiff
path: root/lib/libpam/modules
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpam/modules')
-rw-r--r--lib/libpam/modules/Makefile.inc2
-rw-r--r--lib/libpam/modules/modules.inc1
-rw-r--r--lib/libpam/modules/pam_chroot/Makefile1
-rw-r--r--lib/libpam/modules/pam_chroot/pam_chroot.84
-rw-r--r--lib/libpam/modules/pam_chroot/pam_chroot.c1
-rw-r--r--lib/libpam/modules/pam_deny/pam_deny.84
-rw-r--r--lib/libpam/modules/pam_echo/Makefile1
-rw-r--r--lib/libpam/modules/pam_echo/pam_echo.84
-rw-r--r--lib/libpam/modules/pam_exec/Makefile1
-rw-r--r--lib/libpam/modules/pam_exec/pam_exec.86
-rw-r--r--lib/libpam/modules/pam_exec/pam_exec.c1
-rw-r--r--lib/libpam/modules/pam_ftpusers/Makefile1
-rw-r--r--lib/libpam/modules/pam_ftpusers/pam_ftpusers.84
-rw-r--r--lib/libpam/modules/pam_group/Makefile1
-rw-r--r--lib/libpam/modules/pam_group/pam_group.84
-rw-r--r--lib/libpam/modules/pam_group/pam_group.c1
-rw-r--r--lib/libpam/modules/pam_guest/Makefile1
-rw-r--r--lib/libpam/modules/pam_guest/pam_guest.84
-rw-r--r--lib/libpam/modules/pam_krb5/Makefile54
-rw-r--r--lib/libpam/modules/pam_krb5/config.h412
-rw-r--r--lib/libpam/modules/pam_krb5/pam-krb5.81025
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5.84
-rw-r--r--lib/libpam/modules/pam_krb5/pam_krb5.c5
-rw-r--r--lib/libpam/modules/pam_ksu/Makefile11
-rw-r--r--lib/libpam/modules/pam_ksu/pam_ksu.84
-rw-r--r--lib/libpam/modules/pam_ksu/pam_ksu.c64
-rw-r--r--lib/libpam/modules/pam_lastlog/pam_lastlog.84
-rw-r--r--lib/libpam/modules/pam_login_access/login_access.c1
-rw-r--r--lib/libpam/modules/pam_nologin/pam_nologin.84
-rw-r--r--lib/libpam/modules/pam_nologin/pam_nologin.c1
-rw-r--r--lib/libpam/modules/pam_passwdqc/Makefile1
-rw-r--r--lib/libpam/modules/pam_passwdqc/pam_passwdqc.84
-rw-r--r--lib/libpam/modules/pam_permit/pam_permit.84
-rw-r--r--lib/libpam/modules/pam_radius/pam_radius.84
-rw-r--r--lib/libpam/modules/pam_radius/pam_radius.c1
-rw-r--r--lib/libpam/modules/pam_rhosts/Makefile1
-rw-r--r--lib/libpam/modules/pam_rhosts/pam_rhosts.84
-rw-r--r--lib/libpam/modules/pam_rootok/pam_rootok.84
-rw-r--r--lib/libpam/modules/pam_securetty/pam_securetty.84
-rw-r--r--lib/libpam/modules/pam_securetty/pam_securetty.c1
-rw-r--r--lib/libpam/modules/pam_self/pam_self.84
-rw-r--r--lib/libpam/modules/pam_ssh/pam_ssh.84
-rw-r--r--lib/libpam/modules/pam_ssh/pam_ssh.c1
-rw-r--r--lib/libpam/modules/pam_tacplus/pam_tacplus.c1
-rw-r--r--lib/libpam/modules/pam_unix/pam_unix.82
-rw-r--r--lib/libpam/modules/pam_unix/pam_unix.c1
-rw-r--r--lib/libpam/modules/pam_xdg/Makefile5
-rw-r--r--lib/libpam/modules/pam_xdg/pam_xdg.865
-rw-r--r--lib/libpam/modules/pam_xdg/pam_xdg.c329
49 files changed, 2009 insertions, 62 deletions
diff --git a/lib/libpam/modules/Makefile.inc b/lib/libpam/modules/Makefile.inc
index 955ee5224198..2e66aec64f07 100644
--- a/lib/libpam/modules/Makefile.inc
+++ b/lib/libpam/modules/Makefile.inc
@@ -1,8 +1,6 @@
-
PAMDIR= ${SRCTOP}/contrib/openpam
MK_INSTALLLIB= no
-MK_PROFILE= no
CFLAGS+= -I${PAMDIR}/include -I${SRCTOP}/lib/libpam
diff --git a/lib/libpam/modules/modules.inc b/lib/libpam/modules/modules.inc
index ddbb326f0312..f3ab65333f4f 100644
--- a/lib/libpam/modules/modules.inc
+++ b/lib/libpam/modules/modules.inc
@@ -30,3 +30,4 @@ MODULES += pam_ssh
.endif
MODULES += pam_tacplus
MODULES += pam_unix
+MODULES += pam_xdg \ No newline at end of file
diff --git a/lib/libpam/modules/pam_chroot/Makefile b/lib/libpam/modules/pam_chroot/Makefile
index ca4f3cc17443..206f8fa40a09 100644
--- a/lib/libpam/modules/pam_chroot/Makefile
+++ b/lib/libpam/modules/pam_chroot/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_chroot
SRCS= pam_chroot.c
MAN= pam_chroot.8
diff --git a/lib/libpam/modules/pam_chroot/pam_chroot.8 b/lib/libpam/modules/pam_chroot/pam_chroot.8
index e65c513b7b77..1f614264ba8e 100644
--- a/lib/libpam/modules/pam_chroot/pam_chroot.8
+++ b/lib/libpam/modules/pam_chroot/pam_chroot.8
@@ -78,8 +78,8 @@ Specify the chroot directory to use if one could not be derived from
the user's home directory.
.El
.Sh SEE ALSO
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_chroot/pam_chroot.c b/lib/libpam/modules/pam_chroot/pam_chroot.c
index 5cb38e2570b0..346be34683c1 100644
--- a/lib/libpam/modules/pam_chroot/pam_chroot.c
+++ b/lib/libpam/modules/pam_chroot/pam_chroot.c
@@ -34,7 +34,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <pwd.h>
diff --git a/lib/libpam/modules/pam_deny/pam_deny.8 b/lib/libpam/modules/pam_deny/pam_deny.8
index 530bae05c1f3..5d70bde200d9 100644
--- a/lib/libpam/modules/pam_deny/pam_deny.8
+++ b/lib/libpam/modules/pam_deny/pam_deny.8
@@ -73,6 +73,6 @@ reasons why the user's
authentication attempt was declined.
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr syslog 3 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
diff --git a/lib/libpam/modules/pam_echo/Makefile b/lib/libpam/modules/pam_echo/Makefile
index 58aae0053be9..532d0a51b58e 100644
--- a/lib/libpam/modules/pam_echo/Makefile
+++ b/lib/libpam/modules/pam_echo/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_echo
SRCS= pam_echo.c
MAN= pam_echo.8
diff --git a/lib/libpam/modules/pam_echo/pam_echo.8 b/lib/libpam/modules/pam_echo/pam_echo.8
index c38d4d8cee55..19c083917bbf 100644
--- a/lib/libpam/modules/pam_echo/pam_echo.8
+++ b/lib/libpam/modules/pam_echo/pam_echo.8
@@ -77,8 +77,8 @@ expands to the character following the
.Cm %
character.
.Sh SEE ALSO
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_exec/Makefile b/lib/libpam/modules/pam_exec/Makefile
index 1902d10789b5..c2327a2860cd 100644
--- a/lib/libpam/modules/pam_exec/Makefile
+++ b/lib/libpam/modules/pam_exec/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_exec
SRCS= pam_exec.c
MAN= pam_exec.8
diff --git a/lib/libpam/modules/pam_exec/pam_exec.8 b/lib/libpam/modules/pam_exec/pam_exec.8
index c77162955730..be5666003557 100644
--- a/lib/libpam/modules/pam_exec/pam_exec.8
+++ b/lib/libpam/modules/pam_exec/pam_exec.8
@@ -148,15 +148,15 @@ Each valid codes numerical value is available as an environment variable
etc).
This is useful in shell scripts for instance.
.Sh SEE ALSO
-.Xr pam_get_item 3 ,
-.Xr pam.conf 5 ,
.Xr pam 3 ,
+.Xr pam_get_item 3 ,
.Xr pam_sm_acct_mgmt 3 ,
.Xr pam_sm_authenticate 3 ,
.Xr pam_sm_chauthtok 3 ,
.Xr pam_sm_close_session 3 ,
.Xr pam_sm_open_session 3 ,
-.Xr pam_sm_setcred 3
+.Xr pam_sm_setcred 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_exec/pam_exec.c b/lib/libpam/modules/pam_exec/pam_exec.c
index c249a654c8be..800a791f04a1 100644
--- a/lib/libpam/modules/pam_exec/pam_exec.c
+++ b/lib/libpam/modules/pam_exec/pam_exec.c
@@ -36,7 +36,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/procdesc.h>
diff --git a/lib/libpam/modules/pam_ftpusers/Makefile b/lib/libpam/modules/pam_ftpusers/Makefile
index e92b752309b5..07d37c8b17a8 100644
--- a/lib/libpam/modules/pam_ftpusers/Makefile
+++ b/lib/libpam/modules/pam_ftpusers/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_ftpusers
SRCS= pam_ftpusers.c
MAN= pam_ftpusers.8
diff --git a/lib/libpam/modules/pam_ftpusers/pam_ftpusers.8 b/lib/libpam/modules/pam_ftpusers/pam_ftpusers.8
index a5c810fd2de5..d5a0f0f1fd2e 100644
--- a/lib/libpam/modules/pam_ftpusers/pam_ftpusers.8
+++ b/lib/libpam/modules/pam_ftpusers/pam_ftpusers.8
@@ -82,9 +82,9 @@ will succeed if and only if the user is not listed in
.Pa /etc/ftpusers .
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr ftpusers 5 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_group/Makefile b/lib/libpam/modules/pam_group/Makefile
index dca723748174..0395b3a8f355 100644
--- a/lib/libpam/modules/pam_group/Makefile
+++ b/lib/libpam/modules/pam_group/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_group
SRCS= pam_group.c
MAN= pam_group.8
diff --git a/lib/libpam/modules/pam_group/pam_group.8 b/lib/libpam/modules/pam_group/pam_group.8
index ed96d45db503..315aaa6cc267 100644
--- a/lib/libpam/modules/pam_group/pam_group.8
+++ b/lib/libpam/modules/pam_group/pam_group.8
@@ -86,8 +86,8 @@ options are mutually exclusive, and that
.Nm
will fail if both are specified.
.Sh SEE ALSO
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_group/pam_group.c b/lib/libpam/modules/pam_group/pam_group.c
index 7c9538b73978..9707a9cd278c 100644
--- a/lib/libpam/modules/pam_group/pam_group.c
+++ b/lib/libpam/modules/pam_group/pam_group.c
@@ -35,7 +35,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <grp.h>
diff --git a/lib/libpam/modules/pam_guest/Makefile b/lib/libpam/modules/pam_guest/Makefile
index c168513b98ee..7128b513afbc 100644
--- a/lib/libpam/modules/pam_guest/Makefile
+++ b/lib/libpam/modules/pam_guest/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_guest
SRCS= pam_guest.c
MAN= pam_guest.8
diff --git a/lib/libpam/modules/pam_guest/pam_guest.8 b/lib/libpam/modules/pam_guest/pam_guest.8
index 541fd299ba8b..c626187d5b19 100644
--- a/lib/libpam/modules/pam_guest/pam_guest.8
+++ b/lib/libpam/modules/pam_guest/pam_guest.8
@@ -80,10 +80,10 @@ password.
Requires the guest user to type in the guest account name as password.
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr pam_get_item 3 ,
.Xr pam_getenv 3 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_krb5/Makefile b/lib/libpam/modules/pam_krb5/Makefile
index 1c2831facd50..7634930a7202 100644
--- a/lib/libpam/modules/pam_krb5/Makefile
+++ b/lib/libpam/modules/pam_krb5/Makefile
@@ -23,6 +23,58 @@
# SUCH DAMAGE.
#
+.include <src.opts.mk>
+
+.if ${MK_MITKRB5} != "no"
+SRCDIR= ${SRCTOP}/contrib/pam-krb5
+.PATH: ${SRCDIR}/module \
+ ${SRCDIR}/portable \
+ ${SRCDIR}/pam-util \
+ ${SRCDIR}
+
+PACKAGE= kerberos
+LIB= pam_krb5
+LIBADD= com_err krb5
+
+SRCS= account.c \
+ alt-auth.c \
+ args.c \
+ auth.c \
+ cache.c \
+ context.c \
+ dummy.c \
+ fast.c \
+ krb5-extra.c \
+ logging.c \
+ pam-util_options.c \
+ module_options.c \
+ pam_syslog.c \
+ pam_vsyslog.c \
+ password.c \
+ prompting.c \
+ public.c \
+ setcred.c \
+ support.c \
+ vector.c
+
+MAN= pam-krb5.8
+MLINKS= pam-krb5.8 pam_krb5.8
+
+CFLAGS= -I${SRCDIR} \
+ -I${.CURDIR} \
+ -fno-strict-aliasing \
+ -DHAVE_CONFIG_H
+
+WARNS?= 3
+
+CLEANFILES= pam-util_options.c module_options.c
+
+pam-util_options.c: .PHONY
+ cp ${SRCDIR}/pam-util/options.c pam-util_options.c
+
+module_options.c: .PHONY
+ cp ${SRCDIR}/module/options.c module_options.c
+.else
PACKAGE= kerberos
LIB= pam_krb5
@@ -35,4 +87,6 @@ WARNS?= 3
LIBADD+= krb5
+.endif
+
.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_krb5/config.h b/lib/libpam/modules/pam_krb5/config.h
new file mode 100644
index 000000000000..75695eef66a1
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/config.h
@@ -0,0 +1,412 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `asprintf' function. */
+#define HAVE_ASPRINTF 1
+
+/* Define to 1 if you have the declaration of `krb5_kt_free_entry', and to 0
+ if you don't. */
+#define HAVE_DECL_KRB5_KT_FREE_ENTRY 1
+
+/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
+ don't. */
+#define HAVE_DECL_REALLOCARRAY 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <et/com_err.h> header file. */
+/* #undef HAVE_ET_COM_ERR_H */
+
+/* Define to 1 if you have the `explicit_bzero' function. */
+#define HAVE_EXPLICIT_BZERO 1
+
+/* Define to 1 if you have the <hx509_err.h> header file. */
+/* #undef HAVE_HX509_ERR_H */
+
+/* Define to 1 if you have the <ibm_svc/krb5_svc.h> header file. */
+/* #undef HAVE_IBM_SVC_KRB5_SVC_H */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `issetugid' function. */
+#define HAVE_ISSETUGID 1
+
+/* Define to 1 if you have the <k5profile.h> header file. */
+/* #undef HAVE_K5PROFILE_H */
+
+/* Define to enable kadmin client features. */
+#define HAVE_KADM5CLNT 1
+
+/* Define to 1 if you have the `kadm5_init_krb5_context' function. */
+#define HAVE_KADM5_INIT_KRB5_CONTEXT 1
+
+/* Define to 1 if you have the `kadm5_init_with_skey_ctx' function. */
+/* #undef HAVE_KADM5_INIT_WITH_SKEY_CTX */
+
+/* Define to 1 if you have the <kadm5/kadm5_err.h> header file. */
+#define HAVE_KADM5_KADM5_ERR_H 1
+
+/* Define to 1 if you have the <kerberosv5/com_err.h> header file. */
+/* #undef HAVE_KERBEROSV5_COM_ERR_H */
+
+/* Define to 1 if you have the <kerberosv5/krb5.h> header file. */
+/* #undef HAVE_KERBEROSV5_KRB5_H */
+
+/* Define to enable Kerberos features. */
+#define HAVE_KRB5 1
+
+/* Define to 1 if you have the `krb5_appdefault_string' function. */
+#define HAVE_KRB5_APPDEFAULT_STRING 1
+
+/* Define to 1 if you have the `krb5_cc_get_full_name' function. */
+#define HAVE_KRB5_CC_GET_FULL_NAME 1
+
+/* Define to 1 if you have the `krb5_data_free' function. */
+/* #undef HAVE_KRB5_DATA_FREE */
+
+/* Define to 1 if you have the `krb5_free_default_realm' function. */
+#define HAVE_KRB5_FREE_DEFAULT_REALM 1
+
+/* Define to 1 if you have the `krb5_free_error_message' function. */
+#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
+
+/* Define to 1 if you have the `krb5_free_string' function. */
+#define HAVE_KRB5_FREE_STRING 1
+
+/* Define to 1 if you have the `krb5_get_error_message' function. */
+#define HAVE_KRB5_GET_ERROR_MESSAGE 1
+
+/* Define to 1 if you have the `krb5_get_error_string' function. */
+/* #undef HAVE_KRB5_GET_ERROR_STRING */
+
+/* Define to 1 if you have the `krb5_get_err_txt' function. */
+/* #undef HAVE_KRB5_GET_ERR_TXT */
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_alloc' function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC 1
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_free' function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_FREE 1
+
+/* Define if krb5_get_init_creds_opt_free takes two arguments. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS 1
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_anonymous'
+ function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ANONYMOUS 1
+
+/* Define to 1 if you have the
+ `krb5_get_init_creds_opt_set_change_password_prompt' function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT 1
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_default_flags'
+ function. */
+/* #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS */
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_fast_ccache_name'
+ function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_CCACHE_NAME 1
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_out_ccache'
+ function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_SET_OUT_CCACHE 1
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_pa' function. */
+#define HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PA 1
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_pkinit' function.
+ */
+/* #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT */
+
+/* Define if krb5_get_init_creds_opt_set_pkinit takes 9 arguments. */
+/* #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT_9_ARGS */
+
+/* Define to 1 if you have the `krb5_get_profile' function. */
+/* #undef HAVE_KRB5_GET_PROFILE */
+
+/* Define to 1 if you have the `krb5_get_prompt_types' function. */
+#define HAVE_KRB5_GET_PROMPT_TYPES 1
+
+/* Define to 1 if you have the <krb5.h> header file. */
+#define HAVE_KRB5_H 1
+
+/* Define if your Kerberos implementation is Heimdal. */
+/* #undef HAVE_KRB5_HEIMDAL */
+
+/* Define to 1 if you have the `krb5_init_secure_context' function. */
+#define HAVE_KRB5_INIT_SECURE_CONTEXT 1
+
+/* Define to 1 if you have the <krb5/krb5.h> header file. */
+#define HAVE_KRB5_KRB5_H 1
+
+/* Define if your Kerberos implementation is MIT. */
+#define HAVE_KRB5_MIT 1
+
+/* Define to 1 if you have the `krb5_principal_get_realm' function. */
+/* #undef HAVE_KRB5_PRINCIPAL_GET_REALM */
+
+/* Define to 1 if you have the `krb5_principal_set_comp_string' function. */
+/* #undef HAVE_KRB5_PRINCIPAL_SET_COMP_STRING */
+
+/* Define to 1 if the system has the type `krb5_realm'. */
+/* #undef HAVE_KRB5_REALM */
+
+/* Define to 1 if you have the `krb5_set_password' function. */
+#define HAVE_KRB5_SET_PASSWORD 1
+
+/* Define to 1 if you have the `krb5_set_trace_filename' function. */
+#define HAVE_KRB5_SET_TRACE_FILENAME 1
+
+/* Define to 1 if you have the `krb5_svc_get_msg' function. */
+/* #undef HAVE_KRB5_SVC_GET_MSG */
+
+/* Define to 1 if you have the `krb5_verify_init_creds_opt_init' function. */
+#define HAVE_KRB5_VERIFY_INIT_CREDS_OPT_INIT 1
+
+/* Define to 1 if you have the `krb5_xfree' function. */
+/* #undef HAVE_KRB5_XFREE */
+
+/* Define to 1 if the system has the type `long long int'. */
+#define HAVE_LONG_LONG_INT 1
+
+/* Define to 1 if you have the <minix/config.h> header file. */
+/* #undef HAVE_MINIX_CONFIG_H */
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the `pam_getenv' function. */
+#define HAVE_PAM_GETENV 1
+
+/* Define to 1 if you have the `pam_getenvlist' function. */
+#define HAVE_PAM_GETENVLIST 1
+
+/* Define to 1 if you have the `pam_modutil_getpwnam' function. */
+/* #undef HAVE_PAM_MODUTIL_GETPWNAM */
+
+/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+/* #undef HAVE_PAM_PAM_APPL_H */
+
+/* Define to 1 if you have the <pam/pam_ext.h> header file. */
+/* #undef HAVE_PAM_PAM_EXT_H */
+
+/* Define to 1 if you have the <pam/pam_modutil.h> header file. */
+/* #undef HAVE_PAM_PAM_MODUTIL_H */
+
+/* Define to 1 if you have the `pam_syslog' function. */
+/* #undef HAVE_PAM_SYSLOG */
+
+/* Define to 1 if you have the `pam_vsyslog' function. */
+/* #undef HAVE_PAM_VSYSLOG */
+
+/* Define to 1 if you have the <profile.h> header file. */
+/* #undef HAVE_PROFILE_H */
+
+/* Define to 1 if you have the `reallocarray' function. */
+#define HAVE_REALLOCARRAY 1
+
+/* Define to 1 if you have the `regcomp' function. */
+#define HAVE_REGCOMP 1
+
+/* Define to 1 if you have the <security/pam_appl.h> header file. */
+#define HAVE_SECURITY_PAM_APPL_H 1
+
+/* Define to 1 if you have the <security/pam_ext.h> header file. */
+/* #undef HAVE_SECURITY_PAM_EXT_H */
+
+/* Define to 1 if you have the <security/pam_modutil.h> header file. */
+/* #undef HAVE_SECURITY_PAM_MODUTIL_H */
+
+/* Define to 1 if the system has the type `ssize_t'. */
+#define HAVE_SSIZE_T 1
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strndup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the <sys/bittypes.h> header file. */
+/* #undef HAVE_SYS_BITTYPES_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#define HAVE_UNSIGNED_LONG_LONG_INT 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* The name of the PAM module, used by the pam_vsyslog replacement. */
+#define MODULE_NAME "pam_krb5"
+
+/* Name of package */
+#define PACKAGE "pam-krb5"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "eagle@eyrie.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "pam-krb5"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "pam-krb5 4.11"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "pam-krb5"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "4.11"
+
+/* Define to const if PAM uses const in pam_get_item, empty otherwise. */
+#define PAM_CONST const
+
+/* Define to const if PAM uses const in pam_strerror, empty otherwise. */
+#define PAM_STRERROR_CONST const
+
+/* Define to the full path to openssl for some tests. */
+#define PATH_OPENSSL "/usr/bin/openssl"
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 8
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
+#define STDC_HEADERS 1
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable general extensions on macOS. */
+#ifndef _DARWIN_C_SOURCE
+# define _DARWIN_C_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+ with -lxnet on HP-UX 11.11. */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# define _HPUX_ALT_XOPEN_SOCKET_API 1
+#endif
+/* Identify the host operating system as Minix.
+ This macro does not affect the system headers' behavior.
+ A future release of Autoconf may stop defining this macro. */
+#ifndef _MINIX
+/* # undef _MINIX */
+#endif
+/* Enable general extensions on NetBSD.
+ Enable NetBSD compatibility extensions on Minix. */
+#ifndef _NETBSD_SOURCE
+# define _NETBSD_SOURCE 1
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+ Oddly enough, this does nothing on OpenBSD. */
+#ifndef _OPENBSD_SOURCE
+# define _OPENBSD_SOURCE 1
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_SOURCE
+/* # undef _POSIX_SOURCE */
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_1_SOURCE
+/* # undef _POSIX_1_SOURCE */
+#endif
+/* Enable POSIX-compatible threading on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
+#ifndef __STDC_WANT_LIB_EXT2__
+# define __STDC_WANT_LIB_EXT2__ 1
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009. */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable X/Open extensions. Define to 500 only if necessary
+ to make mbstate_t available. */
+#ifndef _XOPEN_SOURCE
+/* # undef _XOPEN_SOURCE */
+#endif
+
+
+/* Version number of package */
+#define VERSION "4.11"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
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 000000000000..3413748c7850
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/pam-krb5.8
@@ -0,0 +1,1025 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.0102 (Pod::Simple 3.45)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PAM_KRB5 1"
+.TH PAM_KRB5 1 2025-06-05 "perl v5.40.2" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH NAME
+pam_krb5 \- Kerberos PAM module
+.SH SYNOPSIS
+.IX Header "SYNOPSIS"
+.Vb 4
+\& auth sufficient pam_krb5.so minimum_uid=1000
+\& session required pam_krb5.so minimum_uid=1000
+\& account required pam_krb5.so minimum_uid=1000
+\& password sufficient pam_krb5.so minimum_uid=1000
+.Ve
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+The Kerberos service module for PAM, typically installed at
+\&\fI/lib/security/pam_krb5.so\fR, provides functionality for the four PAM
+operations: authentication, account management, session management, and
+password management. \fIpam_krb5.so\fR is a shared object that is
+dynamically loaded by the PAM subsystem as necessary, based on the system
+PAM configuration. PAM is a system for plugging in external
+authentication and session management modules so that each application
+doesn't have to know the best way to check user authentication or create a
+user session on that system. For details on how to configure PAM on your
+system, see the PAM man page, often \fBpam\fR\|(7).
+.PP
+Here are the actions of this module when called from each group:
+.IP auth 4
+.IX Item "auth"
+Provides implementations of \fBpam_authenticate()\fR and \fBpam_setcred()\fR. The
+former takes the username from the PAM session, prompts for the user's
+password (unless configured to use an already-entered password), and then
+performs a Kerberos initial authentication, storing the obtained
+credentials (if successful) in a temporary ticket cache. The latter,
+depending on the flags it is called with, either takes the contents of the
+temporary ticket cache and writes it out to a persistent ticket cache
+owned by the user or uses the temporary ticket cache to refresh an
+existing user ticket cache.
+.Sp
+Passwords as long or longer than PAM_MAX_RESP_SIZE octets (normally 512
+octets) will be rejected, since excessively long passwords can be used as
+a denial of service attack.
+.Sp
+After doing the initial authentication, the Kerberos PAM module will
+attempt to obtain tickets for a key in the local system keytab and then
+verify those tickets. Unless this step is performed, the authentication
+is vulnerable to KDC spoofing, but it requires that the system have a
+local key and that the PAM module be running as a user that can read the
+keytab file (normally \fI/etc/krb5.keytab\fR. You can point the Kerberos PAM
+module at a different keytab with the \fIkeytab\fR option. If that keytab
+cannot be read or if no keys are found in it, the default (potentially
+insecure) behavior is to skip this check. If you want to instead fail
+authentication if the obtained tickets cannot be checked, set
+\&\f(CW\*(C`verify_ap_req_nofail\*(C'\fR to true in the [libdefaults] section of
+\&\fI/etc/krb5.conf\fR. Note that this will affect applications other than
+this PAM module.
+.Sp
+By default, whenever the user is authenticated, a basic authorization
+check will also be done using \fBkrb5_kuserok()\fR. The default behavior of
+this function is to check the user's account for a \fI.k5login\fR file and,
+if one is present, ensure that the user's principal is listed in that
+file. If \fI.k5login\fR is not present, the default check is to ensure that
+the user's principal is in the default local realm and the user portion of
+the principal matches the account name (this can be changed by configuring
+a custom aname to localname mapping in \fIkrb5.conf\fR; see the Kerberos
+documentation for details). This can be customized with several
+configuration options; see below.
+.Sp
+If the username provided to PAM contains an \f(CW\*(C`@\*(C'\fR and Kerberos can,
+treating the username as a principal, map it to a local account name,
+\&\fBpam_authenticate()\fR will change the PAM user to that local account name.
+This allows users to log in with their Kerberos principal and let Kerberos
+do the mapping to an account. This can be disabled with the
+\&\fIno_update_user\fR option. Be aware, however, that this facility cannot be
+used with OpenSSH. OpenSSH will reject usernames that don't match local
+accounts before this remapping can be done and will pass an invalid
+password to the PAM module. Also be aware that several other common PAM
+modules, such as pam_securetty, expect to be able to look up the user with
+\&\fBgetpwnam()\fR and cannot be called before pam_krb5 when using this feature.
+.Sp
+When \fBpam_setcred()\fR is called to initialize a new ticket cache, the
+environment variable KRB5CCNAME is set to the path to that ticket cache.
+By default, the cache will be named \fI/tmp/krb5cc_UID_RANDOM\fR where UID is
+the user's UID and RANDOM is six randomly-chosen letters. This can be
+configured with the \fIccache\fR and \fIccache_dir\fR options.
+.Sp
+pam\-krb5 does not use the default ticket cache location or
+\&\fIdefault_cc_name\fR in the \f(CW\*(C`[libdefaults]\*(C'\fR section of \fIkrb5.conf\fR. The
+default cache location would share a cache for all sessions of the same
+user, which causes confusing behavior when the user logs out of one of
+multiple sessions.
+.Sp
+If \fBpam_setcred()\fR initializes a new ticket cache, it will also set up that
+ticket cache so that it will be deleted when the PAM session is closed.
+Normally, the calling program (\fBlogin\fR, \fBsshd\fR, etc.) will run the
+user's shell as a sub-process, wait for it to exit, and then close the PAM
+session, thereby cleaning up the user's session.
+.IP session 4
+.IX Item "session"
+Provides implementations of \fBpam_open_session()\fR, which is equivalent to
+calling \fBpam_setcred()\fR with the PAM_ESTABLISH_CRED flag, and
+\&\fBpam_close_session()\fR, which destroys the ticket cache created by
+\&\fBpam_setcred()\fR.
+.IP account 4
+.IX Item "account"
+Provides an implementation of \fBpam_acct_mgmt()\fR. All it does is do the same
+authorization check as performed by the \fBpam_authenticate()\fR implementation
+described above.
+.IP password 4
+.IX Item "password"
+Provides an implementation of \fBpam_chauthtok()\fR, which implements password
+changes. The user is prompted for their existing password (unless
+configured to use an already entered one) and the PAM module then obtains
+credentials for the special Kerberos principal \f(CW\*(C`kadmin/changepw\*(C'\fR. It
+then prompts the user for a new password, twice to ensure that the user
+entered it properly (again, unless configured to use an already entered
+password), and then does a Kerberos password change.
+.Sp
+Passwords as long or longer than PAM_MAX_RESP_SIZE octets (normally 512
+octets) will be rejected, since excessively long passwords can be used as
+a denial of service attack.
+.Sp
+Unlike the normal Unix password module, this module will allow any user to
+change any other user's password if they know the old password. Also,
+unlike the normal Unix password module, root will always be prompted for
+the old password, since root has no special status in Kerberos. (To
+change passwords in Kerberos without knowing the old password, use
+\&\fBkadmin\fR\|(8) instead.)
+.PP
+Both the account and session management calls of the Kerberos PAM module
+will return PAM_IGNORE if called in the context of a PAM session for a
+user who did not authenticate with Kerberos (a return code of \f(CW\*(C`ignore\*(C'\fR in
+the Linux PAM configuration language).
+.PP
+Note that this module assumes the network is available in order to do a
+Kerberos authentication. If the network is not available, some Kerberos
+libraries have timeouts longer than the timeout imposed by the login
+process. This means that using this module incautiously can make it
+impossible to log on to console as root. For this reason, you should
+always use the \fIignore_root\fR or \fIminimum_uid\fR options, list a local
+authentication module such as \fBpam_unix\fR first with a control field of
+\&\f(CW\*(C`sufficient\*(C'\fR so that the Kerberos PAM module will be skipped if local
+password authentication was successful.
+.PP
+This is not the same PAM module as the Kerberos PAM module available from
+Sourceforge, or the one included on Red Hat systems. It supports many of
+the same options, has some additional options, and doesn't support some of
+the options those modules do.
+.SH CONFIGURATION
+.IX Header "CONFIGURATION"
+The Kerberos PAM module takes many options, not all of which are relevant
+to every PAM group; options that are not relevant will be silently
+ignored. Any of these options can be set in the PAM configuration as
+arguments listed after \f(CW\*(C`pam_krb5.so\*(C'\fR. Some of the options can also be
+set in the system \fIkrb5.conf\fR file; if this is possible, it will be noted
+below in the option description.
+.PP
+To set a boolean option in the PAM configuration file, just give the name
+of the option in the arguments. To set an option that takes an argument,
+follow the option name with an equal sign (=) and the value, with no
+separating whitespace. Whitespace in option arguments is not supported in
+the PAM configuration.
+.PP
+To set an option for the PAM module in the system \fIkrb5.conf\fR file, put
+that option in the \f(CW\*(C`[appdefaults]\*(C'\fR section. All options must be followed
+by an equal sign (=) and a value, so for boolean options add \f(CW\*(C`= true\*(C'\fR.
+The Kerberos PAM module will look for options either at the top level of
+the \f(CW\*(C`[appdefaults]\*(C'\fR section or in a subsection named \f(CW\*(C`pam\*(C'\fR, inside or
+outside a section for the realm. For example, the following fragment of a
+\&\fIkrb5.conf\fR file would set \fIforwardable\fR to true, \fIminimum_uid\fR to
+1000, and set \fIignore_k5login\fR only if the realm is EXAMPLE.COM.
+.PP
+.Vb 8
+\& [appdefaults]
+\& forwardable = true
+\& pam = {
+\& minimum_uid = 1000
+\& EXAMPLE.COM = {
+\& ignore_k5login = true
+\& }
+\& }
+.Ve
+.PP
+For more information on the syntax of \fIkrb5.conf\fR, see \fBkrb5.conf\fR\|(5).
+Note that options that depend on the realm will be set only on the basis
+of the default realm, either as configured in \fBkrb5.conf\fR\|(5) or as set by
+the \fIrealm\fR option described below. If the user authenticates to an
+account qualified with a realm, that realm will not be used when
+determining which options will apply.
+.PP
+There is no difference to the PAM module whether options are specified at
+the top level or in a \f(CW\*(C`pam\*(C'\fR section; the \f(CW\*(C`pam\*(C'\fR section is supported in
+case there are options that should be set for the PAM module but not for
+other applications.
+.PP
+If the same option is set in \fIkrb5.conf\fR and in the PAM configuration,
+the latter takes precedent. Note, however, that due to the configuration
+syntax, there's no way to turn off a boolean option in the PAM
+configuration that was turned on in \fIkrb5.conf\fR.
+.PP
+The start of each option description is annotated with the version of
+pam\-krb5 in which that option was added with the current meaning.
+.SS Authorization
+.IX Subsection "Authorization"
+.IP alt_auth_map=<format> 4
+.IX Item "alt_auth_map=<format>"
+[3.12] This functions similarly to the \fIsearch_k5login\fR option. The
+<format> argument is used as the authentication Kerberos principal, with
+any \f(CW%s\fR in <format> replaced with the username. If the username
+contains an \f(CW\*(C`@\*(C'\fR, only the part of the username before the realm is used
+to replace \f(CW%s\fR. If <format> contains a realm, it will be used;
+otherwise, the realm of the username (if any) will be appended to the
+result. There is no quote removal.
+.Sp
+If this option is present, the default behavior is to try this alternate
+principal first and then fall back to the standard behavior if it fails.
+The primary usage is to allow alternative principals to be used for
+authentication in programs like \fBsudo\fR. Most examples will look like:
+.Sp
+.Vb 1
+\& alt_auth_map=%s/root
+.Ve
+.Sp
+which attempts authentication as the root instance of the username first
+and then falls back to the regular username (but see \fIforce_alt_auth\fR and
+\&\fIonly_alt_auth\fR).
+.Sp
+This option also allows a cheap way to attempt authentication in an
+alternative realm first and then fall back to the primary realm. A
+setting like:
+.Sp
+.Vb 1
+\& alt_auth_map=%s@EXAMPLE.COM
+.Ve
+.Sp
+will attempt authentication in the EXAMPLE.COM realm first and then fall
+back on the local default realm. This is more convenient than running the
+module multiple times with multiple default realms set with \fIrealm\fR, but
+it is very limited: only two realms can be tried, and the alternate realm
+is always tried first.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR, although
+normally it doesn't make sense to do that; normally it is used in the PAM
+options of configuration for specific programs. It is only applicable to
+the auth and account groups. If this option is set for the auth group, be
+sure to set it for the account group as well or account authorization may
+fail.
+.IP force_alt_auth 4
+.IX Item "force_alt_auth"
+[3.12] This option is used with \fIalt_auth_map\fR and forces authentication
+as the mapped principal if that principal exists in the KDC. Only if the
+KDC returns principal unknown does the Kerberos PAM module fall back to
+normal authentication. This can be used to force authentication with an
+alternate instance. If \fIalt_auth_map\fR is not set, it has no effect.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP ignore_k5login 4
+.IX Item "ignore_k5login"
+[2.0] Never look for a \fI.k5login\fR file in the user's home directory.
+Instead, only check that the Kerberos principal maps to the local account
+name. The default check is to ensure the realm matches the local realm
+and the user portion of the principal matches the local account name, but
+this can be customized by setting up an aname to localname mapping in
+\&\fIkrb5.conf\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and account groups.
+.IP ignore_root 4
+.IX Item "ignore_root"
+[1.1] Do not do anything if the username is \f(CW\*(C`root\*(C'\fR. The authentication
+and password calls will silently fail (allowing that status to be ignored
+via a control of \f(CW\*(C`optional\*(C'\fR or \f(CW\*(C`sufficient\*(C'\fR), and the account and
+session calls (including pam_setcred) will return PAM_IGNORE, telling the
+PAM library to proceed as if they weren't mentioned in the PAM
+configuration. This option is supported and will remain, but normally you
+want to use \fIminimum_uid\fR instead.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR.
+.IP minimum_uid=<uid> 4
+.IX Item "minimum_uid=<uid>"
+[2.0] Do not do anything if the authenticated account name corresponds to
+a local account and that local account has a UID lower than <uid>. If
+both of those conditions are true, the authentication and password calls
+will silently fail (allowing that status to be ignored via a control of
+\&\f(CW\*(C`optional\*(C'\fR or \f(CW\*(C`sufficient\*(C'\fR), and the account and session calls
+(including pam_setcred) will return PAM_IGNORE, telling the PAM library to
+proceed as if they weren't mentioned in the PAM configuration.
+.Sp
+Using this option is highly recommended if you don't need to use Kerberos
+to authenticate password logins to the root account (which isn't
+recommended since Kerberos requires a network connection). It provides
+some defense in depth against user principals that happen to match a
+system account incorrectly authenticating as that system account.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR.
+.IP only_alt_auth 4
+.IX Item "only_alt_auth"
+[3.12] This option is used with \fIalt_auth_map\fR and forces the use of the
+mapped principal for authentication. It disables fallback to normal
+authentication in all cases and overrides \fIsearch_k5login\fR and
+\&\fIforce_alt_auth\fR. If \fIalt_auth_map\fR is not set, it has no effect and
+the standard authentication behavior is used.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP search_k5login 4
+.IX Item "search_k5login"
+[2.0] Normally, the Kerberos implementation of pam_authenticate attempts
+to obtain tickets for the authenticating username in the local realm. If
+this option is set and the local user has a \fI.k5login\fR file in their home
+directory, the module will instead open and read that \fI.k5login\fR file,
+attempting to use the supplied password to authenticate as each principal
+listed there in turn. If any of those authentications succeed, the user
+will be successfully authenticated; otherwise, authentication will fail.
+This option is useful for allowing password authentication (via console or
+\&\fBsshd\fR without GSS-API support) to shared accounts. If there is no
+\&\fI.k5login\fR file, the behavior is the same as normal. Using this option
+requires that the user's \fI.k5login\fR file be readable at the time of
+authentication.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.SS "Kerberos Behavior"
+.IX Subsection "Kerberos Behavior"
+.IP anon_fast 4
+.IX Item "anon_fast"
+[4.6] Attempt to use Flexible Authentication Secure Tunneling (FAST) by
+first authenticating as the anonymous user (WELLKNOWN/ANONYMOUS) and using
+its credentials as the FAST armor. This requires anonymous PKINIT be
+enabled for the local realm, that PKINIT be configured on the local
+system, and that the Kerberos library support FAST and anonymous PKINIT.
+.Sp
+FAST is a mechanism to protect Kerberos against password guessing attacks
+and provide other security improvements. To work, FAST requires that a
+ticket be obtained with a strong key to protect exchanges with potentially
+weaker user passwords. This option uses anonymous authentication to
+obtain that key and then uses it to protect the subsequent authentication.
+.Sp
+If anonymous PKINIT is not available or fails, FAST will not be used and
+the authentication will proceed as normal.
+.Sp
+To instead use an existing ticket cache for the FAST credentials, use
+\&\fIfast_ccache\fR instead of this option. If both \fIfast_ccache\fR and
+\&\fIanon_fast\fR are set, the ticket cache named by \fIfast_ccache\fR will be
+tried first, and the Kerberos PAM module will fall back on attempting
+anonymous PKINIT if that cache could not be used.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.Sp
+The operation is the same as if using the \fIfast_ccache\fR option, but the
+cache is created and destroyed automatically. If both \fIfast_ccache\fR and
+\&\fIanon_fast\fR options are used, the \fIfast_ccache\fR takes precedent and no
+anonymous authentication is done.
+.IP fast_ccache=<ccache_name> 4
+.IX Item "fast_ccache=<ccache_name>"
+[4.3] The same as \fIanon_fast\fR, but use an existing Kerberos ticket cache
+rather than anonymous PKINIT. This allows use of FAST with a realm that
+doesn't support PKINIT or doesn't support anonymous authentication.
+.Sp
+<ccache_name> should be a credential cache containing a ticket obtained
+using a strong key, such as the randomized key for the host principal of
+the local system. If <ccache_name> names a ticket cache that is readable
+by the authenticating process and has tickets then FAST will be attempted.
+The easiest way to use this option is to use a program like \fBk5start\fR to
+maintain a ticket cache using the host's keytab. This ticket cache should
+normally only be readable by root, so this option will not be able to
+protect authentications done as non-root users (such as screensavers).
+.Sp
+If no credentials are present in the ticket cache, or if the ticket cache
+does not exist or is not readable, FAST will not used and authentication
+will proceed as normal. However, if the credentials in that ticket cache
+are expired, authentication will fail if the KDC supports FAST.
+.Sp
+To use anonymous PKINIT to protect the FAST exchange, use the \fIanon_fast\fR
+option instead. \fIanon_fast\fR is easier to configure, since no existing
+ticket cache is required, but requires PKINIT be available and configured
+and that the local realm support anonymous authentication. If both
+\&\fIfast_ccache\fR and \fIanon_fast\fR are set, the ticket cache named by
+\&\fIfast_ccache\fR will be tried first, and the Kerberos PAM module will fall
+back on attempting anonymous PKINIT if that cache could not be used.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.IP forwardable 4
+.IX Item "forwardable"
+[1.0] Obtain forwardable tickets. If set (to either true or false,
+although it can only be set to false in \fIkrb5.conf\fR), this overrides the
+Kerberos library default set in the [libdefaults] section of \fIkrb5.conf\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP keytab=<path> 4
+.IX Item "keytab=<path>"
+[3.0] Specifies the keytab to use when validating the user's credentials.
+The default is the default system keytab (normally \fI/etc/krb5.keytab\fR),
+which is usually only readable by root. Applications not running as root
+that use this PAM module for authentication may wish to point it to
+another keytab the application can read. The first principal found in the
+keytab will be used as the principal for credential verification.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP realm=<realm> 4
+.IX Item "realm=<realm>"
+[2.2] Set the default Kerberos realm and obtain credentials in that realm,
+rather than in the normal default realm for this system. If this option
+is used, it should be set for all groups being used for consistent
+results. This setting will affect authorization decisions since it
+changes the default realm. This setting will also change the service
+principal used to verify the obtained credentials to be in the specified
+realm.
+.Sp
+If you only want to set the realm assumed for user principals without
+changing the realm for authorization decisions or the service principal
+used to verify credentials, see the \fIuser_realm\fR option.
+.IP renew_lifetime=<lifetime> 4
+.IX Item "renew_lifetime=<lifetime>"
+[2.0] Obtain renewable tickets with a maximum renewable lifetime of
+<lifetime>. <lifetime> should be a Kerberos lifetime string such as
+\&\f(CW\*(C`2d4h10m\*(C'\fR or a time in minutes. If set, this overrides the Kerberos
+library default set in the [libdefaults] section of \fIkrb5.conf\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP ticket_lifetime=<lifetime> 4
+.IX Item "ticket_lifetime=<lifetime>"
+[3.0] Obtain tickets with a maximum lifetime of <lifetime>. <lifetime>
+should be a Kerberos lifetime string such as \f(CW\*(C`2d4h10m\*(C'\fR or a time in
+minutes. If set, this overrides the Kerberos library default set in the
+[libdefaults] section of \fIkrb5.conf\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP user_realm 4
+.IX Item "user_realm"
+[4.6] Obtain credentials in the specified realm rather than in the default
+realm for this system. If this option is used, it should be set for all
+groups being used for consistent results (although the account group
+currently doesn't care about realm). This will not change authorization
+decisions. If the obtained credentials are supposed to allow access to a
+shell account, the user will need an appropriate \fI.k5login\fR file entry or
+the system will have to have a custom aname_to_localname mapping.
+.SS "PAM Behavior"
+.IX Subsection "PAM Behavior"
+.IP clear_on_fail 4
+.IX Item "clear_on_fail"
+[3.9] When changing passwords, PAM first does a preliminary check through
+the complete password stack, and then calls each module again to do the
+password change. After that preliminary check, the order of module
+invocation is fixed. This means that even if the Kerberos password change
+fails (or if one of the other password changes in the stack fails), other
+password PAM modules in the stack will still be called even if the failing
+module is marked required or requisite. When using multiple password PAM
+modules to synchronize passwords between multiple systems when they
+change, this behavior can cause unwanted differences between the
+environments.
+.Sp
+Setting this option provides a way to work around this behavior. If this
+option is set and a Kerberos password change is attempted and fails (due
+to network errors or password strength checking on the KDC, for example),
+this module will clear the stored password in the PAM stack. This will
+force any subsequent modules that have \fIuse_authtok\fR set to fail so that
+those environments won't get out of sync with the password in Kerberos.
+The Kerberos PAM module will not meddle with the stored password if it
+skips the user due to configuration such as minimum_uid.
+.Sp
+Unfortunately, setting this option interferes with other desirable PAM
+configurations, such as attempting to change the password in Kerberos
+first and falling back on the local Unix password database if that fails.
+It therefore isn't the default. Turn it on (and list pam_krb5 first after
+pam_cracklib if used) when synchronizing passwords between multiple
+environments.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the password group.
+.IP debug 4
+.IX Item "debug"
+[1.0] Log more verbose trace and debugging information to syslog at
+LOG_DEBUG priority, including entry and exit from each of the external PAM
+interfaces (except pam_close_session).
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR.
+.IP defer_pwchange 4
+.IX Item "defer_pwchange"
+[3.11] By default, pam\-krb5 lets the Kerberos library handle prompting for
+a password change if an account's password is expired during the auth
+group. If this fails, \fBpam_authenticate()\fR returns an error.
+.Sp
+According to the PAM standard, this is not the correct way to handle
+expired passwords. Instead, \fBpam_authenticate()\fR should return success
+without attempting a password change, and then \fBpam_acct_mgmt()\fR should
+return PAM_NEW_AUTHTOK_REQD, at which point the calling application is
+responsible for either rejecting the authentication or calling
+\&\fBpam_chauthtok()\fR. However, following the standard requires that all
+applications call \fBpam_acct_mgmt()\fR and check its return status; otherwise,
+expired accounts may be able to successfully authenticate. Many
+applications do not do this.
+.Sp
+If this option is set, pam\-krb5 uses the fully correct PAM mechanism for
+handling expired accounts instead of failing in \fBpam_authenticate()\fR. Due
+to the security risk of widespread broken applications, be very careful
+about enabling this option. It should normally only be turned on to solve
+a specific problem (such as using Solaris Kerberos libraries that don't
+support prompting for password changes during authentication), and then
+only for specific applications known to call \fBpam_acct_mgmt()\fR and check its
+return status properly.
+.Sp
+This option is only supported when pam\-krb5 is built with MIT Kerberos.
+If built against Heimdal, this option does nothing and normal expired
+password change handling still happens. (Heimdal is missing the required
+API to implement this option, at least as of version 1.6.)
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP fail_pwchange 4
+.IX Item "fail_pwchange"
+[4.2] By default, pam\-krb5 lets the Kerberos library handle prompting for
+a password change if an account's password is expired during the auth
+group. If this option is set, expired passwords are instead treated as an
+authentication failure identical to an incorrect password. Also see
+\&\fIdefer_pwchange\fR and \fIforce_pwchange\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP force_pwchange 4
+.IX Item "force_pwchange"
+[3.11] If this option is set and authentication fails with a Kerberos
+error indicating the user's password is expired, attempt to immediately
+change their password during the authenticate step. Under normal
+circumstances, this is unnecessary. Most Kerberos libraries will do this
+for you, and setting this option will prompt the user twice to change
+their password if the first attempt (done by the Kerberos library) fails.
+However, some system Kerberos libraries (such as Solaris's) have password
+change prompting disabled in the Kerberos library; on those systems, you
+can set this option to simulate the normal library behavior.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP no_update_user 4
+.IX Item "no_update_user"
+[4.7] Normally, if pam\-krb5 is able to canonicalize the principal to a
+local name using \fBkrb5_aname_to_localname()\fR or similar calls, it changes
+the PAM_USER variable for this PAM session to the canonicalized local
+name. Setting this option disables this behavior and leaves PAM_USER set
+to the initial authentication identity.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth group.
+.IP silent 4
+.IX Item "silent"
+[1.0] Don't show messages and errors from Kerberos, such as warnings of
+expiring passwords, to the user via the prompter. This is equivalent to
+the behavior when the application passes in PAM_SILENT, but can be set in
+the PAM configuration.
+.Sp
+This option is only applicable to the auth and password groups.
+.IP trace=<log\-file> 4
+.IX Item "trace=<log-file>"
+[4.6] Enables Kerberos library trace logging to the specified log file if
+it is supported by the Kerberos library. This is intended for temporary
+debugging. The specified file will be appended to without further
+security checks, so do not specify a file in a publicly writable directory
+like \fI/tmp\fR.
+.SS PKINIT
+.IX Subsection "PKINIT"
+.IP pkinit_anchors=<anchors> 4
+.IX Item "pkinit_anchors=<anchors>"
+[3.0] When doing PKINIT authentication, use <anchors> as the client trust
+anchors. This is normally a reference to a file containing the trusted
+certificate authorities. This option is only used if \fItry_pkinit\fR or
+\&\fIuse_pkinit\fR are set.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.IP pkinit_prompt 4
+.IX Item "pkinit_prompt"
+[3.0] Before attempting PKINIT authentication, prompt the user to insert a
+smart card. You may want to set this option for programs such as
+\&\fBgnome-screensaver\fR that call PAM as soon as the mouse is touched and
+don't give the user an opportunity to enter the smart card first. Any
+information entered at the first prompt is ignored. If \fItry_pkinit\fR is
+set, a user who wishes to use a password instead can just press Enter and
+then enter their password as normal. This option is only used if
+\&\fItry_pkinit\fR or \fIuse_pkinit\fR are set.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.IP pkinit_user=<userid> 4
+.IX Item "pkinit_user=<userid>"
+[3.0] When doing PKINIT authentication, use <userid> as the user ID. The
+value of this string is highly dependent on the type of PKINIT
+implementation you're using, but will generally be something like:
+.Sp
+.Vb 1
+\& PKCS11:/usr/lib/pkcs11/lib/soft\-pkcs11.so
+.Ve
+.Sp
+to specify the module to use with a smart card. It may also point to a
+user certificate or to other types of user IDs. See the Kerberos library
+documentation for more details. This option is only used if \fItry_pkinit\fR
+or \fIuse_pkinit\fR are set.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.IP preauth_opt=<option> 4
+.IX Item "preauth_opt=<option>"
+[3.3] Sets a preauth option (currently only applicable when built with MIT
+Kerberos). <option> is either a key/value pair with the key separated
+from the value by \f(CW\*(C`=\*(C'\fR or a boolean option (in which case it's turned on).
+In \fIkrb5.conf\fR, multiple options should be separated by whitespace. In
+the PAM configuration, this option can be given multiple times to set
+multiple options. In either case, <option> may not contain whitespace.
+.Sp
+The primary use of this option, at least in the near future, will be to
+set options for the MIT Kerberos PKINIT support. For the full list of
+possible options, see the PKINIT plugin documentation. At the time of
+this writing, \f(CW\*(C`X509_user_identity\*(C'\fR is equivalent to \fIpkinit_user\fR and
+\&\f(CW\*(C`X509_anchors\*(C'\fR is equivalent to \fIpkinit_anchors\fR. \f(CW\*(C`flag_DSA_PROTOCOL\*(C'\fR
+can only be set via this option.
+.Sp
+Any settings made with this option are applied after the \fIpkinit_anchors\fR
+and \fIpkinit_user\fR options, so if an equivalent setting is made via
+\&\fIpreauth_opt\fR, it will probably override the other setting.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups. Note that there is no way to
+remove a setting made in \fIkrb5.conf\fR using the PAM configuration, but
+options set in the PAM configuration are applied after options set in
+\&\fIkrb5.conf\fR and therefore may override earlier settings.
+.IP try_pkinit 4
+.IX Item "try_pkinit"
+[3.0] Attempt PKINIT authentication before trying a regular password. You
+will probably also need to set the \fIpkinit_user\fR configuration option.
+If PKINIT fails, the PAM module will fall back on regular password
+authentication. This option is currently only supported if pam\-krb5 was
+built against Heimdal 0.8rc1 or later or MIT Kerberos 1.6.3 or later.
+.Sp
+If this option is set and pam\-krb5 is built against MIT Kerberos, and
+PKINIT fails and the module falls back to password authentication, the
+user's password will not be stored in the PAM stack for subsequent
+modules. This is a bug in the interaction between the module and MIT
+Kerberos that requires some reworking of the PKINIT authentication method
+to fix.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.IP use_pkinit 4
+.IX Item "use_pkinit"
+[3.0, 4.9 for MIT Kerberos] Require PKINIT authentication. You will
+probably also need to set the \fIpkinit_user\fR configuration option. If
+PKINIT fails, authentication will fail. This option is only supported if
+pam\-krb5 was built against Heimdal 0.8rc1 or later or MIT Kerberos 1.12 or
+later.
+.Sp
+Be aware that, with MIT Kerberos, this option is implemented by using a
+responder without a prompter, and thus any informational messages from the
+Kerberos libraries or KDC during authentication will not be displayed.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.SS Prompting
+.IX Subsection "Prompting"
+.IP banner=<banner> 4
+.IX Item "banner=<banner>"
+[3.0] By default, the prompts when a user changes their password are:
+.Sp
+.Vb 3
+\& Current Kerberos password:
+\& Enter new Kerberos password:
+\& Retype new Kerberos password:
+.Ve
+.Sp
+The string "Kerberos" is inserted so that users aren't confused about
+which password they're changing. Setting this option replaces the word
+"Kerberos" with whatever this option is set to. Setting this option to
+the empty string removes the word before "password:" entirely.
+.Sp
+If set in the PAM configuration, <banner> may not contain whitespace. If
+you want a value containing whitespace, set it in \fIkrb5.conf\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the password group.
+.IP expose_account 4
+.IX Item "expose_account"
+[3.0] By default, the Kerberos PAM module password prompt is simply
+"Password:". This avoids leaking any information about the system realm
+or account to principal conversions. If this option is set, the string
+"for <principal>" is added before the colon, where <principal> is the
+user's principal. This string is also added before the colon on prompts
+when changing the user's password.
+.Sp
+Enabling this option with ChallengeResponseAuthentication enabled in
+OpenSSH may cause problems for some ssh clients that only recognize
+"Password:" as a prompt. This option is automatically disabled if
+\&\fIsearch_k5login\fR is enabled since the principal displayed would be
+inaccurate.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and password groups.
+.IP force_first_pass 4
+.IX Item "force_first_pass"
+[4.0] Use the password obtained by a previous authentication or password
+module to authenticate the user without prompting the user again. If no
+previous module obtained the user's password, fail without prompting the
+user. Also see \fItry_first_pass\fR and \fIuse_first_pass\fR for weaker
+versions of this option.
+.Sp
+This option is only applicable to the auth and password groups. For the
+password group, it applies only to the old password. See \fIuse_authtok\fR
+for a similar setting for the new password.
+.IP no_prompt 4
+.IX Item "no_prompt"
+[4.6] Never prompt for the current password. Instead, pass in a NULL
+password to the Kerberos library and let the Kerberos library do the
+prompting. This may be needed if, for example, the Kerberos library is
+configured to use other authentication mechanisms than passwords and needs
+full control over the prompting process.
+.Sp
+The major disadvantage of this option is that it means the PAM module will
+never see the user's password and therefore cannot save it in the PAM
+module data for any subsequent modules. In other words, this option
+cannot be used if another module is in the stack behind the Kerberos PAM
+module and wants to use \fIuse_first_pass\fR. The Kerberos library also
+usually includes the principal in the prompt, and therefore this option
+implies behavior similar to \fIexpose_account\fR. Similar to
+\&\fIexpose_account\fR, this can cause problems with OpenSSH if
+ChallengeResponseAuthentication is enabled, since clients may not
+recognize password prompts other than "Password:".
+.Sp
+Using this option with \fIsearch_k5login\fR would result in a password prompt
+for every principal listed in the user's \fI.k5login\fR file. This is
+probably not desired behavior, although it's not prohibited by the module.
+.Sp
+This option is only applicable to the auth and password groups. For the
+password group, it applies only to the authentication process; the user
+will still be prompted for a new password.
+.IP prompt_principal 4
+.IX Item "prompt_principal"
+[3.6] Before prompting for the user's password (or using the previously
+entered password, if \fItry_first_pass\fR, \fIuse_first_pass\fR, or
+\&\fIforce_first_pass\fR are set), prompt the user for the Kerberos principal
+to use for authentication. This allows the user to authenticate with a
+different principal than the one corresponding to the local username,
+provided that either a \fI.k5login\fR file or local Kerberos principal to
+account mapping authorize that principal to access the local account.
+.Sp
+Be cautious when using this configuration option and don't use it with
+OpenSSH PasswordAuthentication, only ChallengeResponseAuthentication.
+Some PAM-enabled applications expect PAM modules to only prompt for
+passwords and may even blindly give the password to the first prompt, no
+matter what it is. Such applications, in combination with this option,
+may expose the user's password in log messages and Kerberos requests.
+.IP try_first_pass 4
+.IX Item "try_first_pass"
+[1.0] If the authentication module isn't the first on the stack, and a
+previous module obtained the user's password, use that password to
+authenticate the user without prompting them again. If that
+authentication fails, fall back on prompting the user for their password.
+This option has no effect if the authentication module is first in the
+stack or if no previous module obtained the user's password. Also see
+\&\fIuse_first_pass\fR and \fIforce_first_pass\fR for stronger versions of this
+option.
+.Sp
+This option is only applicable to the auth and password groups. For the
+password group, it applies only to the old password.
+.IP use_authtok 4
+.IX Item "use_authtok"
+[4.0] Use the new password obtained by a previous password module when
+changing passwords rather than prompting for the new password. If the new
+password isn't available, fail. This can be used to require passwords be
+checked by another, prior module, such as \fBpam_cracklib\fR.
+.Sp
+This option is only applicable to the password group.
+.IP use_first_pass 4
+.IX Item "use_first_pass"
+[1.0] Use the password obtained by a previous authentication module to
+authenticate the user without prompting the user again. If no previous
+module obtained the user's password for either an authentication or
+password change, fall back on prompting the user. If a previous module
+did obtain the user's password but authentication with that password
+fails, fail without further prompting the user. Also see
+\&\fItry_first_pass\fR and \fIforce_first_pass\fR for other versions of this
+option.
+.Sp
+This option is only applicable to the auth and password groups. For the
+password group, it applies only to the old password. See \fIuse_authtok\fR
+for a similar setting for the new password.
+.SS "Ticket Caches"
+.IX Subsection "Ticket Caches"
+.IP ccache=<pattern> 4
+.IX Item "ccache=<pattern>"
+[2.0] Use <pattern> as the pattern for creating credential cache names.
+<pattern> must be in the form <type>:<residual> where <type> and the
+following colon are optional if a file cache should be used. The special
+token \f(CW%u\fR, anywhere in <pattern>, is replaced with the user's numeric
+UID. The special token \f(CW%p\fR, anywhere in <pattern>, is replaced with the
+current process ID.
+.Sp
+If <pattern> ends in the literal string \f(CW\*(C`XXXXXX\*(C'\fR (six X's), that string
+will be replaced by randomly generated characters and the ticket cache
+will be created using \fBmkstemp\fR\|(3). This is strongly recommended if
+<pattern> points to a world-writable directory.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and session groups.
+.IP ccache_dir=<directory> 4
+.IX Item "ccache_dir=<directory>"
+[1.2] Store both the temporary ticket cache used during authentication and
+user ticket caches in <directory> instead of in \fI/tmp\fR. The algorithm
+for generating the ticket cache name is otherwise unchanged. <directory>
+may be prefixed with \f(CW\*(C`FILE:\*(C'\fR to make the cache type unambiguous (and this
+may be required on systems that use a cache type other than file as the
+default).
+.Sp
+Be aware that pam_krb5 creates and stores a temporary ticket cache file
+owned by root during the login process. If you set \fIccache\fR above to
+avoid using the system \fI/tmp\fR directory for user ticket caches, you may
+also want to set \fIccache_dir\fR to move those temporary caches to some
+other location. This will allow pam_krb5 to continue working even if the
+system \fI/tmp\fR directory is full.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and session groups.
+.IP no_ccache 4
+.IX Item "no_ccache"
+[1.0] Do not create a ticket cache after authentication. This option
+shouldn't be set in general, but is useful as part of the PAM
+configuration for a particular service that uses PAM for authentication
+but isn't creating user sessions and doesn't want the overhead of ever
+writing the user credentials to disk. When using this option, the
+application should only call \fBpam_authenticate()\fR; other functions like
+\&\fBpam_setcred()\fR, \fBpam_start_session()\fR, and \fBpam_acct_mgmt()\fR don't make sense
+with this option. Don't use this option if the application needs PAM
+account and session management calls.
+.Sp
+This option is only applicable to the auth group.
+.IP retain_after_close 4
+.IX Item "retain_after_close"
+[2.3] Normally, the user's ticket cache is destroyed when either \fBpam_end()\fR
+or \fBpam_close_session()\fR is called by the authenticating application so that
+ticket caches aren't left behind after the user logs out. In some cases,
+however, this isn't desirable. (On Solaris 8, for instance, the default
+behavior means login will destroy the ticket cache before running the
+user's shell.) If this option is set, the PAM module will never destroy
+the user's ticket cache. If you set this, you may want to call
+\&\fBkdestroy\fR in the shell's logout configuration or run a temporary file
+removal program to avoid accumulating hundreds of ticket caches in
+\&\fI/tmp\fR.
+.Sp
+This option can be set in \f(CW\*(C`[appdefaults]\*(C'\fR in \fIkrb5.conf\fR and is only
+applicable to the auth and session groups.
+.SH ENVIRONMENT
+.IX Header "ENVIRONMENT"
+.IP KRB5CCNAME 4
+.IX Item "KRB5CCNAME"
+Set by \fBpam_setcred()\fR with the PAM_ESTABLISH_CRED option, and therefore
+also by \fBpam_open_session()\fR, to point to the new credential cache for the
+user. See the \fIccache\fR and \fIccache_dir\fR options. By default, the cache
+name will be prefixed with \f(CW\*(C`FILE:\*(C'\fR to make the cache type unambiguous.
+.IP PAM_KRB5CCNAME 4
+.IX Item "PAM_KRB5CCNAME"
+Set by \fBpam_authenticate()\fR to point to the temporary ticket cache used for
+authentication (unless the \fIno_ccache\fR option was given). \fBpam_setcred()\fR
+then uses that environment variable to locate the temporary cache even if
+it was not called in the same PAM session as \fBpam_authenticate()\fR (a problem
+with \fBsshd\fR running in some modes). This environment variable is only
+used internal to the PAM module.
+.SH FILES
+.IX Header "FILES"
+.IP \fI/tmp/krb5cc_UID_RANDOM\fR 4
+.IX Item "/tmp/krb5cc_UID_RANDOM"
+The default credential cache name. UID is the decimal UID of the local
+user and RANDOM is a random six-character string. The pattern may be
+changed with the \fIccache\fR option and the directory with the \fIccache_dir\fR
+option.
+.IP \fI/tmp/krb5cc_pam_RANDOM\fR 4
+.IX Item "/tmp/krb5cc_pam_RANDOM"
+The credential cache name used for the temporary credential cache created
+by \fBpam_authenticate()\fR. This cache is removed again when the PAM session
+is ended or when \fBpam_setcred()\fR is called and will normally not be
+user-visible. RANDOM is a random six-character string.
+.IP \fI~/.k5login\fR 4
+.IX Item "~/.k5login"
+File containing Kerberos principals that are allowed access to that
+account.
+.SH BUGS
+.IX Header "BUGS"
+If \fItry_pkinit\fR is set and pam\-krb5 is built with MIT Kerberos, the
+user's password is not saved in the PAM data if PKINIT fails and the
+module falls back to password authentication.
+.SH CAVEATS
+.IX Header "CAVEATS"
+Be sure to list this module in the session group as well as the auth group
+when using it for interactive logins. Otherwise, some applications (such
+as OpenSSH) will not set up the user's ticket cache correctly.
+.PP
+The Kerberos library, via pam\-krb5, will prompt the user to change their
+password if their password is expired, but when using OpenSSH, this will
+only work when ChallengeResponseAuthentication is enabled. Unless this
+option is enabled, OpenSSH doesn't pass PAM messages to the user and can
+only respond to a simple password prompt.
+.PP
+If you are using MIT Kerberos, be aware that users whose passwords are
+expired will not be prompted to change their password unless the KDC
+configuration for your realm in [realms] in krb5.conf contains a
+master_kdc setting or, if using DNS SRV records, you have a DNS entry for
+_kerberos\-master as well as _kerberos.
+.PP
+\&\fBpam_authenticate()\fR returns failure when called for an ignored account,
+requiring the system administrator to use \f(CW\*(C`optional\*(C'\fR or \f(CW\*(C`sufficient\*(C'\fR to
+ignore the module and move on to the next module. It's arguably more
+correct to return PAM_IGNORE, which causes the module to be ignored as if
+it weren't in the configuration, but this increases the risk of
+inadvertent security holes when listing pam\-krb5 as the only
+authentication module.
+.PP
+This module treats the empty password as an authentication failure
+rather than attempting to use that password to avoid unwanted prompting
+behavior in the Kerberos libraries. If you have a Kerberos principal that
+intentionally has an empty password, it won't work with this module.
+.PP
+This module will not refresh an existing ticket cache if called with an
+effective UID or GID different than the real UID or GID, since refreshing
+an existing ticket cache requires trusting the KRB5CCNAME environment
+variable and the environment should not be trusted in a setuid context.
+.PP
+Old versions of OpenSSH are known to call pam_authenticate followed by
+pam_setcred(PAM_REINITIALIZE_CRED) without first calling pam_open_session,
+thereby requesting that an existing ticket cache be renewed (similar to
+what a screensaver would want) rather than requesting a new ticket cache
+be created. Since this behavior is indistinguishable at the PAM level
+from a screensaver, pam\-krb5 when used with these old versions of OpenSSH
+will refresh the ticket cache of the OpenSSH daemon rather than setting up
+a new ticket cache for the user. The resulting ticket cache will have the
+correct permissions, but will not be named correctly or referenced in the
+user's environment and will be overwritten by the next user login. The
+best solution to this problem is to upgrade OpenSSH. I'm not sure exactly
+when this problem was fixed, but at the very least OpenSSH 4.3 and later
+do not exhibit it.
+.SH AUTHOR
+.IX Header "AUTHOR"
+pam\-krb5 was originally written by Frank Cusack. Andres Salomon made
+extensive modifications, and then Russ Allbery <eagle@eyrie.org> adopted
+it and made even more extensive modifications. Russ Allbery currently
+maintains the module.
+.SH "COPYRIGHT AND LICENSE"
+.IX Header "COPYRIGHT AND LICENSE"
+Copyright 2005\-2010, 2014, 2020 Russ Allbery <eagle@eyrie.org>
+.PP
+Copyright 2008\-2014 The Board of Trustees of the Leland Stanford Junior
+University
+.PP
+Copying and distribution of this file, with or without modification, are
+permitted in any medium without royalty provided the copyright notice and
+this notice are preserved. This file is offered as-is, without any
+warranty.
+.PP
+SPDX-License-Identifier: FSFAP
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fBkadmin\fR\|(8), \fBkdestroy\fR\|(1), \fBkrb5.conf\fR\|(5), \fBpam\fR\|(7), \fBpasswd\fR\|(1), \fBsyslog\fR\|(3)
+.PP
+The current version of this module is available from its web page at
+<https://www.eyrie.org/~eagle/software/pam\-krb5/>.
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5.8 b/lib/libpam/modules/pam_krb5/pam_krb5.8
index b59fdbdee9c4..7c1770961272 100644
--- a/lib/libpam/modules/pam_krb5/pam_krb5.8
+++ b/lib/libpam/modules/pam_krb5/pam_krb5.8
@@ -222,9 +222,9 @@ file containing Kerberos principals that are allowed access.
.Sh SEE ALSO
.Xr kdestroy 1 ,
.Xr passwd 1 ,
+.Xr pam 3 ,
.Xr syslog 3 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
.Sh NOTES
Applications should not call
.Fn pam_authenticate
diff --git a/lib/libpam/modules/pam_krb5/pam_krb5.c b/lib/libpam/modules/pam_krb5/pam_krb5.c
index 34f457d07a40..e13c1b794d5b 100644
--- a/lib/libpam/modules/pam_krb5/pam_krb5.c
+++ b/lib/libpam/modules/pam_krb5/pam_krb5.c
@@ -47,7 +47,6 @@
*
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
@@ -61,6 +60,10 @@
#include <krb5.h>
#include <com_err.h>
+#ifdef MK_MITKRB5
+/* For MIT KRB5 only. */
+#include <k5-int.h>
+#endif
#define PAM_SM_AUTH
#define PAM_SM_ACCOUNT
diff --git a/lib/libpam/modules/pam_ksu/Makefile b/lib/libpam/modules/pam_ksu/Makefile
index c5fd72d9db7d..953ca23d1416 100644
--- a/lib/libpam/modules/pam_ksu/Makefile
+++ b/lib/libpam/modules/pam_ksu/Makefile
@@ -25,10 +25,21 @@
PACKAGE= kerberos
+.include <src.opts.mk>
+
LIB= pam_ksu
SRCS= pam_ksu.c
MAN= pam_ksu.8
+WARNS?= 3
LIBADD+= krb5
+.if ${MK_MITKRB5} != "no"
+WARNS= 2
+CFLAGS+= -I${SRCTOP}/crypto/krb5/src/include
+CFLAGS+= -I${SRCTOP}/krb5/include
+CFLAGS+= -include ${SRCTOP}/crypto/krb5/src/include/k5-int.h
+CFLAGS+= -DMK_MITKRB5=yes
+.endif
+
.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_ksu/pam_ksu.8 b/lib/libpam/modules/pam_ksu/pam_ksu.8
index 36d6936423b1..ace570ea5b5b 100644
--- a/lib/libpam/modules/pam_ksu/pam_ksu.8
+++ b/lib/libpam/modules/pam_ksu/pam_ksu.8
@@ -115,6 +115,6 @@ the user is prompted for another password.
.El
.Sh SEE ALSO
.Xr su 1 ,
+.Xr pam 3 ,
.Xr syslog 3 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
diff --git a/lib/libpam/modules/pam_ksu/pam_ksu.c b/lib/libpam/modules/pam_ksu/pam_ksu.c
index 9a203f694e61..002613188d8c 100644
--- a/lib/libpam/modules/pam_ksu/pam_ksu.c
+++ b/lib/libpam/modules/pam_ksu/pam_ksu.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
+
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
@@ -48,6 +48,62 @@ static long get_su_principal(krb5_context, const char *, const char *,
static int auth_krb5(pam_handle_t *, krb5_context, const char *,
krb5_principal);
+#ifdef MK_MITKRB5
+/* For MIT KRB5 only. */
+
+/*
+ * XXX This entire module will need to be rewritten when heimdal
+ * XXX compatidibility is no longer needed.
+ */
+#define KRB5_DEFAULT_CCFILE_ROOT "/tmp/krb5cc_"
+#define KRB5_DEFAULT_CCROOT "FILE:" KRB5_DEFAULT_CCFILE_ROOT
+
+/*
+ * XXX We will replace krb5_build_principal_va() with
+ * XXX krb5_build_principal_alloc_va() when Heimdal is finally
+ * XXX removed.
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_build_principal_va(krb5_context context,
+ krb5_principal princ,
+ unsigned int rlen,
+ const char *realm,
+ va_list ap);
+typedef char *heim_general_string;
+typedef heim_general_string Realm;
+typedef Realm krb5_realm;
+typedef const char *krb5_const_realm;
+
+static krb5_error_code
+krb5_make_principal(krb5_context context, krb5_principal principal,
+ krb5_const_realm realm, ...)
+{
+ krb5_realm temp_realm = NULL;
+ krb5_error_code rc;
+ va_list ap;
+
+ if (realm == NULL) {
+ if ((rc = krb5_get_default_realm(context, &temp_realm)))
+ return (rc);
+ realm=temp_realm;
+ }
+ va_start(ap, realm);
+ /*
+ * XXX Ideally we should be using krb5_build_principal_alloc_va()
+ * XXX here because krb5_build_principal_va() is deprecated. But,
+ * XXX this would require changes elsewhere in the calling code
+ * XXX to call krb5_free_principal() elsewhere to free the
+ * XXX principal. We can do that after Heimdal is removed from
+ * XXX our tree.
+ */
+ rc = krb5_build_principal_va(context, principal, strlen(realm), realm, ap);
+ va_end(ap);
+ if (temp_realm)
+ free(temp_realm);
+ return (rc);
+}
+#endif
+
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
int argc __unused, const char *argv[] __unused)
@@ -217,7 +273,13 @@ get_su_principal(krb5_context context, const char *target_user, const char *curr
if (rv != 0)
return (errno);
if (default_principal == NULL) {
+#ifdef MK_MITKRB5
+ /* For MIT KRB5. */
+ rv = krb5_make_principal(context, default_principal, NULL, current_user, NULL);
+#else
+ /* For Heimdal. */
rv = krb5_make_principal(context, &default_principal, NULL, current_user, NULL);
+#endif
if (rv != 0) {
PAM_LOG("Could not determine default principal name.");
return (rv);
diff --git a/lib/libpam/modules/pam_lastlog/pam_lastlog.8 b/lib/libpam/modules/pam_lastlog/pam_lastlog.8
index 6e5ba8770ada..e924016151fa 100644
--- a/lib/libpam/modules/pam_lastlog/pam_lastlog.8
+++ b/lib/libpam/modules/pam_lastlog/pam_lastlog.8
@@ -84,11 +84,11 @@ Ignore I/O failures.
.Xr last 1 ,
.Xr w 1 ,
.Xr getutxent 3 ,
+.Xr pam 3 ,
.Xr ulog_login 3 ,
.Xr ulog_logout 3 ,
.Xr pam.conf 5 ,
-.Xr lastlogin 8 ,
-.Xr pam 3
+.Xr lastlogin 8
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_login_access/login_access.c b/lib/libpam/modules/pam_login_access/login_access.c
index c6550a5a9a9d..1fbb644e2055 100644
--- a/lib/libpam/modules/pam_login_access/login_access.c
+++ b/lib/libpam/modules/pam_login_access/login_access.c
@@ -13,7 +13,6 @@ static char sccsid[] = "%Z% %M% %I% %E% %U%";
#endif
#endif
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/param.h>
#include <ctype.h>
diff --git a/lib/libpam/modules/pam_nologin/pam_nologin.8 b/lib/libpam/modules/pam_nologin/pam_nologin.8
index 30f87a65b63e..ff49749e50f1 100644
--- a/lib/libpam/modules/pam_nologin/pam_nologin.8
+++ b/lib/libpam/modules/pam_nologin/pam_nologin.8
@@ -81,8 +81,8 @@ reasons why the user's
login attempt was declined.
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr syslog 3 ,
.Xr login.conf 5 ,
.Xr nologin 5 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
diff --git a/lib/libpam/modules/pam_nologin/pam_nologin.c b/lib/libpam/modules/pam_nologin/pam_nologin.c
index d944c79814a4..16f7ebdc2e7c 100644
--- a/lib/libpam/modules/pam_nologin/pam_nologin.c
+++ b/lib/libpam/modules/pam_nologin/pam_nologin.c
@@ -36,7 +36,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/lib/libpam/modules/pam_passwdqc/Makefile b/lib/libpam/modules/pam_passwdqc/Makefile
index 60d27529dd19..91ce72928a66 100644
--- a/lib/libpam/modules/pam_passwdqc/Makefile
+++ b/lib/libpam/modules/pam_passwdqc/Makefile
@@ -1,4 +1,3 @@
-
SRCDIR= ${SRCTOP}/contrib/pam_modules/pam_passwdqc
.PATH: ${SRCDIR}
diff --git a/lib/libpam/modules/pam_passwdqc/pam_passwdqc.8 b/lib/libpam/modules/pam_passwdqc/pam_passwdqc.8
index f2ec1747d1f8..755e93520427 100644
--- a/lib/libpam/modules/pam_passwdqc/pam_passwdqc.8
+++ b/lib/libpam/modules/pam_passwdqc/pam_passwdqc.8
@@ -248,8 +248,8 @@ is that the former is incompatible with
.El
.Sh SEE ALSO
.Xr getpwnam 3 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_permit/pam_permit.8 b/lib/libpam/modules/pam_permit/pam_permit.8
index f0b2f5527066..270eaee8361d 100644
--- a/lib/libpam/modules/pam_permit/pam_permit.8
+++ b/lib/libpam/modules/pam_permit/pam_permit.8
@@ -68,6 +68,6 @@ debugging information at
level.
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr syslog 3 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
diff --git a/lib/libpam/modules/pam_radius/pam_radius.8 b/lib/libpam/modules/pam_radius/pam_radius.8
index 6b2d1ef1fa55..abc916dcfff6 100644
--- a/lib/libpam/modules/pam_radius/pam_radius.8
+++ b/lib/libpam/modules/pam_radius/pam_radius.8
@@ -123,9 +123,9 @@ The standard RADIUS client configuration file for
.Nm
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr passwd 5 ,
-.Xr radius.conf 5 ,
-.Xr pam 3
+.Xr radius.conf 5
.Sh HISTORY
The
.Nm
diff --git a/lib/libpam/modules/pam_radius/pam_radius.c b/lib/libpam/modules/pam_radius/pam_radius.c
index 418527771446..027916b38138 100644
--- a/lib/libpam/modules/pam_radius/pam_radius.c
+++ b/lib/libpam/modules/pam_radius/pam_radius.c
@@ -38,7 +38,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netdb.h>
diff --git a/lib/libpam/modules/pam_rhosts/Makefile b/lib/libpam/modules/pam_rhosts/Makefile
index af94a24599ab..4cd25fe5dfa5 100644
--- a/lib/libpam/modules/pam_rhosts/Makefile
+++ b/lib/libpam/modules/pam_rhosts/Makefile
@@ -1,4 +1,3 @@
-
LIB= pam_rhosts
SRCS= pam_rhosts.c
MAN= pam_rhosts.8
diff --git a/lib/libpam/modules/pam_rhosts/pam_rhosts.8 b/lib/libpam/modules/pam_rhosts/pam_rhosts.8
index ea005738840c..1f9716b9a0ca 100644
--- a/lib/libpam/modules/pam_rhosts/pam_rhosts.8
+++ b/lib/libpam/modules/pam_rhosts/pam_rhosts.8
@@ -78,9 +78,9 @@ was declined.
do not automatically fail if the target user's UID is 0.
.El
.Sh SEE ALSO
+.Xr pam 3 ,
.Xr hosts.equiv 5 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_rootok/pam_rootok.8 b/lib/libpam/modules/pam_rootok/pam_rootok.8
index d1ab8226e2ca..fd0a6dd3791f 100644
--- a/lib/libpam/modules/pam_rootok/pam_rootok.8
+++ b/lib/libpam/modules/pam_rootok/pam_rootok.8
@@ -69,5 +69,5 @@ authentication attempt was declined.
.El
.Sh SEE ALSO
.Xr getuid 2 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
diff --git a/lib/libpam/modules/pam_securetty/pam_securetty.8 b/lib/libpam/modules/pam_securetty/pam_securetty.8
index b19979000978..582389cf101d 100644
--- a/lib/libpam/modules/pam_securetty/pam_securetty.8
+++ b/lib/libpam/modules/pam_securetty/pam_securetty.8
@@ -84,7 +84,7 @@ authentication attempt was declined.
.El
.Sh SEE ALSO
.Xr getttynam 3 ,
+.Xr pam 3 ,
.Xr syslog 3 ,
.Xr pam.conf 5 ,
-.Xr ttys 5 ,
-.Xr pam 3
+.Xr ttys 5
diff --git a/lib/libpam/modules/pam_securetty/pam_securetty.c b/lib/libpam/modules/pam_securetty/pam_securetty.c
index 4bef10331f2f..4f05961e2737 100644
--- a/lib/libpam/modules/pam_securetty/pam_securetty.c
+++ b/lib/libpam/modules/pam_securetty/pam_securetty.c
@@ -36,7 +36,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
diff --git a/lib/libpam/modules/pam_self/pam_self.8 b/lib/libpam/modules/pam_self/pam_self.8
index c3623998f0be..f875d671286b 100644
--- a/lib/libpam/modules/pam_self/pam_self.8
+++ b/lib/libpam/modules/pam_self/pam_self.8
@@ -80,8 +80,8 @@ do not automatically fail if the current real user ID is 0.
.El
.Sh SEE ALSO
.Xr getuid 2 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.8 b/lib/libpam/modules/pam_ssh/pam_ssh.8
index e63930eb5340..3ef44d8b687b 100644
--- a/lib/libpam/modules/pam_ssh/pam_ssh.8
+++ b/lib/libpam/modules/pam_ssh/pam_ssh.8
@@ -138,8 +138,8 @@ SSH2 Ed25519 key
.El
.Sh SEE ALSO
.Xr ssh-agent 1 ,
-.Xr pam.conf 5 ,
-.Xr pam 3
+.Xr pam 3 ,
+.Xr pam.conf 5
.Sh AUTHORS
The
.Nm
diff --git a/lib/libpam/modules/pam_ssh/pam_ssh.c b/lib/libpam/modules/pam_ssh/pam_ssh.c
index d79676244694..157908b6b910 100644
--- a/lib/libpam/modules/pam_ssh/pam_ssh.c
+++ b/lib/libpam/modules/pam_ssh/pam_ssh.c
@@ -35,7 +35,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/wait.h>
diff --git a/lib/libpam/modules/pam_tacplus/pam_tacplus.c b/lib/libpam/modules/pam_tacplus/pam_tacplus.c
index 297c1e761d44..dd19d7da0557 100644
--- a/lib/libpam/modules/pam_tacplus/pam_tacplus.c
+++ b/lib/libpam/modules/pam_tacplus/pam_tacplus.c
@@ -36,7 +36,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <pwd.h>
diff --git a/lib/libpam/modules/pam_unix/pam_unix.8 b/lib/libpam/modules/pam_unix/pam_unix.8
index 170cf65f34db..5c2ae5cf52e2 100644
--- a/lib/libpam/modules/pam_unix/pam_unix.8
+++ b/lib/libpam/modules/pam_unix/pam_unix.8
@@ -201,10 +201,10 @@ password database.
.Xr getlogin 2 ,
.Xr crypt 3 ,
.Xr getpwent 3 ,
+.Xr pam 3 ,
.Xr syslog 3 ,
.Xr nsswitch.conf 5 ,
.Xr passwd 5 ,
-.Xr pam 3 ,
.Xr pw 8 ,
.Xr yp 8
.Sh BUGS
diff --git a/lib/libpam/modules/pam_unix/pam_unix.c b/lib/libpam/modules/pam_unix/pam_unix.c
index 3949e6f126ff..88313f6ebae8 100644
--- a/lib/libpam/modules/pam_unix/pam_unix.c
+++ b/lib/libpam/modules/pam_unix/pam_unix.c
@@ -36,7 +36,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
diff --git a/lib/libpam/modules/pam_xdg/Makefile b/lib/libpam/modules/pam_xdg/Makefile
new file mode 100644
index 000000000000..df3948987da6
--- /dev/null
+++ b/lib/libpam/modules/pam_xdg/Makefile
@@ -0,0 +1,5 @@
+LIB= pam_xdg
+SRCS= pam_xdg.c
+MAN= pam_xdg.8
+
+.include <bsd.lib.mk>
diff --git a/lib/libpam/modules/pam_xdg/pam_xdg.8 b/lib/libpam/modules/pam_xdg/pam_xdg.8
new file mode 100644
index 000000000000..9b335751a9fb
--- /dev/null
+++ b/lib/libpam/modules/pam_xdg/pam_xdg.8
@@ -0,0 +1,65 @@
+.\" * SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2024 Beckhoff Automation GmbH & Co. KG
+.\"
+.\" * 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.
+.Dd May 20, 2025
+.Dt PAM_XDG 8
+.Os
+.Sh NAME
+.Nm pam_xdg
+.Nd XDG PAM module
+.Sh SYNOPSIS
+.Op Ar service-name
+.Ar module-type
+.Ar control-flag
+.Pa pam_xdg
+.Op Ar arguments
+.Sh DESCRIPTION
+The xdg service module for PAM creates the runtime files base directory
+according to the Cross Desktop Group Base Directory Specification.
+.Pp
+By default the directory is created under
+.Pa /var/run/xdg/ Ns $ Ns Ev USER .
+.Pp
+The following option may be passed to the authentication module:
+.Bl -tag -width "runtime_dir_prefix=directory"
+.It Cm runtime_dir_prefix Ns = Ns Ar directory
+Use an alternate base directory
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width indent
+.It Ev XDG_RUNTIME_DIR
+The location of the runtime files base directory created by this module.
+Note that the module does not set this environment variable.
+.El
+.Sh STANDARDS
+The directory created by this module conforms to the
+.Lk https://specifications.freedesktop.org/basedir-spec XDG Base Directory Specification .
+.Sh SEE ALSO
+.Xr pam 3 ,
+.Xr pam.conf 5
+.Sh AUTHORS
+The
+.Nm
+module and this manual page were written by
+.An Emmanuel Vadot Aq Mt manu@FreeBSD.org .
diff --git a/lib/libpam/modules/pam_xdg/pam_xdg.c b/lib/libpam/modules/pam_xdg/pam_xdg.c
new file mode 100644
index 000000000000..10c6467776a3
--- /dev/null
+++ b/lib/libpam/modules/pam_xdg/pam_xdg.c
@@ -0,0 +1,329 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Beckhoff Automation GmbH & Co. KG
+ *
+ * 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.
+ */
+
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
+#define PAM_SM_SESSION
+
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include <security/pam_mod_misc.h>
+
+#define BASE_RUNTIME_DIR_PREFIX "/var/run/xdg"
+#define RUNTIME_DIR_PREFIX runtime_dir_prefix != NULL ? runtime_dir_prefix : BASE_RUNTIME_DIR_PREFIX
+
+#define RUNTIME_DIR_PREFIX_MODE 0711
+#define RUNTIME_DIR_MODE 0700 /* XDG spec */
+
+#define XDG_MAX_SESSION 100 /* Arbitrary limit because we need one */
+
+static int
+_pam_xdg_open(pam_handle_t *pamh, int flags __unused,
+ int argc __unused, const char *argv[] __unused)
+{
+ struct passwd *passwd;
+ const char *user;
+ const char *runtime_dir_prefix;
+ struct stat sb;
+ char *runtime_dir = NULL;
+ char *xdg_session_file;
+ int rv, rt_dir_prefix, rt_dir, session_file, i;
+
+ session_file = -1;
+ rt_dir_prefix = -1;
+ runtime_dir_prefix = openpam_get_option(pamh, "runtime_dir_prefix");
+
+ /* Get user info */
+ rv = pam_get_item(pamh, PAM_USER, (const void **)&user);
+ if (rv != PAM_SUCCESS || user == NULL) {
+ PAM_VERBOSE_ERROR("Can't get user information");
+ goto out;
+ }
+ if ((passwd = getpwnam(user)) == NULL) {
+ PAM_VERBOSE_ERROR("Can't get user information");
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+
+ /* Open or create the base xdg directory */
+ rt_dir_prefix = open(RUNTIME_DIR_PREFIX, O_DIRECTORY | O_NOFOLLOW);
+ if (rt_dir_prefix < 0) {
+ rt_dir_prefix = mkdir(RUNTIME_DIR_PREFIX, RUNTIME_DIR_PREFIX_MODE);
+ if (rt_dir_prefix != 0) {
+ PAM_VERBOSE_ERROR("Can't mkdir %s", RUNTIME_DIR_PREFIX);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ rt_dir_prefix = open(RUNTIME_DIR_PREFIX, O_DIRECTORY | O_NOFOLLOW);
+ }
+
+ /* Open or create the user xdg directory */
+ rt_dir = openat(rt_dir_prefix, user, O_DIRECTORY | O_NOFOLLOW);
+ if (rt_dir < 0) {
+ rt_dir = mkdirat(rt_dir_prefix, user, RUNTIME_DIR_MODE);
+ if (rt_dir != 0) {
+ PAM_VERBOSE_ERROR("mkdir: %s/%s (%d)", RUNTIME_DIR_PREFIX, user, rt_dir);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ rv = fchownat(rt_dir_prefix, user, passwd->pw_uid, passwd->pw_gid, 0);
+ if (rv != 0) {
+ PAM_VERBOSE_ERROR("fchownat: %s/%s (%d)", RUNTIME_DIR_PREFIX, user, rv);
+ rv = unlinkat(rt_dir_prefix, user, AT_REMOVEDIR);
+ if (rv == -1)
+ PAM_VERBOSE_ERROR("unlinkat: %s/%s (%d)", RUNTIME_DIR_PREFIX, user, errno);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ } else {
+ close(rt_dir);
+ /* Check that the already create dir is correctly owned */
+ rv = fstatat(rt_dir_prefix, user, &sb, 0);
+ if (rv == -1) {
+ PAM_VERBOSE_ERROR("fstatat %s/%s failed (%d)", RUNTIME_DIR_PREFIX, user, errno);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ if (sb.st_uid != passwd->pw_uid ||
+ sb.st_gid != passwd->pw_gid) {
+ PAM_VERBOSE_ERROR("%s/%s isn't owned by %d:%d\n", RUNTIME_DIR_PREFIX, user, passwd->pw_uid, passwd->pw_gid);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ /* Test directory mode */
+ if ((sb.st_mode & 0x1FF) != RUNTIME_DIR_MODE) {
+ PAM_VERBOSE_ERROR("%s/%s have wrong mode\n", RUNTIME_DIR_PREFIX, user);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ }
+
+ /* Setup the environment variable */
+ rv = asprintf(&runtime_dir, "XDG_RUNTIME_DIR=%s/%s", RUNTIME_DIR_PREFIX, user);
+ if (rv < 0) {
+ PAM_VERBOSE_ERROR("asprintf failed %d\n", rv);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ rv = pam_putenv(pamh, runtime_dir);
+ if (rv != PAM_SUCCESS) {
+ PAM_VERBOSE_ERROR("pam_putenv: failed (%d)", rv);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+
+ /* Setup the session count file */
+ for (i = 0; i < XDG_MAX_SESSION; i++) {
+ rv = asprintf(&xdg_session_file, "%s/xdg_session.%d", user, i);
+ if (rv < 0) {
+ PAM_VERBOSE_ERROR("asprintf failed %d\n", rv);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ rv = 0;
+ session_file = openat(rt_dir_prefix, xdg_session_file, O_CREAT | O_EXCL, RUNTIME_DIR_MODE);
+ free(xdg_session_file);
+ if (session_file >= 0)
+ break;
+ }
+ if (session_file < 0) {
+ PAM_VERBOSE_ERROR("Too many sessions");
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+
+out:
+ if (session_file >= 0)
+ close(session_file);
+ if (rt_dir_prefix >= 0)
+ close(rt_dir_prefix);
+
+ if (runtime_dir)
+ free(runtime_dir);
+ return (rv);
+}
+
+static int
+remove_dir(int fd)
+{
+ DIR *dirp;
+ struct dirent *dp;
+
+ dirp = fdopendir(fd);
+ if (dirp == NULL)
+ return (-1);
+
+ while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_type == DT_DIR) {
+ int dirfd;
+
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ dirfd = openat(fd, dp->d_name, 0);
+ remove_dir(dirfd);
+ close(dirfd);
+ unlinkat(fd, dp->d_name, AT_REMOVEDIR);
+ continue;
+ }
+ unlinkat(fd, dp->d_name, 0);
+ }
+ closedir(dirp);
+
+ return (0);
+}
+
+static int
+_pam_xdg_close(pam_handle_t *pamh __unused, int flags __unused,
+ int argc __unused, const char *argv[] __unused)
+{
+ struct passwd *passwd;
+ const char *user;
+ const char *runtime_dir_prefix;
+ struct stat sb;
+ char *xdg_session_file;
+ int rv, rt_dir_prefix, rt_dir, session_file, i;
+
+ rt_dir = -1;
+ rt_dir_prefix = -1;
+ runtime_dir_prefix = openpam_get_option(pamh, "runtime_dir_prefix");
+
+ /* Get user info */
+ rv = pam_get_item(pamh, PAM_USER, (const void **)&user);
+ if (rv != PAM_SUCCESS || user == NULL) {
+ PAM_VERBOSE_ERROR("Can't get user information");
+ goto out;
+ }
+ if ((passwd = getpwnam(user)) == NULL) {
+ PAM_VERBOSE_ERROR("Can't get user information");
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+
+ /* Open the xdg base directory */
+ rt_dir_prefix = open(RUNTIME_DIR_PREFIX, O_DIRECTORY | O_NOFOLLOW);
+ if (rt_dir_prefix < 0) {
+ PAM_VERBOSE_ERROR("open: %s failed (%d)\n", runtime_dir_prefix, rt_dir_prefix);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ /* Check that the already created dir is correctly owned */
+ rv = fstatat(rt_dir_prefix, user, &sb, 0);
+ if (rv == -1) {
+ PAM_VERBOSE_ERROR("fstatat %s/%s failed (%d)", RUNTIME_DIR_PREFIX, user, errno);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ if (sb.st_uid != passwd->pw_uid ||
+ sb.st_gid != passwd->pw_gid) {
+ PAM_VERBOSE_ERROR("%s/%s isn't owned by %d:%d\n", RUNTIME_DIR_PREFIX, user, passwd->pw_uid, passwd->pw_gid);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ /* Test directory mode */
+ if ((sb.st_mode & 0x1FF) != RUNTIME_DIR_MODE) {
+ PAM_VERBOSE_ERROR("%s/%s have wrong mode\n", RUNTIME_DIR_PREFIX, user);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+
+ /* Open the user xdg directory */
+ rt_dir = openat(rt_dir_prefix, user, O_DIRECTORY | O_NOFOLLOW);
+ if (rt_dir < 0) {
+ PAM_VERBOSE_ERROR("openat: %s/%s failed (%d)\n", RUNTIME_DIR_PREFIX, user, rt_dir_prefix);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+
+ /* Get the last session file created */
+ for (i = XDG_MAX_SESSION; i >= 0; i--) {
+ rv = asprintf(&xdg_session_file, "%s/xdg_session.%d", user, i);
+ if (rv < 0) {
+ PAM_VERBOSE_ERROR("asprintf failed %d\n", rv);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ rv = 0;
+ session_file = openat(rt_dir_prefix, xdg_session_file, 0);
+ if (session_file >= 0) {
+ unlinkat(rt_dir_prefix, xdg_session_file, 0);
+ free(xdg_session_file);
+ break;
+ }
+ free(xdg_session_file);
+ }
+ if (session_file < 0) {
+ PAM_VERBOSE_ERROR("Can't find session number\n");
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ close(session_file);
+
+ /* Final cleanup if last user session */
+ if (i == 0) {
+ remove_dir(rt_dir);
+ if (unlinkat(rt_dir_prefix, user, AT_REMOVEDIR) != 0) {
+ PAM_VERBOSE_ERROR("Can't cleanup %s/%s\n", runtime_dir_prefix, user);
+ rv = PAM_SESSION_ERR;
+ goto out;
+ }
+ }
+
+ rv = PAM_SUCCESS;
+out:
+ if (rt_dir >= 0)
+ close(rt_dir);
+ if (rt_dir_prefix >= 0)
+ close(rt_dir_prefix);
+ return (rv);
+}
+
+PAM_EXTERN int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+
+ return (_pam_xdg_open(pamh, flags, argc, argv));
+}
+
+PAM_EXTERN int
+pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+
+ return (_pam_xdg_close(pamh, flags, argc, argv));
+}
+
+PAM_MODULE_ENTRY("pam_xdg");