rpms/krb5/devel krb5-1.8-api.patch, NONE, 1.1 krb5-1.8-dirsrv-accountlock.patch, NONE, 1.1 krb5-1.8-exp_warn.patch, NONE, 1.1 krb5-1.8-key_exp.patch, NONE, 1.1 krb5-1.8-kpasswd_ccache.patch, NONE, 1.1 krb5-1.8-kpasswd_tcp.patch, NONE, 1.1 krb5-1.8-kprop-mktemp.patch, NONE, 1.1 krb5-1.8-ksu-access.patch, NONE, 1.1 krb5-1.8-ksu-path.patch, NONE, 1.1 krb5-1.8-manpaths.patch, NONE, 1.1 krb5-1.8-opte.patch, NONE, 1.1 krb5-1.8-pam.patch, NONE, 1.1 krb5-1.8-selinux-label.patch, NONE, 1.1 krb5-appl-1.0-io.patch, NONE, 1.1 krb5-appl-1.0-largefile.patch, NONE, 1.1 krb5-appl-1.0-login_chdir.patch, NONE, 1.1 krb5-appl-1.0-manpaths.patch, NONE, 1.1 krb5-appl-1.0-pam.patch, NONE, 1.1 krb5-appl-1.0-rlogind-environ.patch, NONE, 1.1 .cvsignore, 1.28, 1.29 kadmind.init, 1.19, 1.20 kpropd.init, 1.10, 1.11 krb5.spec, 1.244, 1.245 krb5kdc.init, 1.14, 1.15 sources, 1.30, 1.31 2010-001-patch.txt, 1.1, NONE krb5-1.3-ksu-access.patch, 1.1, NONE krb5-1.3-rlogind-environ.patch, 1.3, NONE krb5-1.5-ksu-path.patch, 1.1, NONE krb5-1.6.2-key_exp.patch, 1.4, NONE krb5-1.6.2-login_chdir.patch, 1.1, NONE krb5-1.6.3-login-lpass.patch, 1.1, NONE krb5-1.7-api.patch, 1.1, NONE krb5-1.7-dirsrv-accountlock.patch, 1.1, NONE krb5-1.7-exp_warn.patch, 1.1, NONE krb5-1.7-io.patch, 1.1, NONE krb5-1.7-kprop-mktemp.patch, 1.1, NONE krb5-1.7-largefile.patch, 1.3, NONE krb5-1.7-openssl-1.0.patch, 1.1, NONE krb5-1.7-opte.patch, 1.1, NONE krb5-1.7-pam.patch, 1.5, NONE krb5-1.7-selinux-label.patch, 1.9, NONE krb5-1.7-time_t_size.patch, 1.3, NONE krb5-1.7.1-kpasswd_ccache.patch, 1.1, NONE krb5-trunk-kpasswd_tcp.patch, 1.2, NONE krb5-trunk-manpaths.patch, 1.7, NONE

Nalin Dahyabhai nalin at fedoraproject.org
Fri Mar 5 22:19:38 UTC 2010


Author: nalin

Update of /cvs/extras/rpms/krb5/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18527

Modified Files:
	.cvsignore kadmind.init kpropd.init krb5.spec krb5kdc.init 
	sources 
Added Files:
	krb5-1.8-api.patch krb5-1.8-dirsrv-accountlock.patch 
	krb5-1.8-exp_warn.patch krb5-1.8-key_exp.patch 
	krb5-1.8-kpasswd_ccache.patch krb5-1.8-kpasswd_tcp.patch 
	krb5-1.8-kprop-mktemp.patch krb5-1.8-ksu-access.patch 
	krb5-1.8-ksu-path.patch krb5-1.8-manpaths.patch 
	krb5-1.8-opte.patch krb5-1.8-pam.patch 
	krb5-1.8-selinux-label.patch krb5-appl-1.0-io.patch 
	krb5-appl-1.0-largefile.patch krb5-appl-1.0-login_chdir.patch 
	krb5-appl-1.0-manpaths.patch krb5-appl-1.0-pam.patch 
	krb5-appl-1.0-rlogind-environ.patch 
Removed Files:
	2010-001-patch.txt krb5-1.3-ksu-access.patch 
	krb5-1.3-rlogind-environ.patch krb5-1.5-ksu-path.patch 
	krb5-1.6.2-key_exp.patch krb5-1.6.2-login_chdir.patch 
	krb5-1.6.3-login-lpass.patch krb5-1.7-api.patch 
	krb5-1.7-dirsrv-accountlock.patch krb5-1.7-exp_warn.patch 
	krb5-1.7-io.patch krb5-1.7-kprop-mktemp.patch 
	krb5-1.7-largefile.patch krb5-1.7-openssl-1.0.patch 
	krb5-1.7-opte.patch krb5-1.7-pam.patch 
	krb5-1.7-selinux-label.patch krb5-1.7-time_t_size.patch 
	krb5-1.7.1-kpasswd_ccache.patch krb5-trunk-kpasswd_tcp.patch 
	krb5-trunk-manpaths.patch 
Log Message:
- update to 1.8
  - temporarily bundling the krb5-appl package (split upstream as of 1.8)
    until its package review is complete
  - profile.d scriptlets are now only needed by -workstation-clients
  - adjust paths in init scripts
  - drop upstreamed fix for KDC denial of service (CVE-2010-0283)
  - drop patch to check the user's password correctly using crypt(), which
    isn't a code path we hit when we're using PAM


krb5-1.8-api.patch:
 princ_comp.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- NEW FILE krb5-1.8-api.patch ---
Reference docs don't define what happens if you call krb5_realm_compare() with
malformed krb5_principal structures.  Define a behavior which keeps it from
crashing if applications don't check ahead of time.

diff -up krb5-1.8/src/lib/krb5/krb/princ_comp.c.api krb5-1.8/src/lib/krb5/krb/princ_comp.c
--- krb5-1.8/src/lib/krb5/krb/princ_comp.c.api	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/lib/krb5/krb/princ_comp.c	2010-03-05 11:00:55.000000000 -0500
@@ -41,6 +41,12 @@ realm_compare_flags(krb5_context context
     const krb5_data *realm1 = krb5_princ_realm(context, princ1);
     const krb5_data *realm2 = krb5_princ_realm(context, princ2);
 
+    if ((princ1 == NULL) || (princ2 == NULL))
+        return FALSE;
+
+    if ((realm1 == NULL) || (realm2 == NULL))
+        return FALSE;
+
     if (realm1->length != realm2->length)
         return FALSE;
 
@@ -92,6 +98,9 @@ krb5_principal_compare_flags(krb5_contex
     krb5_principal upn2 = NULL;
     krb5_boolean ret = FALSE;
 
+    if ((princ1 == NULL) || (princ2 == NULL))
+        return FALSE;
+
     if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) {
         /* Treat UPNs as if they were real principals */
         if (krb5_princ_type(context, princ1) == KRB5_NT_ENTERPRISE_PRINCIPAL) {

krb5-1.8-dirsrv-accountlock.patch:
 aclocal.m4                                    |   10 ++++++++++
 plugins/kdb/ldap/libkdb_ldap/ldap_misc.c      |   16 ++++++++++++++++
 plugins/kdb/ldap/libkdb_ldap/ldap_principal.c |    3 +++
 3 files changed, 29 insertions(+)

--- NEW FILE krb5-1.8-dirsrv-accountlock.patch ---
Treat 'nsAccountLock: true' the same as 'loginDisabled: true'.  Updated from
original version filed as RT#5891.

diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4
--- krb5-1.8/src/aclocal.m4.dirsrv-accountlock	2010-03-05 11:03:09.000000000 -0500
+++ krb5-1.8/src/aclocal.m4	2010-03-05 11:03:10.000000000 -0500
@@ -1678,6 +1678,12 @@ AC_ARG_WITH([edirectory],
     yes | no) ;;
     *)  AC_MSG_ERROR(Invalid option value --with-edirectory="$withval") ;;
 esac], with_edirectory=no)dnl
+AC_ARG_WITH([dirsrv],
+[  --with-dirsrv       compile 389/Red Hat/Fedora/Netscape Directory Server database backend module],
+[case "$withval" in
+    yes | no) ;;
+    *)  AC_MSG_ERROR(Invalid option value --with-dirsrv="$withval") ;;
+esac], with_dirsrv=no)dnl
 
 if test $with_ldap = yes; then
   if test $with_edirectory = yes; then
@@ -1689,6 +1695,10 @@ elif test $with_edirectory = yes; then
   AC_MSG_NOTICE(enabling eDirectory database backend module support)
   OPENLDAP_PLUGIN=yes
   AC_DEFINE(HAVE_EDIRECTORY,1,[Define if LDAP KDB interface should assume eDirectory.])
+elif test $with_dirsrv = yes; then
+  AC_MSG_NOTICE(enabling 389/Red Hat/Fedora/Netscape Directory Server database backend module support)
+  OPENLDAP_PLUGIN=yes
+  AC_DEFINE(HAVE_DIRSRV,1,[Define if LDAP KDB interface should assume RHDS/FDS/NDS.])
 else
   : # neither enabled
 dnl  AC_MSG_NOTICE(disabling ldap backend module support)
diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
--- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock	2009-11-24 18:52:25.000000000 -0500
+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2010-03-05 11:03:10.000000000 -0500
@@ -2101,6 +2101,22 @@ populate_krb5_db_entry(krb5_context cont
         }
     }
 #endif
+#ifdef HAVE_DIRSRV
+    {
+        krb5_timestamp              expiretime=0;
+        char                        *is_login_disabled=NULL;
+
+        /* LOGIN DISABLED */
+        if ((st=krb5_ldap_get_string(ld, ent, "nsaccountlock", &is_login_disabled,
+                    &attr_present)) != 0)
+            goto cleanup;
+        if (attr_present == TRUE) {
+            if (strcasecmp(is_login_disabled, "TRUE")== 0)
+                entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+            free (is_login_disabled);
+        }
+    }
+#endif
 
     if ((st=krb5_read_tkt_policy (context, ldap_context, entry, tktpolname)) !=0)
         goto cleanup;
diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
--- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock	2009-11-24 18:52:25.000000000 -0500
+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c	2010-03-05 11:03:10.000000000 -0500
@@ -59,6 +59,9 @@ char     *principal_attributes[] = { "kr
                                      "loginexpirationtime",
                                      "logindisabled",
 #endif
+#ifdef HAVE_DIRSRV
+                                     "nsaccountlock",
+#endif
                                      "krbLastPwdChange",
                                      "krbExtraData",
                                      "krbObjectReferences",

krb5-1.8-exp_warn.patch:
 gic_pwd.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- NEW FILE krb5-1.8-exp_warn.patch ---
Don't warn of expiration reported the new way if it's more than a week from
now, for consistency with the code that handles expiration times reported the
old way.

diff -up krb5-1.8/src/lib/krb5/krb/gic_pwd.c.exp_warn krb5-1.8/src/lib/krb5/krb/gic_pwd.c
--- krb5-1.8/src/lib/krb5/krb/gic_pwd.c.exp_warn	2010-03-05 11:04:10.000000000 -0500
+++ krb5-1.8/src/lib/krb5/krb/gic_pwd.c	2010-03-05 11:04:10.000000000 -0500
@@ -407,7 +407,8 @@ cleanup:
                                  delta / 86400, ts);
                     /* ignore an error here */
                     /* PROMPTER_INVOCATION */
-                    (*prompter)(context, data, 0, banner, 0, 0);
+                    if (delta < 86400 * 7)
+                        (*prompter)(context, data, 0, banner, 0, 0);
                 }
         }
     }

krb5-1.8-key_exp.patch:
 do_as_req.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

--- NEW FILE krb5-1.8-key_exp.patch ---
Sadique Puthen notes that the warning on the client side seems to be correspond
to the wrong attribute on the KDC.  Do what RFC4120 says we should do.  RT#5755.

diff -up krb5-1.8/src/kdc/do_as_req.c.key_exp krb5-1.8/src/kdc/do_as_req.c
--- krb5-1.8/src/kdc/do_as_req.c.key_exp	2010-02-16 17:21:08.000000000 -0500
+++ krb5-1.8/src/kdc/do_as_req.c	2010-03-05 11:02:06.000000000 -0500
@@ -555,7 +555,14 @@ process_as_req(krb5_kdc_req *request, kr
         goto errout;
     }
     reply_encpart.nonce = request->nonce;
-    reply_encpart.key_exp = client.expiration;
+    if (client.expiration == 0) {
+       reply_encpart.key_exp = client.pw_expiration;
+    } else if (client.pw_expiration == 0) {
+       reply_encpart.key_exp = client.expiration;
+    } else {
+       reply_encpart.key_exp = client.pw_expiration < client.expiration ?
+                               client.pw_expiration : client.expiration;
+    }
     reply_encpart.flags = enc_tkt_reply.flags;
     reply_encpart.server = ticket_reply.server;
 

krb5-1.8-kpasswd_ccache.patch:
 kpasswd.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

--- NEW FILE krb5-1.8-kpasswd_ccache.patch ---
If we encounter any errors reading the user's principal name from the default
ccache, fall back to the default of using the current user's name.

diff -up krb5-1.8/src/clients/kpasswd/kpasswd.c.kpasswd-ccache krb5-1.8/src/clients/kpasswd/kpasswd.c
--- krb5-1.8/src/clients/kpasswd/kpasswd.c.kpasswd-ccache	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/clients/kpasswd/kpasswd.c	2010-03-05 11:04:42.000000000 -0500
@@ -85,21 +85,23 @@ int main(int argc, char *argv[])
             exit(1);
         }
     } else if ((ret = krb5_cc_default(context, &ccache)) != KRB5_CC_NOTFOUND) {
+        princ = NULL;
+
         if (ret) {
             com_err(argv[0], ret, "opening default ccache");
-            exit(1);
         }
+        else
 
         if ((ret = krb5_cc_get_principal(context, ccache, &princ))) {
             com_err(argv[0], ret, "getting principal from ccache");
-            exit(1);
         }
+        else
 
         if ((ret = krb5_cc_close(context, ccache))) {
             com_err(argv[0], ret, "closing ccache");
-            exit(1);
         }
-    } else {
+    }
+    if (princ == NULL) {
         get_name_from_passwd_file(argv[0], context, &princ);
     }
 

krb5-1.8-kpasswd_tcp.patch:
 changepw.c |   21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

--- NEW FILE krb5-1.8-kpasswd_tcp.patch ---
Fall back to TCP on kdc-unresolvable/unreachable errors.  We still have
to wait for UDP to fail, so this might not be ideal.  RT #5868.

diff -up krb5-1.8/src/lib/krb5/os/changepw.c.kpasswd_tcp krb5-1.8/src/lib/krb5/os/changepw.c
--- krb5-1.8/src/lib/krb5/os/changepw.c.kpasswd_tcp	2009-12-02 13:06:19.000000000 -0500
+++ krb5-1.8/src/lib/krb5/os/changepw.c	2010-03-05 11:02:39.000000000 -0500
@@ -270,11 +270,22 @@ change_set_password(krb5_context context
                                    NULL,
                                    NULL
              ))) {
-
-            /*
-             * Here we may want to switch to TCP on some errors.
-             * right?
-             */
+            /* if we're not using a stream socket, and it's an error which
+             * might reasonably be specific to a datagram "connection", try
+             * again with a stream socket */
+            if (!useTcp) {
+                switch (code) {
+                case KRB5_KDC_UNREACH:
+                case KRB5_REALM_CANT_RESOLVE:
+                case KRB5KRB_ERR_RESPONSE_TOO_BIG:
+                /* should we do this for more result codes than these? */
+                    krb5int_free_addrlist (&al);
+                    useTcp = 1;
+                    continue;
+                default:
+                    break;
+                }
+            }
             break;
         }
 

krb5-1.8-kprop-mktemp.patch:
 kprop.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

--- NEW FILE krb5-1.8-kprop-mktemp.patch ---
Use an in-memory ccache to silence a compiler warning.

diff -up krb5-1.8/src/slave/kprop.c.kprop-mktemp krb5-1.8/src/slave/kprop.c
--- krb5-1.8/src/slave/kprop.c.kprop-mktemp	2009-11-06 18:29:12.000000000 -0500
+++ krb5-1.8/src/slave/kprop.c	2010-03-05 10:59:06.000000000 -0500
@@ -202,9 +202,8 @@ void PRS(argc, argv)
 void get_tickets(context)
     krb5_context context;
 {
-    char   buf[BUFSIZ];
+    char buf[] = "MEMORY:_kproptkt";
     krb5_error_code retval;
-    static char tkstring[] = "/tmp/kproptktXXXXXX";
     krb5_keytab keytab = NULL;
 
     /*
@@ -229,11 +228,8 @@ void get_tickets(context)
 #endif
 
     /*
-     * Initialize cache file which we're going to be using
+     * Initialize an in-memory cache for temporary use
      */
-    (void) mktemp(tkstring);
-    snprintf(buf, sizeof(buf), "FILE:%s", tkstring);
-
     retval = krb5_cc_resolve(context, buf, &ccache);
     if (retval) {
         com_err(progname, retval, "while opening credential cache %s",

krb5-1.8-ksu-access.patch:
 ccache.c    |    2 +-
 heuristic.c |    4 ++--
 main.c      |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

--- NEW FILE krb5-1.8-ksu-access.patch ---
The idea is to not complain about problems in the default ticket file if we
couldn't read it, because the client would be able to tell if it's there or
not.  Still needs work, I think.

diff -up krb5-1.8/src/clients/ksu/ccache.c.ksu-access krb5-1.8/src/clients/ksu/ccache.c
--- krb5-1.8/src/clients/ksu/ccache.c.ksu-access	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/clients/ksu/ccache.c	2010-03-05 10:57:56.000000000 -0500
@@ -78,7 +78,7 @@ krb5_error_code krb5_ccache_copy (contex
     cc_def_name = krb5_cc_get_name(context, cc_def);
     cc_other_name = krb5_cc_get_name(context, *cc_other);
 
-    if ( ! stat(cc_def_name, &st_temp)){
+    if ( ! access(cc_def_name, R_OK) && ! stat(cc_def_name, &st_temp)){
         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
             return retval;
         }
diff -up krb5-1.8/src/clients/ksu/heuristic.c.ksu-access krb5-1.8/src/clients/ksu/heuristic.c
--- krb5-1.8/src/clients/ksu/heuristic.c.ksu-access	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/clients/ksu/heuristic.c	2010-03-05 10:57:56.000000000 -0500
@@ -409,7 +409,7 @@ krb5_error_code find_either_ticket (cont
 
     cc_source_name = krb5_cc_get_name(context, cc);
 
-    if ( ! stat(cc_source_name, &st_temp)){
+    if ( ! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)){
 
         retval = find_ticket(context, cc, client, end_server, &temp_found);
         if (retval)
@@ -569,7 +569,7 @@ krb5_error_code get_best_princ_for_targe
     cc_source_name = krb5_cc_get_name(context, cc_source);
 
 
-    if (! stat(cc_source_name, &st_temp)) {
+    if (! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)) {
         retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ);
         if (retval)
             return retval;
diff -up krb5-1.8/src/clients/ksu/main.c.ksu-access krb5-1.8/src/clients/ksu/main.c
--- krb5-1.8/src/clients/ksu/main.c.ksu-access	2010-03-05 10:57:55.000000000 -0500
+++ krb5-1.8/src/clients/ksu/main.c	2010-03-05 10:57:56.000000000 -0500
@@ -270,7 +270,7 @@ main (argc, argv)
                 if ( strchr(cc_source_tag, ':')){
                     cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
 
-                    if( stat( cc_source_tag_tmp, &st_temp)){
+                    if( access( cc_source_tag_tmp, F_OK | R_OK) || stat( cc_source_tag_tmp, &st_temp)){
                         com_err (prog_name, errno,
                                  "while looking for credentials file %s",
                                  cc_source_tag_tmp);

krb5-1.8-ksu-path.patch:
 Makefile.in |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE krb5-1.8-ksu-path.patch ---
Set the default PATH to the one set by login.

diff -up krb5-1.8/src/clients/ksu/Makefile.in.ksu-path krb5-1.8/src/clients/ksu/Makefile.in
--- krb5-1.8/src/clients/ksu/Makefile.in.ksu-path	2010-03-05 10:58:25.000000000 -0500
+++ krb5-1.8/src/clients/ksu/Makefile.in	2010-03-05 10:58:25.000000000 -0500
@@ -1,6 +1,6 @@
 mydir=clients/ksu
 BUILDTOP=$(REL)..$(S)..
-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
+DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /usr/sbin /bin /usr/bin"'
 DEFS=
 
 PROG_LIBPATH=-L$(TOPLIBD)

krb5-1.8-manpaths.patch:
 aclocal.m4                    |   21 +++++++++++++++++++++
 appl/sample/sserver/sserver.M |    2 +-
 config-files/kdc.conf.M       |    6 +++---
 config-files/krb5.conf.M      |    2 +-
 configure.in                  |   10 ++++++++++
 kadmin/cli/kadmin.M           |    6 +++---
 slave/kprop.M                 |    4 ++--
 slave/kpropd.M                |   10 +++++-----
 8 files changed, 46 insertions(+), 15 deletions(-)

--- NEW FILE krb5-1.8-manpaths.patch ---
Change the absolute paths included in the man pages so that the correct
values can be dropped in by config.status.  After applying this patch,
these files should be renamed to their ".in" counterparts, and then the
configure scripts should be rebuilt.  Originally RT#6525

diff -up krb5-1.8/src/aclocal.m4.manpaths krb5-1.8/src/aclocal.m4
--- krb5-1.8/src/aclocal.m4.manpaths	2010-03-05 10:55:28.000000000 -0500
+++ krb5-1.8/src/aclocal.m4	2010-03-05 10:55:29.000000000 -0500
@@ -1770,3 +1770,24 @@ AC_SUBST(PAM_LIBS)
 AC_SUBST(PAM_MAN)
 AC_SUBST(NON_PAM_MAN)
 ])dnl
+AC_DEFUN(V5_AC_OUTPUT_MANPAGE,[
+mansysconfdir=$sysconfdir
+mansysconfdir=`eval echo $mansysconfdir | sed -e "s,NONE,$prefix,g"`
+mansysconfdir=`eval echo $mansysconfdir | sed -e "s,NONE,$ac_default_prefix,g"`
+mansbindir=$sbindir
+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$exec_prefix,g"`
+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$prefix,g"`
+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$ac_default_prefix,g"`
+manlocalstatedir=$localstatedir
+manlocalstatedir=`eval echo $manlocalstatedir | sed -e "s,NONE,$prefix,g"`
+manlocalstatedir=`eval echo $manlocalstatedir | sed -e "s,NONE,$ac_default_prefix,g"`
+manlibexecdir=$libexecdir
+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$exec_prefix,g"`
+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$prefix,g"`
+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$ac_default_prefix,g"`
+AC_SUBST(mansysconfdir)
+AC_SUBST(mansbindir)
+AC_SUBST(manlocalstatedir)
+AC_SUBST(manlibexecdir)
+AC_CONFIG_FILES($1)
+])
diff -up krb5-1.8/src/appl/sample/sserver/sserver.M.manpaths krb5-1.8/src/appl/sample/sserver/sserver.M
--- krb5-1.8/src/appl/sample/sserver/sserver.M.manpaths	1999-09-24 17:20:59.000000000 -0400
+++ krb5-1.8/src/appl/sample/sserver/sserver.M	2010-03-05 10:55:29.000000000 -0500
@@ -59,7 +59,7 @@ option allows for a different keytab tha
 using a line in
 /etc/inetd.conf that looks like this:
 .PP
-sample  stream  tcp     nowait  root /usr/local/sbin/sserver	sserver
+sample  stream  tcp     nowait  root @mansbindir@/sserver	sserver
 .PP
 Since \fBsample\fP is normally not a port defined in /etc/services, you will
 usually have to add a line to /etc/services which looks like this:
diff -up krb5-1.8/src/config-files/kdc.conf.M.manpaths krb5-1.8/src/config-files/kdc.conf.M
--- krb5-1.8/src/config-files/kdc.conf.M.manpaths	2010-01-04 14:34:33.000000000 -0500
+++ krb5-1.8/src/config-files/kdc.conf.M	2010-03-05 10:55:29.000000000 -0500
@@ -82,14 +82,14 @@ This
 .B string
 specifies the location of the access control list (acl) file that
 kadmin uses to determine which principals are allowed which permissions
-on the database. The default value is /usr/local/var/krb5kdc/kadm5.acl.
+on the database. The default value is @manlocalstatedir@/krb5kdc/kadm5.acl.
 
 .IP admin_keytab
 This
 .B string
 Specifies the location of the keytab file that kadmin uses to
 authenticate to the database.  The default value is
-/usr/local/var/krb5kdc/kadm5.keytab.
+ at manlocalstatedir@/krb5kdc/kadm5.keytab.
 
 .IP database_name
 This
@@ -254,7 +254,7 @@ tickets should be checked against the tr
 realm names and the [capaths] section of its krb5.conf file
 
 .SH FILES 
-/usr/local/var/krb5kdc/kdc.conf
+ at manlocalstatedir@/krb5kdc/kdc.conf
 
 .SH SEE ALSO
 krb5.conf(5), krb5kdc(8)
diff -up krb5-1.8/src/config-files/krb5.conf.M.manpaths krb5-1.8/src/config-files/krb5.conf.M
--- krb5-1.8/src/config-files/krb5.conf.M.manpaths	2010-02-25 15:14:21.000000000 -0500
+++ krb5-1.8/src/config-files/krb5.conf.M	2010-03-05 10:55:29.000000000 -0500
@@ -651,6 +651,6 @@ is whitespace-separated. The LDAP server
 This LDAP specific tag indicates the number of connections to be maintained per
 LDAP server.
 .SH FILES 
-/etc/krb5.conf
+ at mansysconfdir@/krb5.conf
 .SH SEE ALSO
 syslog(3)
diff -up krb5-1.8/src/configure.in.manpaths krb5-1.8/src/configure.in
--- krb5-1.8/src/configure.in.manpaths	2010-03-05 10:55:29.000000000 -0500
+++ krb5-1.8/src/configure.in	2010-03-05 10:55:29.000000000 -0500
@@ -1054,6 +1054,16 @@ fi
 KRB5_WITH_PAM
 
 AC_CONFIG_FILES(krb5-config, [chmod +x krb5-config])
+
+V5_AC_OUTPUT_MANPAGE([
+	appl/sample/sserver/sserver.M
+	config-files/kdc.conf.M
+	config-files/krb5.conf.M
+	kadmin/cli/kadmin.M
+	slave/kpropd.M
+	slave/kprop.M
+])
+
 V5_AC_OUTPUT_MAKEFILE(.
 
 	util util/support util/profile util/send-pr
diff -up krb5-1.8/src/kadmin/cli/kadmin.M.manpaths krb5-1.8/src/kadmin/cli/kadmin.M
--- krb5-1.8/src/kadmin/cli/kadmin.M.manpaths	2010-01-04 14:59:25.000000000 -0500
+++ krb5-1.8/src/kadmin/cli/kadmin.M	2010-03-05 10:55:29.000000000 -0500
@@ -869,9 +869,9 @@ option is specified, less verbose status
 .RS
 .TP
 EXAMPLE:
-kadmin: ktremove -k /usr/local/var/krb5kdc/kadmind.keytab kadmin/admin
+kadmin: ktremove -k @manlocalstatedir@/krb5kdc/kadmind.keytab kadmin/admin
 Entry for principal kadmin/admin with kvno 3 removed
-	from keytab WRFILE:/usr/local/var/krb5kdc/kadmind.keytab.
+	from keytab WRFILE:@manlocalstatedir@/krb5kdc/kadmind.keytab.
 kadmin:
 .RE
 .fi
@@ -913,7 +913,7 @@ passwords.
 .SH HISTORY
 The
 .B kadmin
-prorgam was originally written by Tom Yu at MIT, as an interface to the
+program was originally written by Tom Yu at MIT, as an interface to the
 OpenVision Kerberos administration program.
 .SH SEE ALSO
 .IR kerberos (1),
diff -up krb5-1.8/src/slave/kpropd.M.manpaths krb5-1.8/src/slave/kpropd.M
--- krb5-1.8/src/slave/kpropd.M.manpaths	2009-12-30 23:21:34.000000000 -0500
+++ krb5-1.8/src/slave/kpropd.M	2010-03-05 10:55:29.000000000 -0500
@@ -74,7 +74,7 @@ Normally, kpropd is invoked out of 
 This is done by adding a line to the inetd.conf file which looks like
 this:
 
-kprop	stream	tcp	nowait	root	/usr/local/sbin/kpropd	kpropd
+kprop	stream	tcp	nowait	root	@mansbindir@/kpropd	kpropd
 
 However, kpropd can also run as a standalone daemon, if the
 .B \-S
@@ -111,13 +111,13 @@ is used.
 \fB\-f\fP \fIfile\fP
 specifies the filename where the dumped principal database file is to be
 stored; by default the dumped database file is KPROPD_DEFAULT_FILE
-(normally /usr/local/var/krb5kdc/from_master).
+(normally @manlocalstatedir@/krb5kdc/from_master).
 .TP
 .B \-p
 allows the user to specify the pathname to the
 .IR kdb5_util (8)
 program; by default the pathname used is KPROPD_DEFAULT_KDB5_UTIL
-(normally /usr/local/sbin/kdb5_util).
+(normally @mansbindir@/kdb5_util).
 .TP
 .B \-S
 turn on standalone mode.  Normally, kpropd is invoked out of
@@ -148,14 +148,14 @@ mode.
 allows the user to specify the path to the
 kpropd.acl
 file; by default the path used is KPROPD_ACL_FILE
-(normally /usr/local/var/krb5kdc/kpropd.acl).
+(normally @manlocalstatedir@/krb5kdc/kpropd.acl).
 .SH FILES
 .TP "\w'kpropd.acl\ \ 'u"
 kpropd.acl
 Access file for
 .BR kpropd ;
 the default location is KPROPD_ACL_FILE (normally
-/usr/local/var/krb5kdc/kpropd.acl).
+ at manlocalstatedir@/krb5kdc/kpropd.acl).
 Each entry is a line containing the principal of a host from which the
 local machine will allow Kerberos database propagation via kprop.
 .SH SEE ALSO
diff -up krb5-1.8/src/slave/kprop.M.manpaths krb5-1.8/src/slave/kprop.M
--- krb5-1.8/src/slave/kprop.M.manpaths	1999-09-24 17:20:59.000000000 -0400
+++ krb5-1.8/src/slave/kprop.M	2010-03-05 10:55:29.000000000 -0500
@@ -39,7 +39,7 @@ Kerberos server to a slave Kerberos serv
 This is done by transmitting the dumped database file to the slave
 server over an encrypted, secure channel.  The dump file must be created
 by kdb5_util, and is normally KPROP_DEFAULT_FILE
-(/usr/local/var/krb5kdc/slave_datatrans).
+(@manlocalstatedir@/krb5kdc/slave_datatrans).
 .SH OPTIONS
 .TP
 \fB\-r\fP \fIrealm\fP
@@ -51,7 +51,7 @@ is used.
 \fB\-f\fP \fIfile\fP
 specifies the filename where the dumped principal database file is to be
 found; by default the dumped database file is KPROP_DEFAULT_FILE
-(normally /usr/local/var/krb5kdc/slave_datatrans).
+(normally @manlocalstatedir@/krb5kdc/slave_datatrans).
 .TP
 \fB\-P\fP \fIport\fP
 specifies the port to use to contact the

krb5-1.8-opte.patch:
 gic_pwd.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- NEW FILE krb5-1.8-opte.patch ---
Fall back to the library default for whether or not to prompt for a password-
change during authentication, if we weren't passed any options.

diff -up krb5-1.8/src/lib/krb5/krb/gic_pwd.c.opte krb5-1.8/src/lib/krb5/krb/gic_pwd.c
--- krb5-1.8/src/lib/krb5/krb/gic_pwd.c.opte	2009-12-23 11:00:05.000000000 -0500
+++ krb5-1.8/src/lib/krb5/krb/gic_pwd.c	2010-03-05 11:03:42.000000000 -0500
@@ -123,6 +123,7 @@ krb5_get_init_creds_password(krb5_contex
     int tries;
     krb5_creds chpw_creds;
     krb5_get_init_creds_opt *chpw_opts = NULL;
+    krb5_gic_opt_ext *opte = NULL;
     krb5_data pw0, pw1;
     char banner[1024], pw0array[1024], pw1array[1024];
     krb5_prompt prompt[2];
@@ -218,7 +219,8 @@ krb5_get_init_creds_password(krb5_contex
      * to prompt.  Prompting is only disabled if the option has been set
      * and the value has been set to false.
      */
-    if (!(options->flags & KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT))
+    krb5int_gic_opt_to_opte(context, options, &opte, 1, NULL);
+    if (!(opte->flags & KRB5_GET_INIT_CREDS_OPT_CHG_PWD_PRMPT))
         goto cleanup;
 
     /* ok, we have an expired password.  Give the user a few chances
@@ -332,6 +334,8 @@ krb5_get_init_creds_password(krb5_contex
                                  &use_master, &as_reply);
 
 cleanup:
+    if (opte != options)
+        krb5_get_init_creds_opt_free(context, opte);
     krb5int_set_prompt_types(context, 0);
     /* if getting the password was successful, then check to see if the
        password is about to expire, and warn if so */

krb5-1.8-pam.patch:
 aclocal.m4              |   67 ++++++++
 clients/ksu/Makefile.in |    8 
 clients/ksu/main.c      |   75 +++++++++
 clients/ksu/pam.c       |  389 ++++++++++++++++++++++++++++++++++++++++++++++++
 clients/ksu/pam.h       |   57 +++++++
 configure.in            |    2 
 6 files changed, 595 insertions(+), 3 deletions(-)

--- NEW FILE krb5-1.8-pam.patch ---
Modify ksu so that it performs account and session management for the
target user account, mimicking the action of regular su.  The default
service name is "ksu", because on Fedora at least the configuration used
is determined by whether or not a login shell is being opened, and so
this may need to vary, too.  At run-time, ksu's behavior can be reset to
the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
section of /etc/krb5.conf.

When enabled, ksu gains a dependency on libpam.

Originally RT#5939, needs updating for 1.8.

diff -up krb5-1.8/src/aclocal.m4.pam krb5-1.8/src/aclocal.m4
--- krb5-1.8/src/aclocal.m4.pam	2009-11-22 12:00:45.000000000 -0500
+++ krb5-1.8/src/aclocal.m4	2010-03-05 10:48:08.000000000 -0500
@@ -1703,3 +1703,70 @@ AC_DEFUN(KRB5_AC_KEYRING_CCACHE,[
       ]))
 ])dnl
 dnl
+dnl
+dnl Use PAM instead of local crypt() compare for checking local passwords,
+dnl and perform PAM account, session management, and password-changing where
+dnl appropriate.
+dnl 
+AC_DEFUN(KRB5_WITH_PAM,[
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
+	    withpam="$withval",withpam=auto)
+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
+	    withksupamservice="$withval",withksupamservice=ksu)
+old_LIBS="$LIBS"
+if test "$withpam" != no ; then
+	AC_MSG_RESULT([checking for PAM...])
+	PAM_LIBS=
+
+	AC_CHECK_HEADERS(security/pam_appl.h)
+	if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
+		if test "$withpam" = auto ; then
+			AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
+			withpam=no
+		else
+			AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
+		fi
+	fi
+
+	LIBS=
+	unset ac_cv_func_pam_start
+	AC_CHECK_FUNCS(putenv pam_start)
+	if test "x$ac_cv_func_pam_start" = xno ; then
+		unset ac_cv_func_pam_start
+		AC_CHECK_LIB(dl,dlopen)
+		AC_CHECK_FUNCS(pam_start)
+		if test "x$ac_cv_func_pam_start" = xno ; then
+			AC_CHECK_LIB(pam,pam_start)
+			unset ac_cv_func_pam_start
+			unset ac_cv_func_pam_getenvlist
+			AC_CHECK_FUNCS(pam_start pam_getenvlist)
+			if test "x$ac_cv_func_pam_start" = xyes ; then
+				PAM_LIBS="$LIBS"
+			else
+				if test "$withpam" = auto ; then
+					AC_MSG_RESULT([Unable to locate libpam.])
+					withpam=no
+				else
+					AC_MSG_ERROR([Unable to locate libpam.])
+				fi
+			fi
+		fi
+	fi
+	if test "$withpam" != no ; then
+		AC_MSG_NOTICE([building with PAM support])
+		AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
+		AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
+				   [Define to the name of the PAM service name to be used by ksu.])
+		PAM_LIBS="$LIBS"
+		NON_PAM_MAN=".\\\" "
+		PAM_MAN=
+	else
+		PAM_MAN=".\\\" "
+		NON_PAM_MAN=
+	fi
+fi
+LIBS="$old_LIBS"
+AC_SUBST(PAM_LIBS)
+AC_SUBST(PAM_MAN)
+AC_SUBST(NON_PAM_MAN)
+])dnl
diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/src/clients/ksu/main.c
--- krb5-1.8/src/clients/ksu/main.c.pam	2009-11-02 22:27:56.000000000 -0500
+++ krb5-1.8/src/clients/ksu/main.c	2010-03-05 10:48:08.000000000 -0500
@@ -26,6 +26,7 @@
  * KSU was writen by:  Ari Medvinsky, ari at isi.edu
  */
 
+#include "autoconf.h"
 #include "ksu.h"
 #include "adm_proto.h"
 #include <sys/types.h>
@@ -33,6 +34,10 @@
 #include <signal.h>
 #include <grp.h>
 
+#ifdef USE_PAM
+#include "pam.h"
+#endif
+
 /* globals */
 char * prog_name;
 int auth_debug =0;
@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
 char k5users_path[MAXPATHLEN];
 char * gb_err = NULL;
 int quiet = 0;
+int force_fork = 0;
 /***********/
 
 #define _DEF_CSH "/bin/csh"
@@ -586,6 +592,25 @@ main (argc, argv)
                prog_name,target_user,client_name,
                source_user,ontty());
 
+#ifdef USE_PAM
+        if (appl_pam_enabled(ksu_context, "ksu")) {
+            if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
+                                   NULL, source_user,
+                                   ttyname(STDERR_FILENO)) != 0) {
+                fprintf(stderr, "Access denied for %s.\n", target_user);
+                sweep_up(ksu_context, cc_target);
+                exit(1);
+            }
+            if (appl_pam_requires_chauthtok()) {
+                fprintf(stderr, "Password change required for %s.\n",
+                        target_user);
+                sweep_up(ksu_context, cc_target);
+                exit(1);
+            }
+            force_fork++;
+        }
+#endif
+
         /* Run authorization as target.*/
         if (krb5_seteuid(target_uid)) {
             com_err(prog_name, errno, "while switching to target for authorization check");
@@ -792,7 +817,7 @@ main (argc, argv)
         fprintf(stderr, "program to be execed %s\n",params[0]);
     }
 
-    if( keep_target_cache ) {
+    if( keep_target_cache && !force_fork ) {
         execv(params[0], params);
         com_err(prog_name, errno, "while trying to execv %s",
                 params[0]);
@@ -800,6 +825,33 @@ main (argc, argv)
         exit(1);
     }else{
         statusp = 1;
+
+#ifdef USE_PAM
+        if (appl_pam_enabled(ksu_context, "ksu")) {
+            if (appl_pam_session_open() != 0) {
+                fprintf(stderr, "Error opening session for %s.\n", target_user);
+                sweep_up(ksu_context, cc_target);
+                exit(1);
+            }
+#ifdef DEBUG
+            if (auth_debug){
+                printf(" Opened PAM session.\n");
+            }
+#endif
+            if (appl_pam_cred_init()) {
+                fprintf(stderr, "Error initializing credentials for %s.\n",
+                        target_user);
+                sweep_up(ksu_context, cc_target);
+                exit(1);
+            }
+#ifdef DEBUG
+            if (auth_debug){
+                printf(" Initialized PAM credentials.\n");
+            }
+#endif
+        }
+#endif
+
         switch ((child_pid = fork())) {
         default:
             if (auth_debug){
@@ -823,15 +875,34 @@ main (argc, argv)
             if (ret_pid == -1) {
                 com_err(prog_name, errno, "while calling waitpid");
             }
-            sweep_up(ksu_context, cc_target);
+            if( !keep_target_cache ) {
+                sweep_up(ksu_context, cc_target);
+            }
             exit (statusp);
         case -1:
             com_err(prog_name, errno, "while trying to fork.");
             sweep_up(ksu_context, cc_target);
             exit (1);
         case 0:
+#ifdef USE_PAM
+            if (appl_pam_enabled(ksu_context, "ksu")) {
+                if (appl_pam_setenv() != 0) {
+                    fprintf(stderr, "Error setting up environment for %s.\n",
+                            target_user);
+                    exit (1);
+                }
+#ifdef DEBUG
+                if (auth_debug){
+                    printf(" Set up PAM environment.\n");
+                }
+#endif
+            }
+#endif
             execv(params[0], params);
             com_err(prog_name, errno, "while trying to execv %s", params[0]);
+            if( keep_target_cache ) {
+                sweep_up(ksu_context, cc_target);
+            }
             exit (1);
         }
     }
diff -up krb5-1.8/src/clients/ksu/Makefile.in.pam krb5-1.8/src/clients/ksu/Makefile.in
--- krb5-1.8/src/clients/ksu/Makefile.in.pam	2009-11-22 13:13:29.000000000 -0500
+++ krb5-1.8/src/clients/ksu/Makefile.in	2010-03-05 11:55:14.000000000 -0500
@@ -7,12 +7,14 @@
 PROG_RPATH=$(KRB5_LIBDIR)
 
 KSU_LIBS=@KSU_LIBS@
+PAM_LIBS=@PAM_LIBS@
 
 SRCS = \
 	$(srcdir)/krb_auth_su.c \
 	$(srcdir)/ccache.c \
 	$(srcdir)/authorization.c \
 	$(srcdir)/main.c \
+	$(srcdir)/pam.c \
 	$(srcdir)/heuristic.c \
 	$(srcdir)/xmalloc.c \
 	$(srcdir)/setenv.c
@@ -21,13 +23,17 @@ OBJS = \
 	ccache.o \
 	authorization.o \
 	main.o \
+	pam.o \
 	heuristic.o \
 	xmalloc.o @SETENVOBJ@
 
 all:: ksu
 
 ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
-	$(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
+	$(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
+
+pam.o: pam.c
+	$(CC) $(ALL_CFLAGS) -c $<
 
 clean::
 	$(RM) ksu
diff -up krb5-1.8/src/clients/ksu/pam.c.pam krb5-1.8/src/clients/ksu/pam.c
--- krb5-1.8/src/clients/ksu/pam.c.pam	2010-03-05 10:48:08.000000000 -0500
+++ krb5-1.8/src/clients/ksu/pam.c	2010-03-05 10:48:08.000000000 -0500
@@ -0,0 +1,389 @@
+/*
+ * src/clients/ksu/pam.c
+ *
+ * Copyright 2007,2009,2010 Red Hat, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice, this
+ *  list of conditions and the following disclaimer.
+ *
+ *  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.
+ *
+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ * 
+ * Convenience wrappers for using PAM.
+ */
+
+#include "autoconf.h"
+#ifdef USE_PAM
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "k5-int.h"
+#include "pam.h"
+
+#ifndef MAXPWSIZE
+#define MAXPWSIZE 128
+#endif
+
+static int appl_pam_started;
+static pid_t appl_pam_starter = -1;
+static int appl_pam_session_opened;
+static int appl_pam_creds_initialized;
+static int appl_pam_pwchange_required;
+static pam_handle_t *appl_pamh;
+static struct pam_conv appl_pam_conv;
+static char *appl_pam_user;
+struct appl_pam_non_interactive_args {
+	const char *user;
+	const char *password;
+};
+
+int
+appl_pam_enabled(krb5_context context, const char *section)
+{
+	int enabled = 1;
+	if ((context != NULL) && (context->profile != NULL)) {
+		if (profile_get_boolean(context->profile,
+					section,
+					USE_PAM_CONFIGURATION_KEYWORD,
+					NULL,
+					enabled, &enabled) != 0) {
+			enabled = 1;
+		}
+	}
+	return enabled;
+}
+
+void
+appl_pam_cleanup(void)
+{
+	if (getpid() != appl_pam_starter) {
+		return;
+	}
+#ifdef DEBUG
+	printf("Called to clean up PAM.\n");
+#endif
+	if (appl_pam_creds_initialized) {
+#ifdef DEBUG
+		printf("Deleting PAM credentials.\n");
+#endif
+		pam_setcred(appl_pamh, PAM_DELETE_CRED);
+		appl_pam_creds_initialized = 0;
+	}
+	if (appl_pam_session_opened) {
+#ifdef DEBUG
+		printf("Closing PAM session.\n");
+#endif
+		pam_close_session(appl_pamh, 0);
+		appl_pam_session_opened = 0;
+	}
+	appl_pam_pwchange_required = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Shutting down PAM.\n");
+#endif
+		pam_end(appl_pamh, 0);
+		appl_pam_started = 0;
+		appl_pam_starter = -1;
+		free(appl_pam_user);
+		appl_pam_user = NULL;
+	}
+}
+static int
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
+			      struct pam_response **presp, void *appdata_ptr)
+{
+	const struct pam_message *message;
+	struct pam_response *resp;
+	int i, code;
+	char *pwstring, pwbuf[MAXPWSIZE];
+	unsigned int pwsize;
+	resp = malloc(sizeof(struct pam_response) * num_msg);
+	if (resp == NULL) {
+		return PAM_BUF_ERR;
+	}
+	memset(resp, 0, sizeof(struct pam_response) * num_msg);
+	code = PAM_SUCCESS;
+	for (i = 0; i < num_msg; i++) {
+		message = &(msg[0][i]); /* XXX */
+		message = msg[i]; /* XXX */
+		pwstring = NULL;
+		switch (message->msg_style) {
+		case PAM_TEXT_INFO:
+		case PAM_ERROR_MSG:
+			printf("[%s]\n", message->msg ? message->msg : "");
+			fflush(stdout);
+			resp[i].resp = NULL;
+			resp[i].resp_retcode = PAM_SUCCESS;
+			break;
+		case PAM_PROMPT_ECHO_ON:
+		case PAM_PROMPT_ECHO_OFF:
+			if (message->msg_style == PAM_PROMPT_ECHO_ON) {
+				if (fgets(pwbuf, sizeof(pwbuf),
+					  stdin) != NULL) {
+					pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
+					pwstring = pwbuf;
+				}
+			} else {
+				pwstring = getpass(message->msg ?
+						   message->msg :
+						   "");
+			}
+			if ((pwstring != NULL) && (pwstring[0] != '\0')) {
+				pwsize = strlen(pwstring);
+				resp[i].resp = malloc(pwsize + 1);
+				if (resp[i].resp == NULL) {
+					resp[i].resp_retcode = PAM_BUF_ERR;
+				} else {
+					memcpy(resp[i].resp, pwstring, pwsize);
+					resp[i].resp[pwsize] = '\0';
+					resp[i].resp_retcode = PAM_SUCCESS;
+				}
+			} else {
+				resp[i].resp_retcode = PAM_CONV_ERR;
+				code = PAM_CONV_ERR;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	*presp = resp;
+	return code;
+}
+static int
+appl_pam_non_interactive_converse(int num_msg,
+				  const struct pam_message **msg,
+				  struct pam_response **presp,
+				  void *appdata_ptr)
+{
+	const struct pam_message *message;
+	struct pam_response *resp;
+	int i, code;
+	unsigned int pwsize;
+	struct appl_pam_non_interactive_args *args;
+	const char *pwstring;
+	resp = malloc(sizeof(struct pam_response) * num_msg);
+	if (resp == NULL) {
+		return PAM_BUF_ERR;
+	}
+	args = appdata_ptr;
+	memset(resp, 0, sizeof(struct pam_response) * num_msg);
+	code = PAM_SUCCESS;
+	for (i = 0; i < num_msg; i++) {
+		message = &((*msg)[i]);
+		message = msg[i];
+		pwstring = NULL;
+		switch (message->msg_style) {
+		case PAM_TEXT_INFO:
+		case PAM_ERROR_MSG:
+			break;
+		case PAM_PROMPT_ECHO_ON:
+		case PAM_PROMPT_ECHO_OFF:
+			if (message->msg_style == PAM_PROMPT_ECHO_ON) {
+				/* assume "user" */
+				pwstring = args->user;
+			} else {
+				/* assume "password" */
+				pwstring = args->password;
+			}
+			if ((pwstring != NULL) && (pwstring[0] != '\0')) {
+				pwsize = strlen(pwstring);
+				resp[i].resp = malloc(pwsize + 1);
+				if (resp[i].resp == NULL) {
+					resp[i].resp_retcode = PAM_BUF_ERR;
+				} else {
+					memcpy(resp[i].resp, pwstring, pwsize);
+					resp[i].resp[pwsize] = '\0';
+					resp[i].resp_retcode = PAM_SUCCESS;
+				}
+			} else {
+				resp[i].resp_retcode = PAM_CONV_ERR;
+				code = PAM_CONV_ERR;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	*presp = resp;
+	return code;
+}
+static int
+appl_pam_start(const char *service, int interactive,
+	       const char *login_username,
+	       const char *non_interactive_password,
+	       const char *hostname,
+	       const char *ruser,
+	       const char *tty)
+{
+	static int exit_handler_registered;
+	static struct appl_pam_non_interactive_args args;
+	int ret = 0;
+	if (appl_pam_started &&
+	    (strcmp(login_username, appl_pam_user) != 0)) {
+		appl_pam_cleanup();
+		appl_pam_user = NULL;
+	}
+	if (!appl_pam_started) {
+#ifdef DEBUG
+		printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
+		       service, login_username);
+#endif
+		memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
+		appl_pam_conv.conv = interactive ?
+				     &appl_pam_interactive_converse :
+				     &appl_pam_non_interactive_converse;
+		memset(&args, 0, sizeof(args));
+		args.user = strdup(login_username);
+		args.password = non_interactive_password ?
+				strdup(non_interactive_password) :
+				NULL;
+		appl_pam_conv.appdata_ptr = &args;
+		ret = pam_start(service, login_username,
+				&appl_pam_conv, &appl_pamh);
+		if (ret == 0) {
+			if (hostname != NULL) {
+#ifdef DEBUG
+				printf("Setting PAM_RHOST to \"%s\".\n", hostname);
+#endif
+				pam_set_item(appl_pamh, PAM_RHOST, hostname);
+			}
+			if (ruser != NULL) {
+#ifdef DEBUG
+				printf("Setting PAM_RUSER to \"%s\".\n", ruser);
+#endif
+				pam_set_item(appl_pamh, PAM_RUSER, ruser);
+			}
+			if (tty != NULL) {
+#ifdef DEBUG
+				printf("Setting PAM_TTY to \"%s\".\n", tty);
+#endif
+				pam_set_item(appl_pamh, PAM_TTY, tty);
+			}
+			if (!exit_handler_registered &&
+			    (atexit(appl_pam_cleanup) != 0)) {
+				pam_end(appl_pamh, 0);
+				appl_pamh = NULL;
+				ret = -1;
+			} else {
+				appl_pam_started = 1;
+				appl_pam_starter = getpid();
+				appl_pam_user = strdup(login_username);
+				exit_handler_registered = 1;
+			}
+		}
+	}
+	return ret;
+}
+int
+appl_pam_acct_mgmt(const char *service, int interactive,
+		   const char *login_username,
+		   const char *non_interactive_password,
+		   const char *hostname,
+		   const char *ruser,
+		   const char *tty)
+{
+	int ret;
+	appl_pam_pwchange_required = 0;
+	ret = appl_pam_start(service, interactive, login_username,
+			     non_interactive_password, hostname, ruser, tty);
+	if (ret == 0) {
+#ifdef DEBUG
+		printf("Calling pam_acct_mgmt().\n");
+#endif
+		ret = pam_acct_mgmt(appl_pamh, 0);
+		switch (ret) {
+		case PAM_IGNORE:
+			ret = 0;
+			break;
+		case PAM_NEW_AUTHTOK_REQD:
+			appl_pam_pwchange_required = 1;
+			ret = 0;
+			break;
+		default:
+			break;
+		}
+	}
+	return ret;
+}
+int
+appl_pam_requires_chauthtok(void)
+{
+	return appl_pam_pwchange_required;
+}
+int
+appl_pam_session_open(void)
+{
+	int ret = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Opening PAM session.\n");
+#endif
+		ret = pam_open_session(appl_pamh, 0);
+		if (ret == 0) {
+			appl_pam_session_opened = 1;
+		}
+	}
+	return ret;
+}
+int
+appl_pam_setenv(void)
+{
+	int ret = 0;
+#ifdef HAVE_PAM_GETENVLIST
+#ifdef HAVE_PUTENV
+	int i;
+	char **list;
+	if (appl_pam_started) {
+		list = pam_getenvlist(appl_pamh);
+		for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
+#ifdef DEBUG
+			printf("Setting \"%s\" in environment.\n", list[i]);
+#endif
+			putenv(list[i]);
+		}
+	}
+#endif
+#endif
+	return ret;
+}
+int
+appl_pam_cred_init(void)
+{
+	int ret = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Initializing PAM credentials.\n");
+#endif
+		ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
+		if (ret == 0) {
+			appl_pam_creds_initialized = 1;
+		}
+	}
+	return ret;
+}
+#endif
diff -up krb5-1.8/src/clients/ksu/pam.h.pam krb5-1.8/src/clients/ksu/pam.h
--- krb5-1.8/src/clients/ksu/pam.h.pam	2010-03-05 10:48:08.000000000 -0500
+++ krb5-1.8/src/clients/ksu/pam.h	2010-03-05 10:48:08.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ * src/clients/ksu/pam.h
+ *
+ * Copyright 2007,2009,2010 Red Hat, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice, this
+ *  list of conditions and the following disclaimer.
+ *
+ *  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.
+ *
+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ * 
+ * Convenience wrappers for using PAM.
+ */
+
+#include <krb5.h>
+#ifdef HAVE_SECURITY_PAM_APPL_H
+#include <security/pam_appl.h>
+#endif
+
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
+
+#ifdef USE_PAM
+int appl_pam_enabled(krb5_context context, const char *section);
+int appl_pam_acct_mgmt(const char *service, int interactive,
+		       const char *local_username,
+		       const char *non_interactive_password,
+		       const char *hostname,
+		       const char *ruser,
+		       const char *tty);
+int appl_pam_requires_chauthtok(void);
+int appl_pam_session_open(void);
+int appl_pam_setenv(void);
+int appl_pam_cred_init(void);
+void appl_pam_cleanup(void);
+#endif
diff -up krb5-1.8/src/configure.in.pam krb5-1.8/src/configure.in
--- krb5-1.8/src/configure.in.pam	2009-12-31 18:13:56.000000000 -0500
+++ krb5-1.8/src/configure.in	2010-03-05 10:48:08.000000000 -0500
@@ -1051,6 +1051,8 @@ if test "$ac_cv_lib_socket" = "yes" -a "
 	AC_DEFINE(BROKEN_STREAMS_SOCKETS,1,[Define if socket can't be bound to 0.0.0.0])
 fi
 
+KRB5_WITH_PAM
+
 AC_CONFIG_FILES(krb5-config, [chmod +x krb5-config])
 V5_AC_OUTPUT_MAKEFILE(.
 

krb5-1.8-selinux-label.patch:
 aclocal.m4                                      |   51 +++
 config/pre.in                                   |    3 
 configure.in                                    |    2 
 include/k5-int.h                                |    1 
 include/k5-label.h                              |   30 ++
 include/krb5/krb5.hin                           |    6 
 kadmin/dbutil/dump.c                            |    2 
 krb5-config.in                                  |    3 
 lib/kadm5/logger.c                              |    4 
 lib/krb5/keytab/kt_file.c                       |    4 
 plugins/kdb/db2/adb_openclose.c                 |    2 
 plugins/kdb/db2/kdb_db2.c                       |    8 
 plugins/kdb/db2/libdb2/btree/bt_open.c          |    3 
 plugins/kdb/db2/libdb2/hash/hash.c              |    3 
 plugins/kdb/db2/libdb2/recno/rec_open.c         |    3 
 plugins/kdb/db2/libdb2/test/Makefile.in         |    3 
 plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c |   14 
 slave/kpropd.c                                  |    2 
 util/profile/prof_file.c                        |    3 
 util/support/Makefile.in                        |    3 
 util/support/selinux.c                          |  346 ++++++++++++++++++++++++
 21 files changed, 470 insertions(+), 26 deletions(-)

--- NEW FILE krb5-1.8-selinux-label.patch ---
SELinux bases access to files on the domain of the requesting process,
the operation being performed, and the context applied to the file.

In many cases, applications needn't be SELinux aware to work properly,
because SELinux can apply a default label to a file based on the label
of the directory in which it's created.

In the case of files such as /etc/krb5.keytab, however, this isn't
sufficient, as /etc/krb5.keytab will almost always need to be given a
label which differs from that of /etc/issue or /etc/resolv.conf.  The
the kdb stash file needs a different label than the database for which
it's holding a master key, even though both typically live in the same
directory.

To give the file the correct label, we can either force a "restorecon"
call to fix a file's label after it's created, or create the file with
the right label, as we attempt to do here.  We lean on THREEPARAMOPEN
and define a similar macro named WRITABLEFOPEN with which we replace
several uses of fopen().

The file creation context that we're manipulating here is a process-wide
attribute.  While for the most part, applications which need to label
files when they're created have tended to be single-threaded, there's
not much we can do to avoid interfering with an application that
manipulates the creation context directly.  Right now we're mediating
access using a library-local mutex, but that can only work for consumers
that are part of this package -- an unsuspecting application will still
stomp all over us.

The selabel APIs for looking up the context should be thread-safe (per
Red Hat #273081), so switching to using them instead of matchpathcon(),
which we used earlier, is some improvement.

diff -up krb5-1.8/src/aclocal.m4.selinux-label krb5-1.8/src/aclocal.m4
--- krb5-1.8/src/aclocal.m4.selinux-label	2010-03-05 10:57:23.000000000 -0500
+++ krb5-1.8/src/aclocal.m4	2010-03-05 10:57:23.000000000 -0500
@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag)
 dnl
 KRB5_AC_PRAGMA_WEAK_REF
 WITH_LDAP
+KRB5_WITH_SELINUX
 KRB5_LIB_PARAMS
 KRB5_AC_INITFINI
 KRB5_AC_ENABLE_THREADS
@@ -1791,3 +1792,53 @@ AC_SUBST(manlocalstatedir)
 AC_SUBST(manlibexecdir)
 AC_CONFIG_FILES($1)
 ])
+dnl
+dnl Use libselinux to set file contexts on newly-created files.
+dnl 
+AC_DEFUN(KRB5_WITH_SELINUX,[
+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])],
+           withselinux="$withval",withselinux=auto)
+old_LIBS="$LIBS"
+if test "$withselinux" != no ; then
+       AC_MSG_RESULT([checking for libselinux...])
+       SELINUX_LIBS=
+       AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h)
+       if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then
+               if test "$withselinux" = auto ; then
+                       AC_MSG_RESULT([Unable to locate selinux/selinux.h.])
+                       withselinux=no
+               else
+                       AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
+               fi
+       fi
+
+       LIBS=
+       unset ac_cv_func_setfscreatecon
+       AC_CHECK_FUNCS(setfscreatecon selabel_open)
+       if test "x$ac_cv_func_setfscreatecon" = xno ; then
+               AC_CHECK_LIB(selinux,setfscreatecon)
+               AC_CHECK_LIB(selinux,selabel_open)
+               unset ac_cv_func_setfscreatecon
+               unset ac_cv_func_selabel_open
+               AC_CHECK_FUNCS(setfscreatecon selabel_open)
+               if test "x$ac_cv_func_setfscreatecon" = xyes ; then
+                       SELINUX_LIBS="$LIBS"
+               else
+                       if test "$withselinux" = auto ; then
+                               AC_MSG_RESULT([Unable to locate libselinux.])
+                               withselinux=no
+                       else
+                               AC_MSG_ERROR([Unable to locate libselinux.])
+                       fi
+               fi
+       fi
+       if test "$withselinux" != no ; then
+               AC_MSG_NOTICE([building with SELinux labeling support])
+               AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.])
+               SELINUX_LIBS="$LIBS"
+		EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen"
+       fi
+fi
+LIBS="$old_LIBS"
+AC_SUBST(SELINUX_LIBS)
+])dnl
diff -up krb5-1.8/src/config/pre.in.selinux-label krb5-1.8/src/config/pre.in
--- krb5-1.8/src/config/pre.in.selinux-label	2010-03-05 10:57:23.000000000 -0500
+++ krb5-1.8/src/config/pre.in	2010-03-05 10:57:23.000000000 -0500
@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@
 LD_SHLIBDIR_PREFIX = @LD_SHLIBDIR_PREFIX@
 LDARGS = @LDARGS@
 LIBS = @LIBS@
+SELINUX_LIBS=@SELINUX_LIBS@
 
 INSTALL=@INSTALL@
 INSTALL_STRIP=
@@ -379,7 +380,7 @@ SUPPORT_LIB			= -l$(SUPPORT_LIBNAME)
 # HESIOD_LIBS is -lhesiod...
 HESIOD_LIBS	= @HESIOD_LIBS@
 
-KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
+KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
 KDB5_LIBS	= $(KDB5_LIB) $(GSSRPC_LIBS)
 GSS_LIBS	= $(GSS_KRB5_LIB)
 # needs fixing if ever used on Mac OS X!
diff -up krb5-1.8/src/configure.in.selinux-label krb5-1.8/src/configure.in
--- krb5-1.8/src/configure.in.selinux-label	2010-03-05 10:57:23.000000000 -0500
+++ krb5-1.8/src/configure.in	2010-03-05 10:57:23.000000000 -0500
@@ -1053,6 +1053,8 @@ fi
 
 KRB5_WITH_PAM
 
+KRB5_WITH_SELINUX
+
 AC_CONFIG_FILES(krb5-config, [chmod +x krb5-config])
 
 V5_AC_OUTPUT_MANPAGE([
diff -up krb5-1.8/src/include/k5-int.h.selinux-label krb5-1.8/src/include/k5-int.h
--- krb5-1.8/src/include/k5-int.h.selinux-label	2010-01-04 14:59:16.000000000 -0500
+++ krb5-1.8/src/include/k5-int.h	2010-03-05 10:57:23.000000000 -0500
@@ -133,6 +133,7 @@ typedef unsigned char   u_char;
 typedef UINT64_TYPE krb5_ui_8;
 typedef INT64_TYPE krb5_int64;
 
+#include "k5-label.h"
 
 #define DEFAULT_PWD_STRING1 "Enter password"
 #define DEFAULT_PWD_STRING2 "Re-enter password for verification"
diff -up krb5-1.8/src/include/k5-label.h.selinux-label krb5-1.8/src/include/k5-label.h
--- krb5-1.8/src/include/k5-label.h.selinux-label	2010-03-05 10:57:23.000000000 -0500
+++ krb5-1.8/src/include/k5-label.h	2010-03-05 10:57:23.000000000 -0500
@@ -0,0 +1,30 @@
+#ifndef _KRB5_LABEL_H
+#define _KRB5_LABEL_H
+
+#ifdef THREEPARAMOPEN
+#undef THREEPARAMOPEN
+#endif
+#ifdef WRITABLEFOPEN
+#undef WRITABLEFOPEN
+#endif
+
+/* Wrapper functions which help us create files and directories with the right
+ * context labels. */
+#ifdef USE_SELINUX
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+FILE *krb5int_labeled_fopen(const char *path, const char *mode);
+int krb5int_labeled_creat(const char *path, mode_t mode);
+int krb5int_labeled_open(const char *path, int flags, ...);
+int krb5int_labeled_mkdir(const char *path, mode_t mode);
+int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device);
+#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z)
+#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y)
+#else
+#define WRITABLEFOPEN(x,y) fopen(x,y)
+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
+#endif
+#endif
diff -up krb5-1.8/src/include/krb5/krb5.hin.selinux-label krb5-1.8/src/include/krb5/krb5.hin
--- krb5-1.8/src/include/krb5/krb5.hin.selinux-label	2010-01-21 17:49:07.000000000 -0500
+++ krb5-1.8/src/include/krb5/krb5.hin	2010-03-05 10:57:23.000000000 -0500
@@ -87,6 +87,12 @@
 #define THREEPARAMOPEN(x,y,z) open(x,y,z)
 #endif
 
+#if KRB5_PRIVATE
+#ifndef WRITABLEFOPEN
+#define WRITABLEFOPEN(x,y) fopen(x,y)
+#endif
+#endif
+
 #define KRB5_OLD_CRYPTO
 
 #include <stdlib.h>
diff -up krb5-1.8/src/kadmin/dbutil/dump.c.selinux-label krb5-1.8/src/kadmin/dbutil/dump.c
--- krb5-1.8/src/kadmin/dbutil/dump.c.selinux-label	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/kadmin/dbutil/dump.c	2010-03-05 10:57:23.000000000 -0500
@@ -1274,7 +1274,7 @@ dump_db(argc, argv)
          * want to get into.
          */
         unlink(ofile);
-        if (!(f = fopen(ofile, "w"))) {
+        if (!(f = WRITABLEFOPEN(ofile, "w"))) {
             fprintf(stderr, ofopen_error,
                     progname, ofile, error_message(errno));
             exit_status++;
diff -up krb5-1.8/src/krb5-config.in.selinux-label krb5-1.8/src/krb5-config.in
--- krb5-1.8/src/krb5-config.in.selinux-label	2010-01-21 17:49:01.000000000 -0500
+++ krb5-1.8/src/krb5-config.in	2010-03-05 10:57:23.000000000 -0500
@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@'
 PROG_RPATH_FLAGS='@PROG_RPATH_FLAGS@'
 PTHREAD_CFLAGS='@PTHREAD_CFLAGS@'
 DL_LIB='@DL_LIB@'
+SELINUX_LIBS='@SELINUX_LIBS@'
 
 LIBS='@LIBS@'
 GEN_LIB=@GEN_LIB@
@@ -214,7 +215,7 @@ if test -n "$do_libs"; then
     fi
 
     if test $library = 'krb5'; then
-	lib_flags="$lib_flags -lkrb5 -lk5crypto -lcom_err $GEN_LIB $LIBS $DL_LIB"
+	lib_flags="$lib_flags -lkrb5 -lk5crypto -lcom_err $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB"
     fi
 
     echo $lib_flags
diff -up krb5-1.8/src/lib/kadm5/logger.c.selinux-label krb5-1.8/src/lib/kadm5/logger.c
--- krb5-1.8/src/lib/kadm5/logger.c.selinux-label	2009-12-28 21:42:51.000000000 -0500
+++ krb5-1.8/src/lib/kadm5/logger.c	2010-03-05 10:57:23.000000000 -0500
@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch
                      * Check for append/overwrite, then open the file.
                      */
                     if (cp[4] == ':' || cp[4] == '=') {
-                        f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w");
+                        f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w");
                         if (f) {
                             set_cloexec_file(f);
                             log_control.log_entries[i].lfu_filep = f;
@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext)
              * In case the old logfile did not get moved out of the
              * way, open for append to prevent squashing the old logs.
              */
-            f = fopen(log_control.log_entries[lindex].lfu_fname, "a+");
+            f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+");
             if (f) {
                 set_cloexec_file(f);
                 log_control.log_entries[lindex].lfu_filep = f;
diff -up krb5-1.8/src/lib/krb5/keytab/kt_file.c.selinux-label krb5-1.8/src/lib/krb5/keytab/kt_file.c
--- krb5-1.8/src/lib/krb5/keytab/kt_file.c.selinux-label	2009-11-10 14:59:39.000000000 -0500
+++ krb5-1.8/src/lib/krb5/keytab/kt_file.c	2010-03-05 10:57:23.000000000 -0500
@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context
 
     KTCHECKLOCK(id);
     errno = 0;
-    KTFILEP(id) = fopen(KTFILENAME(id),
+    KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
                         (mode == KRB5_LOCKMODE_EXCLUSIVE) ?
                         fopen_mode_rbplus : fopen_mode_rb);
     if (!KTFILEP(id)) {
@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context
             /* try making it first time around */
             krb5_create_secure_file(context, KTFILENAME(id));
             errno = 0;
-            KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus);
+            KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus);
             if (!KTFILEP(id))
                 goto report_errno;
             writevno = 1;
diff -up krb5-1.8/src/plugins/kdb/db2/adb_openclose.c.selinux-label krb5-1.8/src/plugins/kdb/db2/adb_openclose.c
--- krb5-1.8/src/plugins/kdb/db2/adb_openclose.c.selinux-label	2009-11-24 18:52:25.000000000 -0500
+++ krb5-1.8/src/plugins/kdb/db2/adb_openclose.c	2010-03-05 10:57:23.000000000 -0500
@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char 
          * POSIX systems
          */
         lockp->lockinfo.filename = strdup(lockfilename);
-        if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) {
+        if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) {
             /*
              * maybe someone took away write permission so we could only
              * get shared locks?
diff -up krb5-1.8/src/plugins/kdb/db2/kdb_db2.c.selinux-label krb5-1.8/src/plugins/kdb/db2/kdb_db2.c
--- krb5-1.8/src/plugins/kdb/db2/kdb_db2.c.selinux-label	2009-11-25 09:36:05.000000000 -0500
+++ krb5-1.8/src/plugins/kdb/db2/kdb_db2.c	2010-03-05 10:57:23.000000000 -0500
@@ -326,8 +326,8 @@ krb5_db2_db_init(krb5_context context)
      * should be opened read/write so that write locking can work with
      * POSIX systems
      */
-    if ((db_ctx->db_lf_file = open(filename, O_RDWR, 0666)) < 0) {
-        if ((db_ctx->db_lf_file = open(filename, O_RDONLY, 0666)) < 0) {
+    if ((db_ctx->db_lf_file = THREEPARAMOPEN(filename, O_RDWR, 0666)) < 0) {
+        if ((db_ctx->db_lf_file = THREEPARAMOPEN(filename, O_RDONLY, 0666)) < 0) {
             retval = errno;
             goto err_out;
         }
@@ -745,7 +745,7 @@ krb5_db2_db_create(krb5_context context,
     if (!okname)
         retval = ENOMEM;
     else {
-        fd = open(okname, O_CREAT | O_RDWR | O_TRUNC, 0600);
+        fd = THREEPARAMOPEN(okname, O_CREAT | O_RDWR | O_TRUNC, 0600);
         if (fd < 0)
             retval = errno;
         else
@@ -1925,7 +1925,7 @@ krb5_db2_db_rename(context, from, to, me
         retval = ENOMEM;
         goto errout;
     }
-    db_ctx->db_lf_file = open(db_ctx->db_lf_name, O_RDWR|O_CREAT, 0600);
+    db_ctx->db_lf_file = THREEPARAMOPEN(db_ctx->db_lf_name, O_RDWR|O_CREAT, 0600);
     if (db_ctx->db_lf_file < 0) {
         retval = errno;
         goto errout;
diff -up krb5-1.8/src/plugins/kdb/db2/libdb2/btree/bt_open.c.selinux-label krb5-1.8/src/plugins/kdb/db2/libdb2/btree/bt_open.c
--- krb5-1.8/src/plugins/kdb/db2/libdb2/btree/bt_open.c.selinux-label	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/plugins/kdb/db2/libdb2/btree/bt_open.c	2010-03-05 10:57:23.000000000 -0500
@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c	8.
 
 #include "k5-platform.h"	/* mkstemp? */
 
+#include "k5-int.h"
 #include "db-int.h"
 #include "btree.h"
 
@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, 
 			goto einval;
 		}
 
-		if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
+		if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
 			goto err;
 
 	} else {
diff -up krb5-1.8/src/plugins/kdb/db2/libdb2/hash/hash.c.selinux-label krb5-1.8/src/plugins/kdb/db2/libdb2/hash/hash.c
--- krb5-1.8/src/plugins/kdb/db2/libdb2/hash/hash.c.selinux-label	2009-10-30 20:48:38.000000000 -0400
+++ krb5-1.8/src/plugins/kdb/db2/libdb2/hash/hash.c	2010-03-05 10:57:23.000000000 -0500
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c	8.12 
 #include <assert.h>
 #endif
 
+#include "k5-int.h"
 #include "db-int.h"
 #include "hash.h"
 #include "page.h"
@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info
 		new_table = 1;
 	}
 	if (file) {
-		if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1)
+		if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1)
 			RETURN_ERROR(errno, error0);
 		(void)fcntl(hashp->fp, F_SETFD, 1);
 	}
diff -up krb5-1.8/src/plugins/kdb/db2/libdb2/recno/rec_open.c.selinux-label krb5-1.8/src/plugins/kdb/db2/libdb2/recno/rec_open.c
--- krb5-1.8/src/plugins/kdb/db2/libdb2/recno/rec_open.c.selinux-label	2007-10-22 15:18:53.000000000 -0400
+++ krb5-1.8/src/plugins/kdb/db2/libdb2/recno/rec_open.c	2010-03-05 10:57:23.000000000 -0500
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c	8
 #include <stdio.h>
 #include <unistd.h>
 
+#include "k5-int.h"
 #include "db-int.h"
 #include "recno.h"
 
@@ -68,7 +69,7 @@ __rec_open(fname, flags, mode, openinfo,
 	int rfd, sverrno;
 
 	/* Open the user's file -- if this fails, we're done. */
-	if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0)
+	if (fname != NULL && (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
 		return (NULL);
 
 	if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
diff -up krb5-1.8/src/plugins/kdb/db2/libdb2/test/Makefile.in.selinux-label krb5-1.8/src/plugins/kdb/db2/libdb2/test/Makefile.in
--- krb5-1.8/src/plugins/kdb/db2/libdb2/test/Makefile.in.selinux-label	2009-11-22 13:13:29.000000000 -0500
+++ krb5-1.8/src/plugins/kdb/db2/libdb2/test/Makefile.in	2010-03-05 10:57:23.000000000 -0500
@@ -12,7 +12,8 @@ PROG_RPATH=$(KRB5_LIBDIR)
 
 KRB5_RUN_ENV= @KRB5_RUN_ENV@
 
-DB_LIB		= -ldb
+DB_LIB		= -ldb $(SUPPORT_DEPLIB)
+
 DB_DEPLIB	= ../libdb$(DEPLIBEXT)
 
 all::
diff -up krb5-1.8/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c.selinux-label krb5-1.8/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
--- krb5-1.8/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c.selinux-label	2009-11-24 18:52:25.000000000 -0500
+++ krb5-1.8/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c	2010-03-05 10:57:23.000000000 -0500
@@ -1091,7 +1091,7 @@
 
     /* Create a temporary file which contains all the entries except the
        entry for the given service dn */
-    pfile = fopen(file_name, "r+");
+    pfile = WRITABLEFOPEN(file_name, "r+");
     if (pfile == NULL) {
         com_err(me, errno, "while deleting entry from file %s", file_name);
         goto cleanup;
@@ -1108,7 +1108,7 @@
     snprintf (tmp_file, strlen(file_name) + 4 + 1, "%s%s", file_name, ".tmp");
 
 
-    tmpfd = creat(tmp_file, S_IRUSR|S_IWUSR);
+    tmpfd = THREEPARAMOPEN(tmp_file, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
     umask(omask);
     if (tmpfd == -1) {
         com_err(me, errno, "while deleting entry from file\n");
@@ -1728,7 +1728,7 @@
 
             printf("File does not exist. Creating the file %s...\n", file_name);
             omask = umask(077);
-            fd = creat(file_name, S_IRUSR|S_IWUSR);
+            fd = THREEPARAMOPEN(file_name, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
             umask(omask);
             if (fd == -1) {
                 com_err(me, errno, "Error creating file %s", file_name);
@@ -1756,7 +1756,7 @@
 
     /* TODO: file lock for the service password file */
     /* set password in the file */
-    pfile = fopen(file_name, "r+");
+    pfile = WRITABLEFOPEN(file_name, "r+");
     if (pfile == NULL) {
         com_err(me, errno, "Failed to open file %s", file_name);
         goto cleanup;
@@ -1797,7 +1797,7 @@
         }
 
         omask = umask(077);
-        newfile = fopen(tmp_file, "w+");
+        newfile = WRITABLEFOPEN(tmp_file, "w+");
         umask(omask);
         if (newfile == NULL) {
             com_err(me, errno, "Error creating file %s", tmp_file);
@@ -2019,7 +2019,7 @@
 
     /* set password in the file */
     old_mode = umask(0177);
-    pfile = fopen(file_name, "a+");
+    pfile = WRITABLEFOPEN(file_name, "a+");
     if (pfile == NULL) {
         com_err(me, errno, "Failed to open file %s: %s", file_name,
                 strerror (errno));
@@ -2069,7 +2069,7 @@
         }
 
         omask = umask(077);
-        newfile = fopen(tmp_file, "w");
+        newfile = WRITABLEFOPEN(tmp_file, "w");
         umask (omask);
         if (newfile == NULL) {
             com_err(me, errno, "Error creating file %s", tmp_file);
diff -up krb5-1.8/src/slave/kpropd.c.selinux-label krb5-1.8/src/slave/kpropd.c
--- krb5-1.8/src/slave/kpropd.c.selinux-label	2009-12-31 17:25:11.000000000 -0500
+++ krb5-1.8/src/slave/kpropd.c	2010-03-05 10:57:23.000000000 -0500
@@ -328,7 +328,7 @@ retry:
     if (!debug && iproprole != IPROP_SLAVE)
         daemon(1, 0);
 #ifdef PID_FILE
-    if ((pidfile = fopen(PID_FILE, "w")) != NULL) {
+    if ((pidfile = WRITABLEFOPEN(PID_FILE, "w")) != NULL) {
         fprintf(pidfile, "%d\n", getpid());
         fclose(pidfile);
     } else
diff -up krb5-1.8/src/util/profile/prof_file.c.selinux-label krb5-1.8/src/util/profile/prof_file.c
--- krb5-1.8/src/util/profile/prof_file.c.selinux-label	2009-12-27 19:21:20.000000000 -0500
+++ krb5-1.8/src/util/profile/prof_file.c	2010-03-05 10:57:23.000000000 -0500
@@ -30,6 +30,7 @@
 #endif
 
 #include "k5-platform.h"
+#include "k5-label.h"
 
 struct global_shared_profile_data {
     /* This is the head of the global list of shared trees */
@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_
 
     errno = 0;
 
-    f = fopen(new_file, "w");
+    f = WRITABLEFOPEN(new_file, "w");
     if (!f) {
         retval = errno;
         if (retval == 0)
diff -up krb5-1.8/src/util/support/Makefile.in.selinux-label krb5-1.8/src/util/support/Makefile.in
--- krb5-1.8/src/util/support/Makefile.in.selinux-label	2009-11-23 20:25:10.000000000 -0500
+++ krb5-1.8/src/util/support/Makefile.in	2010-03-05 10:57:23.000000000 -0500
@@ -54,6 +54,7 @@ IPC_SYMS= \
 
 STLIBOBJS= \
 	threads.o \
+	selinux.o \
 	init-addrinfo.o \
 	plugins.o \
 	errors.o \
@@ -108,7 +109,7 @@ SRCS=\
 
 SHLIB_EXPDEPS =
 # Add -lm if dumping thread stats, for sqrt.
-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
 SHLIB_DIRS=
 SHLIB_RDIRS=$(KRB5_LIBDIR)
 
diff -up krb5-1.8/src/util/support/selinux.c.selinux-label krb5-1.8/src/util/support/selinux.c
--- krb5-1.8/src/util/support/selinux.c.selinux-label	2010-03-05 10:57:23.000000000 -0500
+++ krb5-1.8/src/util/support/selinux.c	2010-03-05 10:57:23.000000000 -0500
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2007,2008,2009 Red Hat, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice, this
+ *  list of conditions and the following disclaimer.
+ *
+ *  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.
+ *
+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ * 
+ * File-opening wrappers for creating correctly-labeled files.  So far, we can
+ * assume that this is Linux-specific, so we make many simplifying assumptions.
+ */
+
+#include "../../include/autoconf.h"
+
+#ifdef USE_SELINUX
+
+#include <k5-label.h>
+#include <k5-thread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#ifdef HAVE_SELINUX_LABEL_H
+#include <selinux/label.h>
+#endif
+
+/* #define DEBUG 1 */
+
+/* Mutex used to serialize use of the process-global file creation context. */
+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
+
+/* Make sure we finish initializing that mutex before attempting to use it. */
+k5_once_t labeled_once = K5_ONCE_INIT;
+static void
+label_mutex_init(void)
+{
+	k5_mutex_finish_init(&labeled_mutex);
+}
+
+static security_context_t
+push_fscreatecon(const char *pathname, mode_t mode)
+{
+	security_context_t previous, configuredsc, currentsc, derivedsc;
+	context_t current, derived;
+	const char *fullpath, *currentuser;
+#ifdef HAVE_SELINUX_LABEL_H
+	struct selabel_handle *ctx;
+#endif
+
+	previous = NULL;
+	if (is_selinux_enabled()) {
+		if (getfscreatecon(&previous) == 0) {
+			char *genpath;
+			genpath = NULL;
+			if (pathname[0] != '/') {
+				char *wd;
+				size_t len;
+				len = 0;
+				wd = getcwd(NULL, len);
+				if (wd == NULL) {
+					if (previous != NULL) {
+						freecon(previous);
+					}
+					return NULL;
+				}
+				len = strlen(wd) + 1 + strlen(pathname) + 1;
+				genpath = malloc(len);
+				if (genpath == NULL) {
+					free(wd);
+					if (previous != NULL) {
+						freecon(previous);
+					}
+					return NULL;
+				}
+				sprintf(genpath, "%s/%s", wd, pathname);
+				free(wd);
+				fullpath = genpath;
+			} else {
+				fullpath = pathname;
+			}
+#ifdef DEBUG
+			if (isatty(fileno(stderr))) {
+				fprintf(stderr, "Looking up context for "
+					"\"%s\"(%05o).\n", fullpath, mode);
+			}
+#endif
+			configuredsc = NULL;
+#ifdef HAVE_SELINUX_LABEL_H
+			ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+			if (ctx != NULL) {
+				if (selabel_lookup(ctx, &configuredsc,
+						   fullpath, mode) != 0) {
+					selabel_close(ctx);
+					free(genpath);
+					if (previous != NULL) {
+						freecon(previous);
+					}
+					return NULL;
+				}
+				selabel_close(ctx);
+			}
+#else
+			if (matchpathcon(fullpath, mode, &configuredsc) != 0) {
+				free(genpath);
+				if (previous != NULL) {
+					freecon(previous);
+				}
+				return NULL;
+			}
+#endif
+			free(genpath);
+			if (configuredsc == NULL) {
+				if (previous != NULL) {
+					freecon(previous);
+				}
+				return NULL;
+			}
+			currentsc = NULL;
+			getcon(&currentsc);
+			if (currentsc != NULL) {
+				derived = context_new(configuredsc);
+				if (derived != NULL) {
+					current = context_new(currentsc);
+					if (current != NULL) {
+						currentuser = context_user_get(current);
+						if (currentuser != NULL) {
+							if (context_user_set(derived,
+									     currentuser) == 0) {
+								derivedsc = context_str(derived);
+								if (derivedsc != NULL) {
+									freecon(configuredsc);
+									configuredsc = strdup(derivedsc);
+								}
+							}
+						}
+						context_free(current);
+					}
+					context_free(derived);
+				}
+				freecon(currentsc);
+			}
+#ifdef DEBUG
+			if (isatty(fileno(stderr))) {
+				fprintf(stderr, "Setting file creation context "
+					"to \"%s\".\n", configured);
+			}
+#endif
+			if (setfscreatecon(configuredsc) != 0) {
+				freecon(configuredsc);
+				if (previous != NULL) {
+					freecon(previous);
+				}
+				return NULL;
+			}
+			freecon(configuredsc);
+#ifdef DEBUG
+		} else {
+			if (isatty(fileno(stderr))) {
+				fprintf(stderr, "Unable to determine "
+					"current context.\n");
+			}
+#endif
+		}
+	}
+	return previous;
+}
+
+static void
+pop_fscreatecon(security_context_t previous)
+{
+	if (is_selinux_enabled()) {
+#ifdef DEBUG
+		if (isatty(fileno(stderr))) {
+			if (previous != NULL) {
+				fprintf(stderr, "Resetting file creation "
+					"context to \"%s\".\n", previous);
+			} else {
+				fprintf(stderr, "Resetting file creation "
+					"context to default.\n");
+			}
+		}
+#endif
+		setfscreatecon(previous);
+		if (previous != NULL) {
+			freecon(previous);
+		}
+	}
+}
+
+FILE *
+krb5int_labeled_fopen(const char *path, const char *mode)
+{
+	FILE *fp;
+	int errno_save;
+	security_context_t ctx;
+
+	if (strcmp(mode, "r") == 0) {
+		return fopen(path, mode);
+	}
+
+	k5_once(&labeled_once, label_mutex_init);
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
+		ctx = push_fscreatecon(path, 0);
+		fp = fopen(path, mode);
+		errno_save = errno;
+		pop_fscreatecon(ctx);
+		k5_mutex_unlock(&labeled_mutex);
+		errno = errno_save;
+	} else {
+		fp = fopen(path, mode);
+	}
+
+	return fp;
+}
+
+int
+krb5int_labeled_creat(const char *path, mode_t mode)
+{
+	int fd;
+	int errno_save;
+	security_context_t ctx;
+
+	k5_once(&labeled_once, label_mutex_init);
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
+		ctx = push_fscreatecon(path, 0);
+		fd = creat(path, mode);
+		errno_save = errno;
+		pop_fscreatecon(ctx);
+		k5_mutex_unlock(&labeled_mutex);
+		errno = errno_save;
+	} else {
+		fd = creat(path, mode);
+	}
+	return fd;
+}
+
+int
+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev)
+{
+	int ret;
+	int errno_save;
+	security_context_t ctx;
+
+	k5_once(&labeled_once, label_mutex_init);
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
+		ctx = push_fscreatecon(path, mode);
+		ret = mknod(path, mode, dev);
+		errno_save = errno;
+		pop_fscreatecon(ctx);
+		k5_mutex_unlock(&labeled_mutex);
+		errno = errno_save;
+	} else {
+		ret = mknod(path, mode, dev);
+	}
+	return ret;
+}
+
+int
+krb5int_labeled_mkdir(const char *path, mode_t mode)
+{
+	int ret;
+	int errno_save;
+	security_context_t ctx;
+
+	k5_once(&labeled_once, label_mutex_init);
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
+		ctx = push_fscreatecon(path, S_IFDIR);
+		ret = mkdir(path, mode);
+		errno_save = errno;
+		pop_fscreatecon(ctx);
+		k5_mutex_unlock(&labeled_mutex);
+		errno = errno_save;
+	} else {
+		ret = mkdir(path, mode);
+	}
+	return ret;
+}
+
+int
+krb5int_labeled_open(const char *path, int flags, ...)
+{
+	int fd;
+	int errno_save;
+	security_context_t ctx;
+	mode_t mode;
+	va_list ap;
+
+	if ((flags & O_CREAT) == 0) {
+		return open(path, flags);
+	}
+
+	k5_once(&labeled_once, label_mutex_init);
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
+		ctx = push_fscreatecon(path, 0);
+
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		fd = open(path, flags, mode);
+		va_end(ap);
+
+		errno_save = errno;
+		pop_fscreatecon(ctx);
+		k5_mutex_unlock(&labeled_mutex);
+		errno = errno_save;
+	} else {
+		va_start(ap, flags);
+		mode = va_arg(ap, mode_t);
+		fd = open(path, flags, mode);
+		errno_save = errno;
+		va_end(ap);
+		errno = errno_save;
+	}
+	return fd;
+}
+
+#endif

krb5-appl-1.0-io.patch:
 defines.h |    1 +
 kcmd.c    |    8 +++++++-
 krsh.c    |   54 ++++++++++++++++++++++++++++++++++++++----------------
 krshd.c   |   54 +++++++++++++++++++++++++++++++++++++++---------------
 4 files changed, 85 insertions(+), 32 deletions(-)

--- NEW FILE krb5-appl-1.0-io.patch ---
We can get stuck if a write is going to block because both ends are writing and
neither end is reading.  This is a port of a patch which aims to solve that
problem, but for now it's incomplete because we don't handle partial writes.  A
proper non-blocking implementation would require a bit more work.

diff -up krb5-appl-1.0/bsd/defines.h.io krb5-appl-1.0/bsd/defines.h
--- krb5-appl-1.0/bsd/defines.h.io	2009-11-16 05:27:04.000000000 -0500
+++ krb5-appl-1.0/bsd/defines.h	2010-03-05 11:00:06.000000000 -0500
@@ -36,6 +36,7 @@ extern int kcmd (int *sock, char **ahost
 		 enum kcmd_proto *protonum /* input and output */
 		 );
 
+extern int rcmd_stream_has_unsent_data (void);
 extern int rcmd_stream_read (int fd, char *buf, size_t len, int secondary);
 extern int rcmd_stream_write (int fd, char *buf, size_t len, int secondary);
 extern int getport (int * /* portnum */, int * /* addrfamily */);
diff -up krb5-appl-1.0/bsd/kcmd.c.io krb5-appl-1.0/bsd/kcmd.c
--- krb5-appl-1.0/bsd/kcmd.c.io	2009-11-16 05:27:04.000000000 -0500
+++ krb5-appl-1.0/bsd/kcmd.c	2010-03-05 11:00:06.000000000 -0500
@@ -767,6 +767,11 @@ void rcmd_stream_init_normal()
     output = twrite;
 }
 
+int rcmd_stream_has_unsent_data (void)
+{
+    return (nstored > 0);
+}
+
 void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
 			   protonum)
      krb5_keyblock *in_keyblock;
@@ -927,7 +932,8 @@ static int v5_des_read(fd, buf, len, sec
 	cc = full_read(fd, &c, 1);
 	/* we should check for non-blocking here, but we'd have
 	   to make it save partial reads as well. */
-	if (cc <= 0) return cc; /* read error */
+	if (cc == 0) return nreturned; /* EOF */
+	if (cc < 0) return cc; /* read error */
 	if (cc == 1) {
 	    if (c == 0 || !do_lencheck) break;
 	}
diff -up krb5-appl-1.0/bsd/krsh.c.io krb5-appl-1.0/bsd/krsh.c
--- krb5-appl-1.0/bsd/krsh.c.io	2010-03-05 11:00:05.000000000 -0500
+++ krb5-appl-1.0/bsd/krsh.c	2010-03-05 11:00:06.000000000 -0500
@@ -117,10 +117,11 @@ main(argc, argv0)
      char **argv0;
 {
     int rem, pid = 0;
-    char *host=0, **ap, buf[RCMD_BUFSIZ], *args, **argv = argv0, *user = 0;
+    char *host=0, **ap, buf[PIPE_BUF], *args, **argv = argv0, *user = 0;
     register int cc;
     struct passwd *pwd;
     fd_set readfrom, ready;
+    fd_set writeto, ready_wr;
     int one = 1;
     struct servent *sp;
     struct servent defaultservent;
@@ -510,9 +511,14 @@ main(argc, argv0)
     FD_ZERO(&readfrom);
     FD_SET(rfd2, &readfrom);
     FD_SET(rem, &readfrom);
+    FD_ZERO(&writeto);
     do {
+	int max_fd;
+	max_fd = (rfd2 > rem) ? rfd2 : rem;
+	max_fd = (max_fd > 2) ? max_fd : 2;
 	ready = readfrom;
-	if (select(((rfd2 > rem) ? rfd2 : rem) + 1, &ready, 0, 0, 0) < 0) {
+	ready_wr = writeto;
+	if (select(max_fd + 1, &ready, &ready_wr, 0, 0) < 0) {
 	    if (errno != EINTR) {
 		perror("select");
 		exit(1);
@@ -520,22 +526,38 @@ main(argc, argv0)
 	    continue;
 	}
 	if (FD_ISSET(rfd2, &ready)) {
-	    errno = 0;
-	    cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
-	    if (cc <= 0) {
-		if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
-		    FD_CLR(rfd2, &readfrom);
-	    } else
-	      (void) write(2, buf, (unsigned) cc);
+            FD_SET(2, &writeto);
+	}
+	if (FD_ISSET(2, &ready_wr)) {
+	    do {
+		errno = 0;
+		cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
+		if (cc <= 0) {
+		    if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) {
+			FD_CLR(rfd2, &readfrom);
+			break;
+		    }
+		} else
+		  (void) write(2, buf, (unsigned) cc);
+	    } while (rcmd_stream_has_unsent_data());
+	    FD_CLR(2, &writeto);
 	}
 	if (FD_ISSET(rem, &ready)) {
-	    errno = 0;
-	    cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
-	    if (cc <= 0) {
-		if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
-		    FD_CLR(rem, &readfrom);
-	    } else
-	      (void) write(1, buf, (unsigned) cc);
+	    FD_SET(1, &writeto);
+	}
+	if (FD_ISSET(1, &ready_wr)) {
+	    do {
+		errno = 0;
+		cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
+		if (cc <= 0) {
+		    if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) {
+			FD_CLR(rem, &readfrom);
+			break;
+		    }
+		} else
+		  (void) write(1, buf, (unsigned) cc);
+	    } while (rcmd_stream_has_unsent_data());
+	    FD_CLR(1, &writeto);
 	}
     } while (FD_ISSET(rem, &readfrom) || FD_ISSET(rfd2, &readfrom));
     if (nflag == 0)
diff -up krb5-appl-1.0/bsd/krshd.c.io krb5-appl-1.0/bsd/krshd.c
--- krb5-appl-1.0/bsd/krshd.c.io	2010-03-05 11:00:05.000000000 -0500
+++ krb5-appl-1.0/bsd/krshd.c	2010-03-05 11:00:06.000000000 -0500
@@ -585,7 +585,8 @@ void doit(f, fromp)
     short port;
     int pv[2], pw[2], px[2], cc;
     fd_set ready, readfrom;
-    char buf[RCMD_BUFSIZ], sig;
+    fd_set ready_wr, writeto;
+    char buf[PIPE_BUF], sig;
     struct sockaddr_storage localaddr;
 #ifdef POSIX_SIGNALS
     struct sigaction sa;
@@ -1216,6 +1217,10 @@ void doit(f, fromp)
 	    if (pw[0] > maxfd)
 		maxfd = pw[0];
 	    
+	    if (px[1] > maxfd)
+		maxfd = px[1];
+	    FD_ZERO(&writeto);
+
 	    /* read from f, write to px[1] -- child stdin */
 	    /* read from s, signal child */
 	    /* read from pv[0], write to s -- child stderr */
@@ -1223,36 +1228,47 @@ void doit(f, fromp)
 
 	    do {
 		ready = readfrom;
-		if (select(maxfd + 1, &ready, (fd_set *)0,
+		ready_wr = writeto;
+		if (select(maxfd + 1, &ready, &ready_wr,
 			   (fd_set *)0, (struct timeval *)0) < 0) {
 		    if (errno == EINTR) {
 			continue;
 		    } else {
 			break;
-		}
+		    }
 		}
 
 		if (port&&FD_ISSET(pv[0], &ready)) {
+		    FD_SET(s, &writeto);
+		    FD_CLR(pv[0], &readfrom);
+		}
+		if (port&&FD_ISSET(s, &ready_wr)) {
 		    /* read from the child stderr, write to the net */
 		    errno = 0;
 		    cc = read(pv[0], buf, sizeof (buf));
-		    if (cc <= 0) {
+		    if ((cc <= 0) ||
+			(rcmd_stream_write(s, buf, (unsigned) cc, 1) != cc)) {
 			shutdown(s, 1+1);
-			FD_CLR(pv[0], &readfrom);
 		    } else {
-			(void) rcmd_stream_write(s, buf, (unsigned) cc, 1);
+			FD_SET(pv[0], &readfrom);
 		    }
+		    FD_CLR(s, &writeto);
 		}
 		if (FD_ISSET(pw[0], &ready)) {
+		    FD_SET(f, &writeto);
+		    FD_CLR(pw[0], &readfrom);
+		}
+		if (FD_ISSET(f, &ready_wr)) {
 		    /* read from the child stdout, write to the net */
 		    errno = 0;
 		    cc = read(pw[0], buf, sizeof (buf));
-		    if (cc <= 0) {
+		    if ((cc <= 0) ||
+			(rcmd_stream_write(f, buf, (unsigned) cc, 0) != cc)) {
 			shutdown(f, 1+1);
-			FD_CLR(pw[0], &readfrom);
 		    } else {
-			(void) rcmd_stream_write(f, buf, (unsigned) cc, 0);
+			FD_SET(pw[0], &readfrom);
 		    }
+		    FD_CLR(f, &writeto);
 		}
 		if (port&&FD_ISSET(s, &ready)) {
 		    /* read from the alternate channel, signal the child */
@@ -1270,12 +1286,15 @@ void doit(f, fromp)
 		    }
 		}
 		if (FD_ISSET(f, &ready)) {
+		    FD_SET(px[1], &writeto);
+		    FD_CLR(f, &readfrom);
+		}
+		if (FD_ISSET(px[1], &ready_wr)) {
 		    /* read from the net, write to child stdin */
 		    errno = 0;
 		    cc = rcmd_stream_read(f, buf, sizeof(buf), 0);
 		    if (cc <= 0) {
 			(void) close(px[1]);
-			FD_CLR(f, &readfrom);
 		    } else {
 		        int wcc;
 		        wcc = write(px[1], buf, (unsigned) cc);
@@ -1283,17 +1302,22 @@ void doit(f, fromp)
 			  /* pipe closed, don't read any more */
 			  /* might check for EPIPE */
 			  (void) close(px[1]);
-			  FD_CLR(f, &readfrom);
-			} else if (wcc != cc) {
-			  syslog(LOG_INFO, "only wrote %d/%d to child", 
-				 wcc, cc);
+			} else {
+			    if (wcc != cc)
+				syslog(LOG_INFO, "only wrote %d/%d to child", 
+				       wcc, cc);
+			    FD_SET(f, &readfrom);
 			}
 		    }
+		    FD_CLR(px[1], &writeto);
 		}
 	    } while ((port&&FD_ISSET(s, &readfrom)) ||
 		     FD_ISSET(f, &readfrom) ||
 		     (port&&FD_ISSET(pv[0], &readfrom) )||
-		     FD_ISSET(pw[0], &readfrom));
+		     FD_ISSET(pw[0], &readfrom) ||
+		     (port&&FD_ISSET(s, &writeto)) ||
+		     FD_ISSET(f, &writeto) ||
+		     FD_ISSET(px[1], &writeto));
 	    ignore_signals();
 #ifdef KERBEROS
 	    syslog(LOG_INFO ,

krb5-appl-1.0-largefile.patch:
 bsd/krcp.c             |    5 +++++
 configure.ac           |    4 ++++
 gssftp/ftp/ftp.c       |   24 +++++++++++++++++++++---
 gssftp/ftp/ftp_var.h   |    6 ++++++
 gssftp/ftpd/ftpcmd.y   |   12 ++++++++++++
 gssftp/ftpd/ftpd.c     |   27 ++++++++++++++++++++++++++-
 gssftp/ftpd/ftpd_var.h |    6 ++++++
 7 files changed, 80 insertions(+), 4 deletions(-)

--- NEW FILE krb5-appl-1.0-largefile.patch ---
* Turn on large file support in gssftp and rcp (and the rest of the bsd
  applications) using AC_SYS_LARGEFILE.
* The size of off_t might now be greater than that of an int or a long, so
  if we have a "long long" type, assume that format specifiers for it work
  correctly and that we can cast off_t values to long long for displaying
  and logging.
* Check for fseeko(), which takes an off_t, and if we find it, use it
  instead of fseek(), which takes a long and might not handle the full
  range of values.
RT#6524

diff -up krb5-appl-1.0/bsd/krcp.c.largefile krb5-appl-1.0/bsd/krcp.c
--- krb5-appl-1.0/bsd/krcp.c.largefile	2010-03-05 11:06:23.000000000 -0500
+++ krb5-appl-1.0/bsd/krcp.c	2010-03-05 11:06:24.000000000 -0500
@@ -748,8 +748,13 @@ void source(argc, argv)
 		continue;
 	    }
 	}
+#ifdef HAVE_LONG_LONG_INT
+	(void) snprintf(buf, sizeof(buf), "C%04o %lld %s\n",
+			(int) stb.st_mode&07777, (long long) stb.st_size, last);
+#else
 	(void) snprintf(buf, sizeof(buf), "C%04o %ld %s\n",
 			(int) stb.st_mode&07777, (long ) stb.st_size, last);
+#endif
 	(void) rcmd_stream_write(rem, buf, strlen(buf), 0);
 	if (response() < 0) {
 	    (void) close(f);
diff -up krb5-appl-1.0/configure.ac.largefile krb5-appl-1.0/configure.ac
--- krb5-appl-1.0/configure.ac.largefile	2010-03-05 11:06:23.000000000 -0500
+++ krb5-appl-1.0/configure.ac	2010-03-05 11:06:24.000000000 -0500
@@ -103,6 +103,10 @@ case $host in
     ;;
 esac
 
+AC_SYS_LARGEFILE
+AC_FUNC_FSEEKO
+AC_TYPE_LONG_LONG_INT
+AC_TYPE_UNSIGNED_LONG_LONG_INT
 AC_CHECK_FUNCS(_getpty cgetent getcwd getenv gettosbyname getusershell getutmp)
 AC_CHECK_FUNCS(getutmpx grantpt inet_aton initgroups isatty killpg killpg)
 AC_CHECK_FUNCS(line_push logwtmp openpty ptsname revoke rmufile rresvport_af)
diff -up krb5-appl-1.0/gssftp/ftpd/ftpcmd.y.largefile krb5-appl-1.0/gssftp/ftpd/ftpcmd.y
--- krb5-appl-1.0/gssftp/ftpd/ftpcmd.y.largefile	2009-11-05 15:15:06.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftpd/ftpcmd.y	2010-03-05 11:06:24.000000000 -0500
@@ -1499,12 +1499,20 @@ char *filename;
 		    (stbuf.st_mode&S_IFMT) != S_IFREG)
 			reply(550, "%s: not a plain file.", filename);
 		else
+#ifdef HAVE_LONG_LONG_INT
+			reply(213, "%llu", (long long) stbuf.st_size);
+#else
 			reply(213, "%lu", (long) stbuf.st_size);
+#endif
 		break;}
 	case TYPE_A: {
 		FILE *fin;
 		register int c;
+#ifdef HAVE_LONG_LONG_INT
+		register long long count;
+#else
 		register long count;
+#endif
 		struct stat stbuf;
 		fin = fopen(filename, "r");
 		if (fin == NULL) {
@@ -1526,7 +1534,11 @@ char *filename;
 		}
 		(void) fclose(fin);
 
+#ifdef HAVE_LONG_LONG_INT
+		reply(213, "%lld", count);
+#else
 		reply(213, "%ld", count);
+#endif
 		break;}
 	default:
 		reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
diff -up krb5-appl-1.0/gssftp/ftpd/ftpd.c.largefile krb5-appl-1.0/gssftp/ftpd/ftpd.c
--- krb5-appl-1.0/gssftp/ftpd/ftpd.c.largefile	2010-03-05 11:06:23.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftpd/ftpd.c	2010-03-05 11:06:24.000000000 -0500
@@ -1205,8 +1205,13 @@ retrieve(cmd, name)
 done:
 	(*closefunc)(fin);
 	if (logging > 2 && !cmd) {
+#ifdef HAVE_UNSIGNED_LONG_LONG_INT
+		syslog(LOG_NOTICE, "get: %llu bytes transferred",
+		       (unsigned long long) byte_count);
+#else
 	        syslog(LOG_NOTICE, "get: %lu bytes transferred",
 		       (unsigned long) byte_count);
+#endif
 	}
 }
 
@@ -1252,7 +1257,7 @@ store_file(name, fmode, unique)
 			 * because we are changing from reading to
 			 * writing.
 			 */
-			if (fseek(fout, 0L, L_INCR) < 0) {
+			if (FSEEK(fout, 0L, L_INCR) < 0) {
 				perror_reply(550, name);
 				goto done;
 			}
@@ -1277,8 +1282,13 @@ store_file(name, fmode, unique)
 done:
 	(*closefunc)(fout);
 	if (logging > 2) {
+#ifdef HAVE_UNSIGNED_LONG_LONG_INT
+		syslog(LOG_NOTICE, "put: %llu bytes transferred",
+		       (unsigned long long) byte_count);
+#else
 	        syslog(LOG_NOTICE, "put: %lu bytes transferred",
 		       (unsigned long) byte_count);
+#endif
 	}
 }
 
@@ -1341,8 +1351,13 @@ dataconn(name, size, fmode)
 	byte_count = 0;
 	if (size != (off_t) -1)
 		/* cast size to long in case sizeof(off_t) > sizeof(long) */
+#ifdef HAVE_LONG_LONG_INT
+		(void) snprintf (sizebuf, sizeof(sizebuf), " (%lld bytes)",
+				 (long long)size);
+#else
 		(void) snprintf (sizebuf, sizeof(sizebuf), " (%ld bytes)",
 				 (long)size);
+#endif
 	else
 		sizebuf[0] = '\0';
 	if (pdata >= 0) {
@@ -2063,6 +2078,15 @@ myoob(sig)
 		siglongjmp(urgcatch, 1);
 	}
 	if (strcmp(cp, "STAT") == 0) {
+#ifdef HAVE_LONG_LONG_INT
+		if (file_size != (off_t) -1)
+			reply(213, "Status: %llu of %llu bytes transferred",
+			      (unsigned long long) byte_count, 
+			      (unsigned long long) file_size);
+		else
+			reply(213, "Status: %llu bytes transferred", 
+			      (unsigned long long) byte_count);
+#else
 		if (file_size != (off_t) -1)
 			reply(213, "Status: %lu of %lu bytes transferred",
 			      (unsigned long) byte_count, 
@@ -2070,6 +2094,7 @@ myoob(sig)
 		else
 			reply(213, "Status: %lu bytes transferred", 
 			      (unsigned long) byte_count);
+#endif
 	}
 }
 
diff -up krb5-appl-1.0/gssftp/ftpd/ftpd_var.h.largefile krb5-appl-1.0/gssftp/ftpd/ftpd_var.h
--- krb5-appl-1.0/gssftp/ftpd/ftpd_var.h.largefile	2009-11-05 15:15:06.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftpd/ftpd_var.h	2010-03-05 11:06:24.000000000 -0500
@@ -41,6 +41,12 @@
 char *radix_error (int);
 int radix_encode (unsigned char *, unsigned char *, size_t *, int);
 
+#ifdef HAVE_FSEEKO
+#define FSEEK(fd, offset, whence) fseeko(fd, (off_t) offset, whence)
+#else
+#define FSEEK(fd, offset, whence) fseek(fd, (long) offset, whence)
+#endif
+
 /* ftpd.c */
 void ack(char *);
 int auth_data(unsigned char *);
diff -up krb5-appl-1.0/gssftp/ftp/ftp.c.largefile krb5-appl-1.0/gssftp/ftp/ftp.c
--- krb5-appl-1.0/gssftp/ftp/ftp.c.largefile	2010-03-05 11:06:24.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftp/ftp.c	2010-03-05 11:06:24.000000000 -0500
@@ -156,7 +156,11 @@ void user_gss_error (OM_uint32, OM_uint3
 
 static void proxtrans (char *, char *, char *);
 static int initconn (void);
+#ifdef HAVE_LONG_LONG_INT
+static void ptransfer (char *, long long, struct timeval *, struct timeval *);
+#else
 static void ptransfer (char *, long, struct timeval *, struct timeval *);
+#endif
 static void abort_remote (FILE *);
 static void tvsub (struct timeval *, struct timeval *, struct timeval *);
 static char *gunique (char *);
@@ -787,7 +791,11 @@ void sendrequest(char *cmd, char *local,
 	FILE *volatile fin, *volatile dout = 0;
 	int (*volatile closefunc)();
 	volatile sig_t oldintr, oldintp;
+#ifdef HAVE_LONG_LONG_INT
+	volatile long long bytes = 0, hashbytes = HASHBYTES;
+#else
 	volatile long bytes = 0, hashbytes = HASHBYTES;
+#endif
 	char *volatile lmode;
 	char buf[FTP_BUFSIZ], *bufp;
 
@@ -884,7 +892,7 @@ void sendrequest(char *cmd, char *local,
 
 	if (restart_point &&
 	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
-		if (fseek(fin, (long) restart_point, 0) < 0) {
+		if (FSEEK(fin, restart_point, 0) < 0) {
 			fprintf(stderr, "local: %s: %s\n", local,
 				strerror(errno));
 			restart_point = 0;
@@ -1279,7 +1287,7 @@ void recvrequest(char *cmd, char *volati
 		if (restart_point) {
 			register int i, n, ch;
 
-			if (fseek(fout, 0L, L_SET) < 0)
+			if (FSEEK(fout, 0L, L_SET) < 0)
 				goto done;
 			n = restart_point;
 			for (i = 0; i++ < n;) {
@@ -1288,7 +1296,7 @@ void recvrequest(char *cmd, char *volati
 				if (ch == '\n')
 					i++;
 			}
-			if (fseek(fout, 0L, L_INCR) < 0) {
+			if (FSEEK(fout, 0L, L_INCR) < 0) {
 done:
 				fprintf(stderr, "local: %s: %s\n", local,
 					strerror(errno));
@@ -1553,8 +1561,13 @@ dataconn(char *lmode)
 	return (FDOPEN_SOCKET(data, lmode));
 }
 
+#ifdef HAVE_LONG_LONG_INT
+static void ptransfer(char *direction, long long bytes,
+		      struct timeval *t0, struct timeval *t1)
+#else
 static void ptransfer(char *direction, long bytes,
 		      struct timeval *t0, struct timeval *t1)
+#endif
 {
 	struct timeval td;
 	float s, kbs;
@@ -1564,8 +1577,13 @@ static void ptransfer(char *direction, l
 		s = td.tv_sec + (td.tv_usec / 1000000.);
 #define	nz(x)	((x) == 0 ? 1 : (x))
 		kbs = (bytes / nz(s))/1024.0;
+#ifdef HAVE_LONG_LONG_INT
+		printf("%lld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
+		    bytes, direction, s, kbs);
+#else
 		printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
 		    bytes, direction, s, kbs);
+#endif
 	}
 }
 
diff -up krb5-appl-1.0/gssftp/ftp/ftp_var.h.largefile krb5-appl-1.0/gssftp/ftp/ftp_var.h
--- krb5-appl-1.0/gssftp/ftp/ftp_var.h.largefile	2010-03-05 11:06:24.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftp/ftp_var.h	2010-03-05 11:06:24.000000000 -0500
@@ -46,12 +46,18 @@ FILE* fdopen_socket(SOCKET s, char* mode
 #define FDOPEN_SOCKET(s, mode) fdopen_socket(s, mode)
 #define SOCKETNO(fd) _get_osfhandle(fd)
 #define PERROR_SOCKET(str) do { errno = SOCKET_ERRNO; perror(str); } while(0)
+#define FSEEK(fd, offset, whence) fseek(fd, (long) offset, whence)
 #else
 #define FCLOSE_SOCKET(f) fclose(f)
 FILE* fdopen_socket(int *s, char* mode);
 #define FDOPEN_SOCKET(s, mode) fdopen_socket(&s, mode)
 #define SOCKETNO(fd) (fd)
 #define PERROR_SOCKET(str) perror(str)
+#ifdef HAVE_FSEEKO
+#define FSEEK(fd, offset, whence) fseeko(fd, (off_t) offset, whence)
+#else
+#define FSEEK(fd, offset, whence) fseek(fd, (long) offset, whence)
+#endif
 #endif
 
 #ifdef _WIN32

krb5-appl-1.0-login_chdir.patch:
 login.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

--- NEW FILE krb5-appl-1.0-login_chdir.patch ---
Change to the user's directory after dropping privileges, in case it is only
accessible to the user (for example, if it's in NFS with root squashing).
Incomplete - we probably need to do the same for rshd and ftpd.

diff -up krb5-appl-1.0/bsd/login.c.login_chdir krb5-appl-1.0/bsd/login.c
--- krb5-appl-1.0/bsd/login.c.login_chdir	2010-03-05 11:01:23.000000000 -0500
+++ krb5-appl-1.0/bsd/login.c	2010-03-05 11:01:23.000000000 -0500
@@ -1115,13 +1115,8 @@ int main(argc, argv)
     }
 #endif /* USE_PAM */
 
-    if (chdir(pwd->pw_dir) < 0) {
-	printf("No directory %s!\n", pwd->pw_dir);
-	if (chdir("/"))
-	    exit(0);
-	pwd->pw_dir = "/";
-	printf("Logging in with home = \"/\".\n");
-    }
+    if (chdir("/"))
+	exit(0);
 
     /* nothing else left to fail -- really log in */
     login_time = time(NULL);
@@ -1293,6 +1288,14 @@ int main(argc, argv)
 	sleepexit(1);
     }
 
+    if (chdir(pwd->pw_dir) < 0) {
+	printf("No directory %s!\n", pwd->pw_dir);
+	if (chdir("/"))
+	    exit(0);
+	pwd->pw_dir = "/";
+	printf("Logging in with home = \"/\".\n");
+    }
+
     /*
      * We are the user now.  Re-create the destroyed ccache and
      * ticket file.

krb5-appl-1.0-manpaths.patch:
 aclocal.m4               |   21 +++++++++++++++++++++
 bsd/klogind.M            |    2 +-
 bsd/kshd.M               |    4 ++--
 configure.ac             |    7 +++++++
 gssftp/ftpd/ftpd.M       |    2 +-
 telnet/telnetd/telnetd.8 |    2 +-
 6 files changed, 33 insertions(+), 5 deletions(-)

--- NEW FILE krb5-appl-1.0-manpaths.patch ---
Change the absolute paths included in the man pages so that the correct
values can be dropped in by config.status.  After applying this patch,
these files should be renamed to their ".in" counterparts, and then the
configure scripts should be rebuilt.  Originally RT#6525

diff -up krb5-appl-1.0/aclocal.m4.manpaths krb5-appl-1.0/aclocal.m4
--- krb5-appl-1.0/aclocal.m4.manpaths	2010-03-05 10:55:58.000000000 -0500
+++ krb5-appl-1.0/aclocal.m4	2010-03-05 10:55:58.000000000 -0500
@@ -565,3 +565,24 @@ AC_SUBST(PAM_LIBS)
 AC_SUBST(PAM_MAN)
 AC_SUBST(NON_PAM_MAN)
 ])dnl
+AC_DEFUN(V5_AC_OUTPUT_MANPAGE,[
+mansysconfdir=$sysconfdir
+mansysconfdir=`eval echo $mansysconfdir | sed -e "s,NONE,$prefix,g"`
+mansysconfdir=`eval echo $mansysconfdir | sed -e "s,NONE,$ac_default_prefix,g"`
+mansbindir=$sbindir
+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$exec_prefix,g"`
+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$prefix,g"`
+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$ac_default_prefix,g"`
+manlocalstatedir=$localstatedir
+manlocalstatedir=`eval echo $manlocalstatedir | sed -e "s,NONE,$prefix,g"`
+manlocalstatedir=`eval echo $manlocalstatedir | sed -e "s,NONE,$ac_default_prefix,g"`
+manlibexecdir=$libexecdir
+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$exec_prefix,g"`
+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$prefix,g"`
+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$ac_default_prefix,g"`
+AC_SUBST(mansysconfdir)
+AC_SUBST(mansbindir)
+AC_SUBST(manlocalstatedir)
+AC_SUBST(manlibexecdir)
+AC_CONFIG_FILES($1)
+])
diff -up krb5-appl-1.0/bsd/klogind.M.manpaths krb5-appl-1.0/bsd/klogind.M
--- krb5-appl-1.0/bsd/klogind.M.manpaths	2008-12-15 15:29:01.000000000 -0500
+++ krb5-appl-1.0/bsd/klogind.M	2010-03-05 10:55:58.000000000 -0500
@@ -27,7 +27,7 @@ server is invoked by \fIinetd(8)\fP when
 the port indicated in /etc/inetd.conf.  A typical /etc/inetd.conf
 configuration line for \fIklogind\fP might be:
 
-klogin stream tcp nowait root /usr/cygnus/sbin/klogind klogind -e5c
+klogin stream tcp nowait root @mansbindir@/klogind klogind -e5c
 
 When a service request is received, the following protocol is initiated:
 
diff -up krb5-appl-1.0/bsd/kshd.M.manpaths krb5-appl-1.0/bsd/kshd.M
--- krb5-appl-1.0/bsd/kshd.M.manpaths	2006-06-12 14:19:26.000000000 -0400
+++ krb5-appl-1.0/bsd/kshd.M	2010-03-05 10:55:58.000000000 -0500
@@ -8,7 +8,7 @@
 .SH NAME
 kshd \- kerberized remote shell server
 .SH SYNOPSIS
-.B /usr/local/sbin/kshd 
+.B @mansbindir@/kshd 
 [
 .B \-kr45ec
 ]
@@ -30,7 +30,7 @@ server is invoked by \fIinetd(8c)\fP whe
 on the port indicated in /etc/inetd.conf.  A typical /etc/inetd.conf
 configuration line for \fIkrshd\fP might be:
 
-kshell	stream	tcp	nowait	root	/usr/local/sbin/kshd	kshd -5c
+kshell	stream	tcp	nowait	root	@mansbindir@/kshd	kshd -5c
 
 When a service request is received, the following protocol is initiated:
 
diff -up krb5-appl-1.0/configure.ac.manpaths krb5-appl-1.0/configure.ac
--- krb5-appl-1.0/configure.ac.manpaths	2010-03-05 10:55:58.000000000 -0500
+++ krb5-appl-1.0/configure.ac	2010-03-05 10:55:58.000000000 -0500
@@ -412,6 +412,13 @@ else
 fi
 AC_SUBST(HAVE_RUNTEST)
 
+V5_AC_OUTPUT_MANPAGE([
+	gssftp/ftpd/ftpd.M
+	bsd/klogind.M
+	bsd/kshd.M
+	telnet/telnetd/telnetd.8
+])
+
 V5_AC_OUTPUT_MAKEFILE(. bsd libmissing libpty
                       gssftp gssftp/ftp gssftp/ftpd
                       telnet telnet/libtelnet telnet/telnet telnet/telnetd
diff -up krb5-appl-1.0/gssftp/ftpd/ftpd.M.manpaths krb5-appl-1.0/gssftp/ftpd/ftpd.M
--- krb5-appl-1.0/gssftp/ftpd/ftpd.M.manpaths	2009-01-28 00:42:11.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftpd/ftpd.M	2010-03-05 10:55:58.000000000 -0500
@@ -35,7 +35,7 @@
 .SH NAME
 ftpd \- DARPA Internet File Transfer Protocol server
 .SH SYNOPSIS
-.B ftpd
+.B @mansbindir@/ftpd
 [\fB\-A \fP|\fB -a\fP] [\fB\-C\fP] [\fB\-c\fP] [\fB\-d\fP] [\fB-E\fP]
 [\fB\-l\fP] [\fB\-v\fP] [\fB\-T\fP \fImaxtimeout\fP] [\fB\-t\fP \fItimeout\fP]
 [\fB\-p\fP \fIport\fP] [\fB\-U\fP \fIftpusers-file\fP] [\fB\-u\fP \fIumask\fP]
diff -up krb5-appl-1.0/telnet/telnetd/telnetd.8.manpaths krb5-appl-1.0/telnet/telnetd/telnetd.8
--- krb5-appl-1.0/telnet/telnetd/telnetd.8.manpaths	2004-11-15 16:25:41.000000000 -0500
+++ krb5-appl-1.0/telnet/telnetd/telnetd.8	2010-03-05 10:55:58.000000000 -0500
@@ -37,7 +37,7 @@ telnetd \-
 .SM DARPA TELNET
 protocol server
 .SH SYNOPSIS
-.B /usr/libexec/telnetd
+.B @mansbindir@/telnetd
 [\fB\-a\fP \fIauthmode\fP] [\fB\-B\fP] [\fB\-D\fP] [\fIdebugmode\fP]
 [\fB\-e\fP] [\fB\-h\fP] [\fB\-I\fP\fIinitid\fP] [\fB\-l\fP]
 [\fB\-k\fP] [\fB\-n\fP] [\fB\-r\fP\fIlowpty-highpty\fP] [\fB\-s\fP]

krb5-appl-1.0-pam.patch:
 aclocal.m4              |   79 ++++++++
 bsd/Makefile.in         |   13 -
 bsd/krshd.c             |   64 ++++++-
 bsd/login.c             |   61 ++++++
 bsd/pam.c               |  438 ++++++++++++++++++++++++++++++++++++++++++++++++
 bsd/pam.h               |   65 +++++++
 configure.ac            |    2 
 gssftp/ftpd/Makefile.in |   11 -
 gssftp/ftpd/ftpd.c      |   72 +++++++
 9 files changed, 785 insertions(+), 20 deletions(-)

--- NEW FILE krb5-appl-1.0-pam.patch ---
Modify krshd so that it performs PAM account and session management.  It
must now always fork so that it can always clean up the session.  The
PAM session is opened and credentials initialized after any forwarded
credentials are stored to disk and before access to the user's home
directory is attempted.  The default service name is "kshell" or
"ekshell", depending on whether or not encryption is in use, to avoid a
dependency or conflict on the plain rsh server's configuration file.  At
run-time, krshd's behavior can be reset to the earlier, non-PAM behavior
by setting "use_pam" to false in the [rshd] section of /etc/krb5.conf.

Modify ftpd so that authentication with a plaintext password goes
through PAM, and it performs PAM account and session management.  The
PAM session is opened and credentials initialized after any forwarded
credentials are stored to disk.  The default service name is "gssftp",
mainly to avoid conflicts with other FTP servers' configuration files.
At run-time, krshd's behavior can be reset to the earlier, non-PAM
behavior by setting "use_pam" to false in the [ftpd] section of
/etc/krb5.conf.

Modify login so that instead of directly obtaining v5 credentials
or running aklog, it calls PAM for authentication if strong
authentication hasn't already been performed, so that it performs
account management using PAM (prompting for a password change if need
be), and that it performs session management.  The PAM session is opened
and credentials initialized after any forwarded credentials are stored
to disk.  The default service name is "login", because its configuration
is pretty much always going to be there.  At run-time, login's behavior
can be reset to the earlier, non-PAM behavior by setting "use_pam" to
false in the [login] section of /etc/krb5.conf.

When enabled, ftpd, krshd, and login.krb5 gain dependence on libpam.
Originally filed as RT#5939.

diff -up krb5-appl-1.0/aclocal.m4.pam krb5-appl-1.0/aclocal.m4
--- krb5-appl-1.0/aclocal.m4.pam	2009-11-21 15:29:19.000000000 -0500
+++ krb5-appl-1.0/aclocal.m4	2010-03-05 10:48:50.000000000 -0500
@@ -486,3 +486,82 @@ AC_DEFUN([KRB5_AC_LIBUTIL],
   UTIL_LIB=-lutil])dnl
 AC_SUBST(UTIL_LIB)
 ])dnl
+dnl
+dnl Use PAM instead of local crypt() compare for checking local passwords,
+dnl and perform PAM account, session management, and password-changing where
+dnl appropriate.
+dnl 
+AC_DEFUN(KRB5_WITH_PAM,[
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
+	    withpam="$withval",withpam=auto)
+AC_ARG_WITH(pam-login-service,[AC_HELP_STRING(--with-login-service,[PAM service name for login ["login"]])],
+	    withloginpamservice="$withval",withloginpamservice=login)
+AC_ARG_WITH(pam-kshell-service,[AC_HELP_STRING(--with-kshell-service,[PAM service name for unencrypted rsh ["kshell"]])],
+	    withkshellpamservice="$withval",withkshellpamservice=kshell)
+AC_ARG_WITH(pam-ekshell-service,[AC_HELP_STRING(--with-ekshell-service,[PAM service name for encrypted rsh ["ekshell"]])],
+	    withekshellpamservice="$withval",withekshellpamservice=ekshell)
+AC_ARG_WITH(pam-ftp-service,[AC_HELP_STRING(--with-ftp-service,[PAM service name for ftpd ["gssftp"]])],
+	    withftppamservice="$withval",withftppamservice=gssftp)
+old_LIBS="$LIBS"
+if test "$withpam" != no ; then
+	AC_MSG_RESULT([checking for PAM...])
+	PAM_LIBS=
+
+	AC_CHECK_HEADERS(security/pam_appl.h)
+	if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
+		if test "$withpam" = auto ; then
+			AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
+			withpam=no
+		else
+			AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
+		fi
+	fi
+
+	LIBS=
+	unset ac_cv_func_pam_start
+	AC_CHECK_FUNCS(putenv pam_start)
+	if test "x$ac_cv_func_pam_start" = xno ; then
+		unset ac_cv_func_pam_start
+		AC_CHECK_LIB(dl,dlopen)
+		AC_CHECK_FUNCS(pam_start)
+		if test "x$ac_cv_func_pam_start" = xno ; then
+			AC_CHECK_LIB(pam,pam_start)
+			unset ac_cv_func_pam_start
+			unset ac_cv_func_pam_getenvlist
+			AC_CHECK_FUNCS(pam_start pam_getenvlist)
+			if test "x$ac_cv_func_pam_start" = xyes ; then
+				PAM_LIBS="$LIBS"
+			else
+				if test "$withpam" = auto ; then
+					AC_MSG_RESULT([Unable to locate libpam.])
+					withpam=no
+				else
+					AC_MSG_ERROR([Unable to locate libpam.])
+				fi
+			fi
+		fi
+	fi
+	if test "$withpam" != no ; then
+		AC_MSG_NOTICE([building with PAM support])
+		AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
+		AC_DEFINE_UNQUOTED(LOGIN_PAM_SERVICE,"$withloginpamservice",
+				   [Define to the name of the PAM service name to be used by login.])
+		AC_DEFINE_UNQUOTED(KSHELL_PAM_SERVICE,"$withkshellpamservice",
+				   [Define to the name of the PAM service name to be used by rshd for unencrypted sessions.])
+		AC_DEFINE_UNQUOTED(EKSHELL_PAM_SERVICE,"$withekshellpamservice",
+				   [Define to the name of the PAM service name to be used by rshd for encrypted sessions.])
+		AC_DEFINE_UNQUOTED(FTP_PAM_SERVICE,"$withftppamservice",
+				   [Define to the name of the PAM service name to be used by ftpd.])
+		PAM_LIBS="$LIBS"
+		NON_PAM_MAN=".\\\" "
+		PAM_MAN=
+	else
+		PAM_MAN=".\\\" "
+		NON_PAM_MAN=
+	fi
+fi
+LIBS="$old_LIBS"
+AC_SUBST(PAM_LIBS)
+AC_SUBST(PAM_MAN)
+AC_SUBST(NON_PAM_MAN)
+])dnl
diff -up krb5-appl-1.0/bsd/krshd.c.pam krb5-appl-1.0/bsd/krshd.c
--- krb5-appl-1.0/bsd/krshd.c.pam	2009-11-16 05:27:04.000000000 -0500
+++ krb5-appl-1.0/bsd/krshd.c	2010-03-05 10:48:50.000000000 -0500
@@ -163,6 +163,10 @@ char copyright[] =
 #include <arpa/nameser.h>
 #endif
 
+#ifdef USE_PAM
+#include "pam.h"
+#endif
+
 #ifndef MAXDNAME
 #define MAXDNAME 256 /*per the rfc*/
 #endif
@@ -183,6 +187,7 @@ void fatal(int, const char *);
 
 int require_encrypt = 0;
 int do_encrypt = 0;
+int force_fork = 0;
 int anyport = 0;
 char *kprogdir = KPROGDIR;
 int netf;
@@ -1032,14 +1037,6 @@ void doit(f, fromp)
     }
 #endif /*CRAY*/
     
-    if (chdir(pwd->pw_dir) < 0) {
-      if(chdir("/") < 0) {
-      	error("No remote directory.\n");
-	goto signout_please;
-      }
-	   pwd->pw_dir = "/";
-    }
-
 #ifdef KERBEROS
     /* krb5_kuserok returns 1 if OK */
     if (!krb5_kuserok(bsd_context, client, locuser)){
@@ -1069,11 +1066,51 @@ void doit(f, fromp)
 	goto signout_please;
     }
     
+#ifdef USE_PAM
+    if (appl_pam_enabled(bsd_context, "rshd")) {
+        if (appl_pam_acct_mgmt(do_encrypt ?
+			       EKSHELL_PAM_SERVICE :
+			       KSHELL_PAM_SERVICE,
+			       0,
+			       locuser,
+			       "",
+			       hostname,
+			       NULL,
+			       do_encrypt ?
+			       EKSHELL_PAM_SERVICE :
+			       KSHELL_PAM_SERVICE) != 0) {
+	    error("Login denied.\n");
+	    goto signout_please;
+        }
+        if (appl_pam_requires_chauthtok()) {
+	    error("Password change required, but not possible over rsh.\n");
+	    goto signout_please;
+        }
+        force_fork = 1;
+        appl_pam_set_forwarded_ccname(getenv("KRB5CCNAME"));
+        if (appl_pam_session_open() != 0) {
+	    error("Login failure.\n");
+	    goto signout_please;
+        }
+        if (appl_pam_cred_init()) {
+	    error("Login failure.\n");
+	    goto signout_please;
+        }
+    } else
+#endif
     if (pwd->pw_uid && !access(NOLOGIN, F_OK)) {
 	error("Logins currently disabled.\n");
 	goto signout_please;
     }
     
+    if (chdir(pwd->pw_dir) < 0) {
+	if (chdir("/") < 0) {
+	    error("No remote directory.\n");
+	    goto signout_please;
+	}
+	pwd->pw_dir = "/";
+    }
+
     /* Log access to account */
     pwd = (struct passwd *) getpwnam(locuser);
     if (pwd && (pwd->pw_uid == 0)) {
@@ -1113,7 +1150,7 @@ void doit(f, fromp)
     
     (void) write(2, "", 1);
     
-    if (port||do_encrypt) {
+    if (port||do_encrypt||force_fork) {
 	if (port&&(pipe(pv) < 0)) {
 	    error("Can't make pipe.\n");
 	    goto signout_please;
@@ -1418,6 +1455,15 @@ void doit(f, fromp)
 
     environ = envinit;
     
+#ifdef USE_PAM
+    if (appl_pam_enabled(bsd_context, "rshd")) {
+        if (appl_pam_setenv() != 0) {
+	    error("Login failure.\n");
+	    goto signout_please;
+        }
+    }
+#endif
+
 #ifdef KERBEROS
     /* To make Kerberos rcp work correctly, we must ensure that we
        invoke Kerberos rcp on this end, not normal rcp, even if the
diff -up krb5-appl-1.0/bsd/login.c.pam krb5-appl-1.0/bsd/login.c
--- krb5-appl-1.0/bsd/login.c.pam	2009-11-21 15:29:19.000000000 -0500
+++ krb5-appl-1.0/bsd/login.c	2010-03-05 10:48:50.000000000 -0500
@@ -148,6 +148,11 @@ typedef sigtype (*handler)();
 #define KRB5_ENV_CCNAME "KRB5CCNAME"
 #endif /* KRB5_GET_TICKETS */
 
+#ifdef USE_PAM
+#include "pam.h"
+int login_use_pam = 1;
+#endif
+
 #ifndef __STDC__
 #ifndef volatile
 #define volatile
@@ -293,6 +298,9 @@ static struct login_confs {
     char *flagname;
     int *flag;
 } login_conf_set[] = {
+#ifdef USE_PAM
+    {USE_PAM_CONFIGURATION_KEYWORD, &login_use_pam},
+#endif
 #ifdef KRB5_GET_TICKETS
     {"krb5_get_tickets", &login_krb5_get_tickets},
     {"krb_run_aklog", &login_krb_run_aklog},
@@ -934,6 +942,21 @@ int main(argc, argv)
 	if (!unix_needs_passwd())
 	    break;
 
+#ifdef USE_PAM
+	if (login_use_pam) {
+	    if (appl_pam_authenticate(LOGIN_PAM_SERVICE, 1, username, "",
+				      hostname,
+				      NULL,
+				      ttyname(STDIN_FILENO)) == PAM_SUCCESS) {
+		break;
+	    } else {
+		/* the goto target label is in a different nesting scope, but
+		 * it's roughly where we want to land */
+		goto bad_login;
+	    }
+	}
+#endif
+
 #ifdef KRB5_GET_TICKETS
 	if (login_krb5_get_tickets) {
 	    /* rename these to something more verbose */
@@ -1021,6 +1044,24 @@ int main(argc, argv)
     /* committed to login -- turn off timeout */
     (void) alarm((u_int) 0);
 
+#ifdef USE_PAM
+    if (login_use_pam) {
+	if (appl_pam_acct_mgmt(LOGIN_PAM_SERVICE, 1, username, "",
+			       hostname, NULL, ttyname(STDIN_FILENO)) != 0) {
+	    printf("Login incorrect\n");
+	    sleepexit(1);
+	}
+	if (appl_pam_requires_chauthtok()) {
+	    if (appl_pam_chauthtok() != 0) {
+		printf("Failed to change password.\n");
+		sleepexit(1);
+	    }
+	}
+    } else {
+	/* the "else" here is the non-PAM behavior which continues until the
+	 * next ifdef USE_PAM block, as of this writing more or less
+	 * duplicating the work of pam_securetty and an OQUOTA check */
+#endif
     /*
      * If valid so far and root is logging in, see if root logins on
      * this terminal are permitted.
@@ -1061,6 +1102,21 @@ int main(argc, argv)
 	sleepexit(0);
     }
 #endif
+#ifdef USE_PAM
+    }
+#endif /* USE_PAM */
+
+#ifdef USE_PAM
+    if (login_use_pam) {
+	appl_pam_set_forwarded_ccname(getenv("KRB5CCNAME"));
+	if (appl_pam_session_open() != 0) {
+	    sleepexit(1);
+	}
+	if (appl_pam_cred_init() != 0) {
+	    sleepexit(1);
+	}
+    }
+#endif /* USE_PAM */
 
     if (chdir(pwd->pw_dir) < 0) {
 	printf("No directory %s!\n", pwd->pw_dir);
@@ -1343,6 +1399,11 @@ int main(argc, argv)
     }
 #endif /* KRB5_GET_TICKETS */
 
+#ifdef USE_PAM
+    if (login_use_pam)
+	appl_pam_setenv();
+#endif
+
     if (tty[sizeof("tty")-1] == 'd')
 	syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
     if (pwd->pw_uid == 0)
diff -up krb5-appl-1.0/bsd/Makefile.in.pam krb5-appl-1.0/bsd/Makefile.in
--- krb5-appl-1.0/bsd/Makefile.in.pam	2009-11-05 15:10:37.000000000 -0500
+++ krb5-appl-1.0/bsd/Makefile.in	2010-03-05 10:48:50.000000000 -0500
@@ -3,11 +3,14 @@ BUILDTOP=$(REL)..
 
 LOGINLIBS=@LOGINLIBS@
 KRSHDLIBS=@KRSHDLIBS@
+PAMOBJS=pam.o
+PAM_LIBS=@PAM_LIBS@
 
 SRCS= $(srcdir)/krcp.c $(srcdir)/krlogin.c $(srcdir)/krsh.c $(srcdir)/kcmd.c \
 	$(srcdir)/forward.c $(srcdir)/login.c $(srcdir)/krshd.c \
 	$(srcdir)/krlogind.c
-OBJS= krcp.o krlogin.o krsh.o kcmd.o forward.o login.o krshd.o krlogind.o
+OBJS= krcp.o krlogin.o krsh.o kcmd.o forward.o login.o krshd.o krlogind.o \
+	$(PAMOBJS)
 
 UCB_RLOGIN = @UCB_RLOGIN@
 UCB_RSH = @UCB_RSH@
@@ -50,8 +53,8 @@ install::
 	  ) || exit 1; \
 	done
 
-kshd: krshd.o kcmd.o forward.o $(PTY_DEPLIB) $(MISSING_DEPLIB)
-	$(CC_LINK) -o kshd krshd.o kcmd.o forward.o $(KRSHDLIBS) $(PTY_LIB) $(UTIL_LIB) $(MISSING_LIB) $(KRB5_BASE_LIBS) $(LIBS)
+kshd: krshd.o kcmd.o forward.o $(PAMOBJS) $(PTY_DEPLIB) $(MISSING_DEPLIB)
+	$(CC_LINK) -o kshd krshd.o kcmd.o forward.o $(PAMOBJS) $(KRSHDLIBS) $(PTY_LIB) $(UTIL_LIB) $(MISSING_LIB) $(KRB5_BASE_LIBS) $(PAM_LIBS) $(LIBS)
 
 klogind: krlogind.o kcmd.o forward.o $(PTY_DEPLIB) $(MISSING_DEPLIB)
 	$(CC_LINK) -o klogind krlogind.o kcmd.o forward.o $(PTY_LIB) $(UTIL_LIB) $(MISSING_LIB) $(KRB5_BASE_LIBS) $(LIBS)
@@ -68,8 +71,8 @@ install::
 # No program name transformation is done with login.krb5 since it is directly
 # referenced by klogind.
 #
-login.krb5: login.o $(PTY_DEPLIB) $(MISSING_DEPLIB)
-	$(CC_LINK) -o login.krb5 login.o $(LOGINLIBS) $(PTY_LIB) $(KRB5_BASE_LIBS) $(MISSING_LIB) $(LIBS)
+login.krb5: login.o $(PAMOBJS) $(PTY_DEPLIB) $(MISSING_DEPLIB)
+	$(CC_LINK) -o login.krb5 login.o $(PAMOBJS) $(LOGINLIBS) $(PTY_LIB) $(KRB5_BASE_LIBS) $(MISSING_LIB) $(PAM_LIBS) $(LIBS)
 
 install::
 	$(INSTALL_PROGRAM) login.krb5 $(DESTDIR)$(SERVER_BINDIR)/login.krb5
diff -up krb5-appl-1.0/bsd/pam.c.pam krb5-appl-1.0/bsd/pam.c
--- krb5-appl-1.0/bsd/pam.c.pam	2010-03-05 10:48:50.000000000 -0500
+++ krb5-appl-1.0/bsd/pam.c	2010-03-05 10:48:50.000000000 -0500
@@ -0,0 +1,438 @@
+/*
+ * src/appl/bsd/pam.c
+ *
+ * Copyright 2007,2009,2010 Red Hat, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice, this
+ *  list of conditions and the following disclaimer.
+ *
+ *  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.
+ *
+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ * 
+ * Convenience wrappers for using PAM.
+ */
+
+#include "autoconf.h"
+#ifdef USE_PAM
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <profile.h>
+#include "pam.h"
+
+#ifndef MAXPWSIZE
+#define MAXPWSIZE 128
+#endif
+
+#ifndef KRB5_ENV_CCNAME
+#define KRB5_ENV_CCNAME "KRB5CCNAME"
+#endif
+
+static int appl_pam_started;
+static pid_t appl_pam_starter = -1;
+static int appl_pam_session_opened;
+static int appl_pam_creds_initialized;
+static int appl_pam_pwchange_required;
+static pam_handle_t *appl_pamh;
+static struct pam_conv appl_pam_conv;
+static char *appl_pam_user;
+struct appl_pam_non_interactive_args {
+	const char *user;
+	const char *password;
+};
+
+int
+appl_pam_enabled(krb5_context context, const char *section)
+{
+	int enabled = 1;
+	profile_t profile = NULL;
+	if ((context != NULL) && (krb5_get_profile(context, &profile) == 0)) {
+		if (profile_get_boolean(profile,
+					section,
+					USE_PAM_CONFIGURATION_KEYWORD,
+					NULL,
+					enabled, &enabled) != 0) {
+			enabled = 1;
+		}
+	}
+	return enabled;
+}
+
+void
+appl_pam_cleanup(void)
+{
+	if (getpid() != appl_pam_starter) {
+		return;
+	}
+#ifdef DEBUG
+	printf("Called to clean up PAM.\n");
+#endif
+	if (appl_pam_creds_initialized) {
+#ifdef DEBUG
+		printf("Deleting PAM credentials.\n");
+#endif
+		pam_setcred(appl_pamh, PAM_DELETE_CRED);
+		appl_pam_creds_initialized = 0;
+	}
+	if (appl_pam_session_opened) {
+#ifdef DEBUG
+		printf("Closing PAM session.\n");
+#endif
+		pam_close_session(appl_pamh, 0);
+		appl_pam_session_opened = 0;
+	}
+	appl_pam_pwchange_required = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Shutting down PAM.\n");
+#endif
+		pam_end(appl_pamh, 0);
+		appl_pam_started = 0;
+		appl_pam_starter = -1;
+		free(appl_pam_user);
+		appl_pam_user = NULL;
+	}
+}
+static int
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
+			      struct pam_response **presp, void *appdata_ptr)
+{
+	const struct pam_message *message;
+	struct pam_response *resp;
+	int i, code;
+	char *pwstring, pwbuf[MAXPWSIZE];
+	unsigned int pwsize;
+	resp = malloc(sizeof(struct pam_response) * num_msg);
+	if (resp == NULL) {
+		return PAM_BUF_ERR;
+	}
+	memset(resp, 0, sizeof(struct pam_response) * num_msg);
+	code = PAM_SUCCESS;
+	for (i = 0; i < num_msg; i++) {
+		message = &(msg[0][i]); /* XXX */
+		message = msg[i]; /* XXX */
+		pwstring = NULL;
+		switch (message->msg_style) {
+		case PAM_TEXT_INFO:
+		case PAM_ERROR_MSG:
+			printf("[%s]\n", message->msg ? message->msg : "");
+			fflush(stdout);
+			resp[i].resp = NULL;
+			resp[i].resp_retcode = PAM_SUCCESS;
+			break;
+		case PAM_PROMPT_ECHO_ON:
+		case PAM_PROMPT_ECHO_OFF:
+			if (message->msg_style == PAM_PROMPT_ECHO_ON) {
+				if (fgets(pwbuf, sizeof(pwbuf),
+					  stdin) != NULL) {
+					pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
+					pwstring = pwbuf;
+				}
+			} else {
+				pwstring = getpass(message->msg ?
+						   message->msg :
+						   "");
+			}
+			if ((pwstring != NULL) && (pwstring[0] != '\0')) {
+				pwsize = strlen(pwstring);
+				resp[i].resp = malloc(pwsize + 1);
+				if (resp[i].resp == NULL) {
+					resp[i].resp_retcode = PAM_BUF_ERR;
+				} else {
+					memcpy(resp[i].resp, pwstring, pwsize);
+					resp[i].resp[pwsize] = '\0';
+					resp[i].resp_retcode = PAM_SUCCESS;
+				}
+			} else {
+				resp[i].resp_retcode = PAM_CONV_ERR;
+				code = PAM_CONV_ERR;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	*presp = resp;
+	return code;
+}
+static int
+appl_pam_non_interactive_converse(int num_msg,
+				  const struct pam_message **msg,
+				  struct pam_response **presp,
+				  void *appdata_ptr)
+{
+	const struct pam_message *message;
+	struct pam_response *resp;
+	int i, code;
+	unsigned int pwsize;
+	struct appl_pam_non_interactive_args *args;
+	const char *pwstring;
+	resp = malloc(sizeof(struct pam_response) * num_msg);
+	if (resp == NULL) {
+		return PAM_BUF_ERR;
+	}
+	args = appdata_ptr;
+	memset(resp, 0, sizeof(struct pam_response) * num_msg);
+	code = PAM_SUCCESS;
+	for (i = 0; i < num_msg; i++) {
+		message = &((*msg)[i]);
+		message = msg[i];
+		pwstring = NULL;
+		switch (message->msg_style) {
+		case PAM_TEXT_INFO:
+		case PAM_ERROR_MSG:
+			break;
+		case PAM_PROMPT_ECHO_ON:
+		case PAM_PROMPT_ECHO_OFF:
+			if (message->msg_style == PAM_PROMPT_ECHO_ON) {
+				/* assume "user" */
+				pwstring = args->user;
+			} else {
+				/* assume "password" */
+				pwstring = args->password;
+			}
+			if ((pwstring != NULL) && (pwstring[0] != '\0')) {
+				pwsize = strlen(pwstring);
+				resp[i].resp = malloc(pwsize + 1);
+				if (resp[i].resp == NULL) {
+					resp[i].resp_retcode = PAM_BUF_ERR;
+				} else {
+					memcpy(resp[i].resp, pwstring, pwsize);
+					resp[i].resp[pwsize] = '\0';
+					resp[i].resp_retcode = PAM_SUCCESS;
+				}
+			} else {
+				resp[i].resp_retcode = PAM_CONV_ERR;
+				code = PAM_CONV_ERR;
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	*presp = resp;
+	return code;
+}
+void
+appl_pam_set_forwarded_ccname(const char *ccname)
+{
+	char *ccname2;
+	if (appl_pam_started && (ccname != NULL) && (strlen(ccname) > 0)) {
+		ccname2 = malloc(strlen(KRB5_ENV_CCNAME) + strlen(ccname) + 2);
+		if (ccname2 != NULL) {
+#ifdef DEBUG
+			printf("Setting %s to \"%s\" in PAM environment.\n",
+			       KRB5_ENV_CCNAME, ccname);
+#endif
+			sprintf(ccname2, "%s=%s", KRB5_ENV_CCNAME, ccname);
+			pam_putenv(appl_pamh, ccname2);
+		}
+	}
+}
+static int
+appl_pam_start(const char *service, int interactive,
+	       const char *login_username,
+	       const char *non_interactive_password,
+	       const char *hostname,
+	       const char *ruser,
+	       const char *tty)
+{
+	static int exit_handler_registered;
+	static struct appl_pam_non_interactive_args args;
+	int ret = 0;
+	if (appl_pam_started &&
+	    (strcmp(login_username, appl_pam_user) != 0)) {
+		appl_pam_cleanup();
+		appl_pam_user = NULL;
+	}
+	if (!appl_pam_started) {
+#ifdef DEBUG
+		printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
+		       service, login_username);
+#endif
+		memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
+		appl_pam_conv.conv = interactive ?
+				     &appl_pam_interactive_converse :
+				     &appl_pam_non_interactive_converse;
+		memset(&args, 0, sizeof(args));
+		args.user = strdup(login_username);
+		args.password = non_interactive_password ?
+				strdup(non_interactive_password) :
+				NULL;
+		appl_pam_conv.appdata_ptr = &args;
+		ret = pam_start(service, login_username,
+				&appl_pam_conv, &appl_pamh);
+		if (ret == 0) {
+			if (hostname != NULL) {
+#ifdef DEBUG
+				printf("Setting PAM_RHOST to \"%s\".\n", hostname);
+#endif
+				pam_set_item(appl_pamh, PAM_RHOST, hostname);
+			}
+			if (ruser != NULL) {
+#ifdef DEBUG
+				printf("Setting PAM_RUSER to \"%s\".\n", ruser);
+#endif
+				pam_set_item(appl_pamh, PAM_RUSER, ruser);
+			}
+			if (tty != NULL) {
+#ifdef DEBUG
+				printf("Setting PAM_TTY to \"%s\".\n", tty);
+#endif
+				pam_set_item(appl_pamh, PAM_TTY, tty);
+			}
+			if (!exit_handler_registered &&
+			    (atexit(appl_pam_cleanup) != 0)) {
+				pam_end(appl_pamh, 0);
+				appl_pamh = NULL;
+				ret = -1;
+			} else {
+				appl_pam_started = 1;
+				appl_pam_starter = getpid();
+				appl_pam_user = strdup(login_username);
+				exit_handler_registered = 1;
+			}
+		}
+	}
+	return ret;
+}
+int
+appl_pam_authenticate(const char *service, int interactive,
+		      const char *login_username,
+		      const char *non_interactive_password,
+		      const char *hostname,
+		      const char *ruser,
+		      const char *tty)
+{
+	int ret;
+	ret = appl_pam_start(service, interactive, login_username,
+			     non_interactive_password, hostname, ruser, tty);
+	if (ret == 0) {
+		ret = pam_authenticate(appl_pamh, 0);
+	}
+	return ret;
+}
+int
+appl_pam_acct_mgmt(const char *service, int interactive,
+		   const char *login_username,
+		   const char *non_interactive_password,
+		   const char *hostname,
+		   const char *ruser,
+		   const char *tty)
+{
+	int ret;
+	appl_pam_pwchange_required = 0;
+	ret = appl_pam_start(service, interactive, login_username,
+			     non_interactive_password, hostname, ruser, tty);
+	if (ret == 0) {
+#ifdef DEBUG
+		printf("Calling pam_acct_mgmt().\n");
+#endif
+		ret = pam_acct_mgmt(appl_pamh, 0);
+		switch (ret) {
+		case PAM_IGNORE:
+			ret = 0;
+			break;
+		case PAM_NEW_AUTHTOK_REQD:
+			appl_pam_pwchange_required = 1;
+			ret = 0;
+			break;
+		default:
+			break;
+		}
+	}
+	return ret;
+}
+int
+appl_pam_requires_chauthtok(void)
+{
+	return appl_pam_pwchange_required;
+}
+int
+appl_pam_chauthtok(void)
+{
+	int ret = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Changing PAM expired authentication token.\n");
+#endif
+		ret = pam_chauthtok(appl_pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+	}
+	return ret;
+}
+int
+appl_pam_session_open(void)
+{
+	int ret = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Opening PAM session.\n");
+#endif
+		ret = pam_open_session(appl_pamh, 0);
+		if (ret == 0) {
+			appl_pam_session_opened = 1;
+		}
+	}
+	return ret;
+}
+int
+appl_pam_setenv(void)
+{
+	int ret = 0;
+#ifdef HAVE_PAM_GETENVLIST
+#ifdef HAVE_PUTENV
+	int i;
+	char **list;
+	if (appl_pam_started) {
+		list = pam_getenvlist(appl_pamh);
+		for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
+#ifdef DEBUG
+			printf("Setting \"%s\" in environment.\n", list[i]);
+#endif
+			putenv(list[i]);
+		}
+	}
+#endif
+#endif
+	return ret;
+}
+int
+appl_pam_cred_init(void)
+{
+	int ret = 0;
+	if (appl_pam_started) {
+#ifdef DEBUG
+		printf("Initializing PAM credentials.\n");
+#endif
+		ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
+		if (ret == 0) {
+			appl_pam_creds_initialized = 1;
+		}
+	}
+	return ret;
+}
+#endif
diff -up krb5-appl-1.0/bsd/pam.h.pam krb5-appl-1.0/bsd/pam.h
--- krb5-appl-1.0/bsd/pam.h.pam	2010-03-05 10:48:50.000000000 -0500
+++ krb5-appl-1.0/bsd/pam.h	2010-03-05 10:48:50.000000000 -0500
@@ -0,0 +1,65 @@
+/*
+ * src/appl/bsd/pam.h
+ *
+ * Copyright 2007,2009 Red Hat, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice, this
+ *  list of conditions and the following disclaimer.
+ *
+ *  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.
+ *
+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
+ *  used to endorse or promote products derived from this software without
+ *  specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+ * 
+ * Convenience wrappers for using PAM.
+ */
+
+#include <krb5.h>
+#ifdef HAVE_SECURITY_PAM_APPL_H
+#include <security/pam_appl.h>
+#endif
+
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
+
+#ifdef USE_PAM
+int appl_pam_enabled(krb5_context context, const char *section);
+int appl_pam_authenticate(const char *service, int interactive,
+			  const char *local_username,
+			  const char *non_interactive_password,
+			  const char *hostname,
+			  const char *ruser,
+			  const char *tty);
+int appl_pam_acct_mgmt(const char *service, int interactive,
+		       const char *local_username,
+		       const char *non_interactive_password,
+		       const char *hostname,
+		       const char *ruser,
+		       const char *tty);
+int appl_pam_requires_chauthtok(void);
+int appl_pam_chauthtok(void);
+void appl_pam_set_forwarded_ccname(const char *ccname);
+int appl_pam_session_open(void);
+int appl_pam_setenv(void);
+int appl_pam_cred_init(void);
+void appl_pam_cleanup(void);
+#endif
diff -up krb5-appl-1.0/configure.ac.pam krb5-appl-1.0/configure.ac
--- krb5-appl-1.0/configure.ac.pam	2009-11-21 16:46:39.000000000 -0500
+++ krb5-appl-1.0/configure.ac	2010-03-05 10:48:50.000000000 -0500
@@ -156,6 +156,8 @@ AC_CHECK_FUNC(tgetent, ,
               [AC_MSG_ERROR([Could not find tgetent; are you missing a curses/ncurses library?])])
 LIBS="$old_LIBS"
 
+KRB5_WITH_PAM
+
 # Make our operating system-specific security checks and definitions
 # for libpty, login, and ftpd.  The following code decides what
 # streams modules will be pushed onto a pty.  In particular, if
diff -up krb5-appl-1.0/gssftp/ftpd/ftpd.c.pam krb5-appl-1.0/gssftp/ftpd/ftpd.c
--- krb5-appl-1.0/gssftp/ftpd/ftpd.c.pam	2009-11-18 00:07:46.000000000 -0500
+++ krb5-appl-1.0/gssftp/ftpd/ftpd.c	2010-03-05 10:48:50.000000000 -0500
@@ -69,6 +69,9 @@ static char sccsid[] = "@(#)ftpd.c	5.40 
 #ifdef HAVE_SHADOW
 #include <shadow.h>
 #endif
+#ifdef USE_PAM
+#include "../../bsd/pam.h"
+#endif
 #include <grp.h> 
 #include <setjmp.h>
 #ifndef POSIX_SETJMP
@@ -743,6 +746,22 @@ user(name)
 				name);
 		}
 #endif /* GSSAPI */
+#ifdef USE_PAM
+		if (appl_pam_enabled(kcontext, "ftpd")) {
+			if (appl_pam_acct_mgmt(FTP_PAM_SERVICE, 0,
+					       name, "",
+					       hostname,
+					       NULL,
+					       FTP_PAM_SERVICE) != 0) {
+					       reply(530, "Login incorrect.");
+				return;
+			}
+			if (appl_pam_requires_chauthtok()) {
+				reply(530, "Password change required.");
+				return;
+			}
+		}
+#endif
 
 		if (!authorized && authlevel == AUTHLEVEL_AUTHORIZE) {
 			strncat(buf, "; Access denied.",
@@ -843,6 +862,10 @@ end_login()
 	(void) krb5_seteuid((uid_t)0);
 	if (logged_in)
 		pty_logwtmp(ttyline, "", "");
+#ifdef USE_PAM
+	if (appl_pam_enabled(kcontext, "ftpd"))
+		appl_pam_cleanup();
+#endif
 	if (have_creds) {
 #ifdef GSSAPI
 		krb5_cc_destroy(kcontext, ccache);
@@ -951,9 +974,19 @@ pass(passwd)
 		 *   kpass fails and the user has no local password
 		 *   kpass fails and the provided password doesn't match pw
 		 */
-		if (pw == NULL || (!kpass(pw->pw_name, passwd) &&
-				   (want_creds || !*pw->pw_passwd ||
-				    strcmp(xpasswd, pw->pw_passwd)))) {
+		if ((pw == NULL) || (
+#ifdef USE_PAM
+		    appl_pam_enabled(kcontext, "ftpd") ?
+		    (appl_pam_authenticate(FTP_PAM_SERVICE, 0,
+					   pw->pw_name, passwd,
+					   hostname,
+					   NULL,
+					   FTP_PAM_SERVICE) != 0) :
+#endif
+		    (!kpass(pw->pw_name, passwd) &&
+		     (want_creds ||
+		      !*pw->pw_passwd ||
+		      strcmp(xpasswd, pw->pw_passwd))))) {
 			pw = NULL;
 			sleep(5);
 			if (++login_attempts >= 3) {
@@ -970,6 +1003,23 @@ pass(passwd)
 	}
 	login_attempts = 0;		/* this time successful */
 
+#ifdef USE_PAM
+	if (appl_pam_enabled(kcontext, "ftpd")) {
+		if (appl_pam_acct_mgmt(FTP_PAM_SERVICE, 0,
+				       pw->pw_name, passwd,
+				       hostname,
+				       NULL,
+				       FTP_PAM_SERVICE) != 0) {
+			reply(530, "Login incorrect.");
+			return;
+		}
+		if (appl_pam_requires_chauthtok()) {
+			reply(530, "Password change required.");
+			return;
+		}
+	}
+#endif
+
 	login(passwd, 0);
 	return;
 }
@@ -985,6 +1035,18 @@ login(passwd, logincode)
 		chown(ccname, pw->pw_uid, pw->pw_gid);
 #endif
 	}
+#ifdef USE_PAM
+	if (appl_pam_enabled(kcontext, "ftpd")) {
+		if (appl_pam_session_open() != 0) {
+			reply(550, "Can't open PAM session.");
+			goto bad;
+		}
+		if (appl_pam_cred_init() != 0) {
+			reply(550, "Can't establish PAM credentials.");
+			goto bad;
+		}
+	}
+#endif
 
 	(void) krb5_setegid((gid_t)pw->pw_gid);
 	(void) initgroups(pw->pw_name, pw->pw_gid);
@@ -1966,6 +2028,10 @@ dologout(status)
 		krb5_cc_destroy(kcontext, ccache);
 #endif
 	}
+#ifdef USE_PAM
+	if (appl_pam_enabled(kcontext, "ftpd"))
+		appl_pam_cleanup();
+#endif
 	/* beware of flushing buffers after a SIGPIPE */
 	_exit(status);
 }
diff -up krb5-appl-1.0/gssftp/ftpd/Makefile.in.pam krb5-appl-1.0/gssftp/ftpd/Makefile.in
--- krb5-appl-1.0/gssftp/ftpd/Makefile.in.pam	2009-07-20 13:21:24.000000000 -0400
+++ krb5-appl-1.0/gssftp/ftpd/Makefile.in	2010-03-05 10:48:50.000000000 -0500
@@ -6,22 +6,24 @@ PROG_LIBPATH=-L$(TOPLIBD)
 PROG_RPATH=$(KRB5_LIBDIR)
 
 FTPD_LIBS=@FTPD_LIBS@
+PAM_LIBS=@PAM_LIBS@
 
 SRCS	= $(srcdir)/ftpd.c ftpcmd.c $(srcdir)/popen.c \
 	  $(srcdir)/vers.c \
 	  $(srcdir)/../ftp/glob.c \
 	  $(srcdir)/../ftp/radix.c \
-	  $(srcdir)/../ftp/secure.c
+	  $(srcdir)/../ftp/secure.c \
+	  $(srcdir)/../../bsd/pam.c
 
 OBJS	= ftpd.o ftpcmd.o glob.o popen.o vers.o radix.o \
-	  secure.o
+	  secure.o pam.o
 
 LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir)
 
 all::	ftpd
 
 ftpd:	$(OBJS) $(PTY_DEPLIB) $(MISSING_DEPLIB)
-	$(CC_LINK) -o $@ $(OBJS) $(FTPD_LIBS) $(PTY_LIB) $(UTIL_LIB) $(MISSING_LIB) $(GSS_LIBS) $(LIBS)
+	$(CC_LINK) -o $@ $(OBJS) $(FTPD_LIBS) $(PTY_LIB) $(UTIL_LIB) $(MISSING_LIB) $(GSS_LIBS) $(PAM_LIBS) $(LIBS)
 
 generate-files-mac: ftpcmd.c
 
@@ -61,4 +63,7 @@ ftpcmd.o: ftpcmd.c
 popen.o: $(srcdir)/popen.c
 vers.o: $(srcdir)/vers.c
 
+pam.o: $(srcdir)/../../bsd/pam.c
+	$(CC) -c $(ALL_CFLAGS) $(srcdir)/../../bsd/pam.c
+
 # NOPOSTFIX

krb5-appl-1.0-rlogind-environ.patch:
 krlogind.c |   21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

--- NEW FILE krb5-appl-1.0-rlogind-environ.patch ---
Start with only TERM defined in the environment, like NetKit rlogind does, and
KRB5CCNAME, which we set ourselves.

diff -up krb5-appl-1.0/bsd/krlogind.c.rlogind-environ krb5-appl-1.0/bsd/krlogind.c
--- krb5-appl-1.0/bsd/krlogind.c.rlogind-environ	2009-11-21 15:29:19.000000000 -0500
+++ krb5-appl-1.0/bsd/krlogind.c	2010-03-05 11:07:34.000000000 -0500
@@ -667,6 +667,9 @@ void doit(f, fromp)
 #else
 	struct sgttyb b;
 #endif /* POSIX_TERMIOS */
+	char environ_term[sizeof(term) + 6], environ_ccname[sizeof(environ_term)];
+	char *bare_environ[] = {environ_term, environ_ccname, NULL};
+
 	if ((retval = pty_open_slave(line, &t))) {
 	    fatal(f, pty_error_message(retval));
 	    exit(1);
@@ -773,11 +776,15 @@ void doit(f, fromp)
 /* use the vendors login, which has -p and -f. Tested on 
  * AIX 4.1.4 and HPUX 10 
  */
+    memset(environ_term, '\0', sizeof(environ_term));
+    memset(environ_ccname, '\0', sizeof(environ_ccname));
+    if (getenv("KRB5CCNAME") != NULL)
+      snprintf(environ_ccname, sizeof(environ_ccname) - 1, "KRB5CCNAME=%s", getenv("KRB5CCNAME"));
     {
         char *cp;
-        if ((cp = strchr(term,'/')))
+        snprintf(environ_term, sizeof(environ_term) - 1, "TERM=%s", term);
+        if ((cp = strchr(environ_term,'/')))
             *cp = '\0';
-        setenv("TERM",term, 1);
     }
 
     retval = pty_make_sane_hostname((struct sockaddr *) fromp, maxhostlen,
@@ -786,13 +793,13 @@ void doit(f, fromp)
     if (retval)
         fatalperror(f, "failed make_sane_hostname");
     if (passwd_req)
-        execl(login_program, "login", "-p", "-h", rhost_sane,
-          lusername, (char *)NULL);
+        execle(login_program, "login", "-p", "-h", rhost_sane,
+          lusername, NULL, bare_environ);
     else
-        execl(login_program, "login", "-p", "-h", rhost_sane,
-             "-f", lusername, (char *)NULL);
+        execle(login_program, "login", "-p", "-h", rhost_sane,
+             "-f", lusername, NULL, bare_environ);
 #else /* USE_LOGIN_F */
-	execl(login_program, "login", "-r", rhost_sane, (char *)NULL);
+	execle(login_program, "login", "-r", rhost_sane, NULL, bare_environ);
 #endif /* USE_LOGIN_F */
 	syslog(LOG_ERR, "failed exec of %s: %s",
 	       login_program, error_message(errno));


Index: .cvsignore
===================================================================
RCS file: /cvs/extras/rpms/krb5/devel/.cvsignore,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -p -r1.28 -r1.29
--- .cvsignore	3 Feb 2010 17:11:34 -0000	1.28
+++ .cvsignore	5 Mar 2010 22:19:34 -0000	1.29
@@ -31,3 +31,8 @@ krb5-1.7-pdf.tar.gz
 krb5-1.7.1.tar.gz
 krb5-1.7.1.tar.gz.asc
 krb5-1.7.1-pdf.tar.gz
+krb5-1.8.tar.gz
+krb5-1.8.tar.gz.asc
+krb5-appl-1.0.tar.gz
+krb5-appl-1.0.tar.gz.asc
+krb5-1.8-pdf.tar.gz


Index: kadmind.init
===================================================================
RCS file: /cvs/extras/rpms/krb5/devel/kadmind.init,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -p -r1.19 -r1.20
--- kadmind.init	14 Jan 2010 21:14:25 -0000	1.19
+++ kadmind.init	5 Mar 2010 22:19:34 -0000	1.20
@@ -33,7 +33,7 @@
 # Source function library.
 . /etc/init.d/functions
 prog="Kerberos 5 Admin Server"
-kadmind=/usr/kerberos/sbin/kadmind
+kadmind=/usr/sbin/kadmind
 
 RETVAL=0
 


Index: kpropd.init
===================================================================
RCS file: /cvs/extras/rpms/krb5/devel/kpropd.init,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -p -r1.10 -r1.11
--- kpropd.init	14 Jan 2010 21:14:25 -0000	1.10
+++ kpropd.init	5 Mar 2010 22:19:34 -0000	1.11
@@ -29,7 +29,7 @@
 
 RETVAL=0
 prog="Kerberos 5 Propagation Server"
-kpropd=/usr/kerberos/sbin/kpropd
+kpropd=/usr/sbin/kpropd
 
 # Shell functions to cut down on useless shell instances.
 start() {


Index: krb5.spec
===================================================================
RCS file: /cvs/extras/rpms/krb5/devel/krb5.spec,v
retrieving revision 1.244
retrieving revision 1.245
diff -u -p -r1.244 -r1.245
--- krb5.spec	3 Mar 2010 16:16:35 -0000	1.244
+++ krb5.spec	5 Mar 2010 22:19:37 -0000	1.245
@@ -12,14 +12,18 @@
 
 Summary: The Kerberos network authentication system
 Name: krb5
-Version: 1.7.1
-Release: 6%{?dist}
+Version: 1.8
+Release: 1%{?dist}
 # Maybe we should explode from the now-available-to-everybody tarball instead?
 # http://web.mit.edu/kerberos/dist/krb5/1.7/krb5-1.7.1-signed.tar
 Source0: krb5-%{version}.tar.gz
 Source1: krb5-%{version}.tar.gz.asc
+# Everything that needs a krb5-appl counterpart will have it with number + 100
+# until we get the package split done, else the telnet/ftp/rcmd stuff will just
+# "vanish".
+Source100: krb5-appl-%{appl_version}.tar.gz
+Source101: krb5-appl-%{appl_version}.tar.gz.asc
 Source2: kpropd.init
-Source3: krb5-appl-%{appl_version}.tar.gz
 Source4: kadmind.init
 Source5: krb5kdc.init
 Source6: krb5.conf
@@ -41,7 +45,8 @@ Source22: ekrb5-telnet.xinetd
 # and tarred up.
 Source23: krb5-%{version}-pdf.tar.gz
 Source24: krb5-tex-pdf.sh
-Source25: krb5-trunk-manpaths.txt
+Source25: krb5-1.8-manpaths.txt
+Source125: krb5-appl-1.0-manpaths.txt
 Source26: gssftp.pamd
 Source27: kshell.pamd
 Source28: ekshell.pamd
@@ -51,45 +56,43 @@ Source31: kerberos-adm.portreserve
 Source32: krb5_prop.portreserve
 
 Patch3: krb5-1.3-netkit-rsh.patch
-Patch4: krb5-1.3-rlogind-environ.patch
-Patch5: krb5-1.3-ksu-access.patch
-Patch6: krb5-1.5-ksu-path.patch
+Patch4: krb5-appl-1.0-rlogind-environ.patch
+Patch5: krb5-1.8-ksu-access.patch
+Patch6: krb5-1.8-ksu-path.patch
 Patch11: krb5-1.2.1-passive.patch
 Patch12: krb5-1.7-ktany.patch
 Patch14: krb5-1.3-ftp-glob.patch
 Patch16: krb5-1.7-buildconf.patch
 Patch23: krb5-1.3.1-dns.patch
 Patch26: krb5-1.3.2-efence.patch
-Patch29: krb5-1.7-kprop-mktemp.patch
+Patch29: krb5-1.8-kprop-mktemp.patch
 Patch30: krb5-1.3.4-send-pr-tempfile.patch
-Patch33: krb5-1.7-io.patch
+Patch33: krb5-appl-1.0-io.patch
 Patch36: krb5-1.7-rcp-markus.patch
-Patch39: krb5-1.7-api.patch
+Patch39: krb5-1.8-api.patch
 Patch40: krb5-1.4.1-telnet-environ.patch
-Patch41: krb5-1.6.3-login-lpass.patch
 Patch53: krb5-1.7-nodeplibs.patch
 Patch55: krb5-1.6.1-empty.patch
 Patch56: krb5-1.7-doublelog.patch
-Patch57: krb5-1.6.2-login_chdir.patch
-Patch58: krb5-1.6.2-key_exp.patch
-Patch59: krb5-trunk-kpasswd_tcp.patch
-Patch60: krb5-1.7-pam.patch
-Patch61: krb5-trunk-manpaths.patch
-Patch63: krb5-1.7-selinux-label.patch
+Patch57: krb5-appl-1.0-login_chdir.patch
+Patch58: krb5-1.8-key_exp.patch
+Patch59: krb5-1.8-kpasswd_tcp.patch
+Patch60: krb5-1.8-pam.patch
+Patch160: krb5-appl-1.0-pam.patch
+Patch61: krb5-1.8-manpaths.patch
+Patch161: krb5-appl-1.0-manpaths.patch
+Patch63: krb5-1.8-selinux-label.patch
 Patch70: krb5-trunk-kpasswd_tcp2.patch
-Patch71: krb5-1.7-dirsrv-accountlock.patch
+Patch71: krb5-1.8-dirsrv-accountlock.patch
 Patch72: krb5-1.6.3-ftp_fdleak.patch
 Patch73: krb5-1.6.3-ftp_glob_runique.patch
 Patch79: krb5-trunk-ftp_mget_case.patch
-Patch86: krb5-1.7-time_t_size.patch
 Patch88: krb5-1.7-sizeof.patch
-Patch89: krb5-1.7-largefile.patch
-Patch90: krb5-1.7-openssl-1.0.patch
+Patch89: krb5-appl-1.0-largefile.patch
 Patch93: krb5-1.7-create_on_load.patch
-Patch95: krb5-1.7-opte.patch
-Patch96: krb5-1.7-exp_warn.patch
-Patch97: http://web.mit.edu/kerberos/advisories/2010-001-patch.txt
-Patch98: krb5-1.7.1-kpasswd_ccache.patch
+Patch95: krb5-1.8-opte.patch
+Patch96: krb5-1.8-exp_warn.patch
+Patch98: krb5-1.8-kpasswd_ccache.patch
 
 License: MIT
 URL: http://web.mit.edu/kerberos/www/
@@ -207,8 +210,7 @@ Group: System Environment/Base
 Requires: %{name}-workstation = %{version}-%{release}
 Requires(post): initscripts
 Requires(postun): initscripts
-# mktemp is used by krb5-send-pr
-Requires: mktemp, xinetd, /etc/pam.d/%{login_pam_service}
+Requires: xinetd, /etc/pam.d/%{login_pam_service}
 
 %description workstation-servers
 Kerberos is a network authentication system. The krb5-workstation-servers
@@ -228,50 +230,69 @@ to obtain initial credentials from a KDC
 certificate.
 
 %prep
-%setup -q -a 3 -a 23
-ln -s README LICENSE
-pushd src
-%patch60 -p2 -b .pam
-%patch61 -p0 -b .manpaths
+%setup -q -a 23 -a 100
+ln -s NOTICE LICENSE
+
+%patch60 -p1 -b .pam
+pushd krb5-appl-%{appl_version}
+%patch160 -p1 -b .pam
+popd
+
+%patch61 -p1 -b .manpaths
+pushd krb5-appl-%{appl_version}
+%patch161 -p1 -b .manpaths
 popd
+
 %patch63 -p1 -b .selinux-label
-%patch3  -p1 -b .netkit-rsh
+pushd krb5-appl-%{appl_version}
+%patch3  -p3 -b .netkit-rsh
 %patch4  -p1 -b .rlogind-environ
+popd
+
 %patch5  -p1 -b .ksu-access
 %patch6  -p1 -b .ksu-path
-%patch11 -p1 -b .passive
+pushd krb5-appl-%{appl_version}
+%patch11 -p3 -b .passive
+popd
 %patch12 -p1 -b .ktany
-%patch14 -p1 -b .ftp-glob
+pushd krb5-appl-%{appl_version}
+%patch14 -p3 -b .ftp-glob
+popd
 %patch16 -p1 -b .buildconf
 %patch23 -p1 -b .dns
 # Removes a malloc(0) case, nothing more.
 # %patch26 -p1 -b .efence
 %patch29 -p1 -b .kprop-mktemp
 %patch30 -p1 -b .send-pr-tempfile
+pushd krb5-appl-%{appl_version}
 %patch33 -p1 -b .io
-%patch36 -p1 -b .rcp-markus
+%patch36 -p3 -b .rcp-markus
+popd
 %patch39 -p1 -b .api
-%patch40 -p1 -b .telnet-environ
-%patch41 -p1 -b .login-lpass
+pushd krb5-appl-%{appl_version}
+%patch40 -p3 -b .telnet-environ
+popd
 %patch53 -p1 -b .nodeplibs
 #%patch55 -p1 -b .empty
 %patch56 -p1 -b .doublelog
-#%patch57 -p1 -b .login_chdir
+pushd krb5-appl-%{appl_version}
+%patch57 -p1 -b .login_chdir
+popd
 %patch58 -p1 -b .key_exp
-%patch59 -p0 -b .kpasswd_tcp
+%patch59 -p1 -b .kpasswd_tcp
 #%patch70 -p0 -b .kpasswd_tcp2
 %patch71 -p1 -b .dirsrv-accountlock
-%patch72 -p1 -b .ftp_fdleak
-%patch73 -p1 -b .ftp_glob_runique
-%patch79 -p0 -b .ftp_mget_case
-%patch86 -p1 -b .time_t_size
-%patch88 -p1 -b .sizeof
+pushd krb5-appl-%{appl_version}
+%patch72 -p3 -b .ftp_fdleak
+%patch73 -p3 -b .ftp_glob_runique
+%patch79 -p2 -b .ftp_mget_case
+%patch88 -p3 -b .sizeof
 %patch89 -p1 -b .largefile
-%patch90 -p0 -b .openssl-1.0
-%patch93 -p1 -b .create_on_load
+popd
+# Shouldn't be necessary in 1.8.
+##%patch93 -p1 -b .create_on_load
 %patch95 -p1 -b .opte
 %patch96 -p1 -b .exp_warn
-%patch97 -p1 -b .2010-001
 %patch98 -p1 -b .kpasswd-ccache
 gzip doc/*.ps
 
@@ -284,7 +305,7 @@ sed -i -e '1c\
 \\usepackage{hyperref}' doc/implement/implement.tex
 
 # Take the execute bit off of documentation.
-chmod -x doc/krb5-protocol/*.txt doc/*.html
+chmod -x doc/krb5-protocol/*.txt doc/*.html doc/*/*.html
 
 # Rename the man pages so that they'll get generated correctly.  Uses the
 # "krb5-trunk-manpaths.txt" source file.
@@ -293,6 +314,11 @@ cat %{SOURCE25} | while read manpage ; d
 	mv "$manpage" "$manpage".in
 done
 popd
+pushd krb5-appl-%{appl_version}
+cat %{SOURCE125} | while read manpage ; do
+	mv "$manpage" "$manpage".in
+done
+popd
 
 # Check that the PDFs we built earlier match this source tree, using the
 # "krb5-tex-pdf.sh" source file.
@@ -315,20 +341,21 @@ egrep -iv '(^$|^dn:|^changetype:|^add:)'
 touch -r $inldif 60kerberos.ldif
 
 # Rebuild the configure scripts.
-cd src
-top=`pwd`
-for configurein in `find -name configure.in -type f` ; do
-	pushd `dirname $configurein`
-	grep -q A._CONFIG_HEADER configure.in && autoheader -I "$top"
-	autoconf -I "$top"
-	popd
-done
+pushd src
+autoheader
+autoconf
+popd
+
+pushd krb5-appl-%{appl_version}
+autoheader
+autoconf
+popd
 
 %build
 cd src
 INCLUDES=-I%{_includedir}/et
 # Work out the CFLAGS and CPPFLAGS which we intend to use.
-CFLAGS="`echo $RPM_OPT_FLAGS $DEFINES $INCLUDES -fPIC -fno-strict-aliasing`"
+CFLAGS="`echo $RPM_OPT_FLAGS $DEFINES $INCLUDES -fPIC`"
 CPPFLAGS="`echo $DEFINES $INCLUDES`"
 %configure \
 	CC="%{__cc}" \
@@ -340,10 +367,6 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`"
 	SS_LIB="-lss -lncurses" \
 %endif
 	--enable-shared \
-	--bindir=%{krb5prefix}/bin \
-	--mandir=%{krb5prefix}/man \
-	--sbindir=%{krb5prefix}/sbin \
-	--datadir=%{krb5prefix}/share \
 	--localstatedir=%{_var}/kerberos \
 	--disable-rpath \
 	--with-system-et \
@@ -364,11 +387,28 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`"
 	--disable-pkinit \
 %endif
 	--with-pam \
-	--with-pam-login-service=%{login_pam_service} \
 	--with-selinux
 # Now build it.
 make %{?_smp_mflags}
 
+# The applications, too.  Build everything position-independent.  We only get
+# away with this if our build dependencies drag an older krb5-devel onto the
+# system.
+pushd ../krb5-appl-%{appl_version}
+CFLAGS="`echo $RPM_OPT_FLAGS $DEFINES $INCLUDES -fPIE -fno-strict-aliasing`"
+LDFLAGS="-pie"
+%configure \
+	CFLAGS="$CFLAGS" \
+	LDFLAGS="$LDFLAGS" \
+	--bindir=%{krb5prefix}/bin \
+	--mandir=%{krb5prefix}/man \
+	--sbindir=%{krb5prefix}/sbin \
+	--datadir=%{krb5prefix}/share \
+	--with-pam \
+	--with-pam-login-service=%{login_pam_service}
+make %{?_smp_mflags}
+popd
+
 # Run the test suite.  We can't actually do this in the build system.
 : make check TMPDIR=%{_tmppath}
 
@@ -399,7 +439,7 @@ install -pm 644 %{SOURCE6} $RPM_BUILD_RO
 
 # Login-time scriptlets (krb5.sh, krb5.csh) to fix the PATH variable.
 mkdir -p $RPM_BUILD_ROOT/etc/profile.d
-for subpackage in devel workstation ; do
+for subpackage in workstation-clients workstation-servers ; do
 	install -pm 644 %{SOURCE7} \
 	$RPM_BUILD_ROOT/etc/profile.d/krb5-$subpackage.sh
 	install -pm 644 %{SOURCE8} \
@@ -467,12 +507,13 @@ install -pdm 755 $RPM_BUILD_ROOT/%{_libd
 install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/authdata
 
 # The rest of the binaries, headers, libraries, and docs.
-make -C src DESTDIR=$RPM_BUILD_ROOT install
+make -C src DESTDIR=$RPM_BUILD_ROOT EXAMPLEDIR=%{_docdir}/krb5-libs-%{version}/examples install
+make -C krb5-appl-%{appl_version} DESTDIR=$RPM_BUILD_ROOT install
 
 # Munge krb5-config yet again.  This is totally wrong for 64-bit, but chunks
 # of the buildconf patch already conspire to strip out /usr/<anything> from the
 # list of link flags, and it helps prevent file conflicts on multilib systems.
-sed -r -i -e 's|^libdir=/usr/lib(64)?$|libdir=/usr/lib|g' $RPM_BUILD_ROOT%{krb5prefix}/bin/krb5-config
+sed -r -i -e 's|^libdir=/usr/lib(64)?$|libdir=/usr/lib|g' $RPM_BUILD_ROOT%{_bindir}/krb5-config
 
 # Move specific libraries from %{_libdir} to /%{_lib}, and fixup the symlinks.
 touch $RPM_BUILD_ROOT/rootfile
@@ -489,13 +530,6 @@ for library in libgssapi_krb5 libgssrpc 
 	popd
 done
 
-# Move man pages which will be in the -libs subpackage into %%{_mandir}'s tree.
-for man in man1/tmac.doc man1/kerberos.1 man5/.k5login.5 man5/krb5.conf.5 ; do
-	mkdir -p $RPM_BUILD_ROOT/%{_mandir}/${man%%/*}
-	mv $RPM_BUILD_ROOT/%{krb5prefix}/man/${man} \
-	   $RPM_BUILD_ROOT/%{_mandir}/${man%%/*}/
-done
-
 %clean
 [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
 
@@ -574,62 +608,56 @@ fi
 exit 0
 
 %files workstation
-%defattr(-,root,root)
-%docdir %{krb5prefix}/man
-%config(noreplace) /etc/profile.d/krb5-workstation.sh
-%config(noreplace) /etc/profile.d/krb5-workstation.csh
+%defattr(-,root,root,-)
 %doc doc/user*.ps.gz src/config-files/services.append
 %doc doc/{kdestroy,kinit,klist,kpasswd,ksu}.html
+%doc doc/krb5-user.html
 %attr(0755,root,root) %doc src/config-files/convert-config-files
 %{_infodir}/krb5-user.info*
 
-%dir %{krb5prefix}
-%dir %{krb5prefix}/bin
-%dir %{krb5prefix}/man
-%dir %{krb5prefix}/man/man1
-%dir %{krb5prefix}/man/man8
-%dir %{krb5prefix}/sbin
-
 # Clients of the KDC, including tools you're likely to need if you're running
 # app servers other than those built from this source package.
-%{krb5prefix}/bin/kdestroy
-%{krb5prefix}/man/man1/kdestroy.1*
-%{krb5prefix}/bin/kinit
-%{krb5prefix}/man/man1/kinit.1*
-%{krb5prefix}/bin/klist
-%{krb5prefix}/man/man1/klist.1*
-%{krb5prefix}/bin/kpasswd
-%{krb5prefix}/man/man1/kpasswd.1*
-
-%{krb5prefix}/bin/kvno
-%{krb5prefix}/man/man1/kvno.1*
-%{krb5prefix}/bin/kadmin
-%{krb5prefix}/man/man1/kadmin.1*
-%{krb5prefix}/bin/k5srvutil
-%{krb5prefix}/man/man1/k5srvutil.1*
-%{krb5prefix}/bin/ktutil
-%{krb5prefix}/man/man1/ktutil.1*
+%{_bindir}/kdestroy
+%{_mandir}/man1/kdestroy.1*
+%{_bindir}/kinit
+%{_mandir}/man1/kinit.1*
+%{_bindir}/klist
+%{_mandir}/man1/klist.1*
+%{_bindir}/kpasswd
+%{_mandir}/man1/kpasswd.1*
+
+%{_bindir}/kvno
+%{_mandir}/man1/kvno.1*
+%{_bindir}/kadmin
+%{_mandir}/man1/kadmin.1*
+%{_bindir}/k5srvutil
+%{_mandir}/man1/k5srvutil.1*
+%{_bindir}/ktutil
+%{_mandir}/man1/ktutil.1*
 
 # Doesn't really fit anywhere else.
-%attr(4755,root,root) %{krb5prefix}/bin/ksu
-%{krb5prefix}/man/man1/ksu.1*
+%attr(4755,root,root) %{_bindir}/ksu
+%{_mandir}/man1/ksu.1*
 %config(noreplace) /etc/pam.d/ksu
 
 # Problem-reporting tool.
-%{krb5prefix}/sbin/krb5-send-pr
-%{krb5prefix}/man/man1/krb5-send-pr.1*
+%{_sbindir}/krb5-send-pr
+%dir %{_datadir}/gnats
+%{_datadir}/gnats/mit
+%{_mandir}/man1/krb5-send-pr.1*
 
 %files workstation-clients
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %docdir %{krb5prefix}/man
-%doc doc/{ftp,rcp,rlogin,rsh,telnet}.html
 %attr(0755,root,root) %doc src/config-files/convert-config-files
 
+%config(noreplace) /etc/profile.d/krb5-workstation-clients.sh
+%config(noreplace) /etc/profile.d/krb5-workstation-clients.csh
+
 %dir %{krb5prefix}
 %dir %{krb5prefix}/bin
 %dir %{krb5prefix}/man
 %dir %{krb5prefix}/man/man1
-%dir %{krb5prefix}/sbin
 
 # Used by both clients and servers.
 %{krb5prefix}/bin/rcp
@@ -646,11 +674,15 @@ exit 0
 %{krb5prefix}/man/man1/rsh.1*
 %{krb5prefix}/bin/telnet
 %{krb5prefix}/man/man1/telnet.1*
+%{krb5prefix}/man/man1/tmac.doc*
 
 %files workstation-servers
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %docdir %{krb5prefix}/man
 
+%config(noreplace) /etc/profile.d/krb5-workstation-servers.sh
+%config(noreplace) /etc/profile.d/krb5-workstation-servers.csh
+
 %dir %{krb5prefix}
 %dir %{krb5prefix}/bin
 %dir %{krb5prefix}/man
@@ -658,10 +690,6 @@ exit 0
 %dir %{krb5prefix}/man/man8
 %dir %{krb5prefix}/sbin
 
-# Problem-reporting tool.
-%{krb5prefix}/sbin/krb5-send-pr
-%{krb5prefix}/man/man1/krb5-send-pr.1*
-
 # Used by both clients and servers.
 %{krb5prefix}/bin/rcp
 %{krb5prefix}/man/man1/rcp.1*
@@ -686,8 +714,8 @@ exit 0
 %{krb5prefix}/man/man8/telnetd.8*
 
 %files server
-%defattr(-,root,root)
-%docdir %{krb5prefix}/man
+%defattr(-,root,root,-)
+%docdir %{_mandir}
 
 /etc/rc.d/init.d/krb5kdc
 /etc/rc.d/init.d/kadmin
@@ -700,6 +728,8 @@ exit 0
 
 %doc doc/admin*.ps.gz
 %doc doc/install*.ps.gz
+%doc doc/krb5-admin.html
+%doc doc/krb5-install.html
 
 %{_infodir}/krb5-admin.info*
 %{_infodir}/krb5-install.info*
@@ -709,82 +739,72 @@ exit 0
 %config(noreplace) %{_var}/kerberos/krb5kdc/kdc.conf
 %config(noreplace) %{_var}/kerberos/krb5kdc/kadm5.acl
 
-%dir %{krb5prefix}
-%dir %{krb5prefix}/bin
 %dir %{_libdir}/krb5
 %dir %{_libdir}/krb5/plugins
 %dir %{_libdir}/krb5/plugins/kdb
 %dir %{_libdir}/krb5/plugins/preauth
 %dir %{_libdir}/krb5/plugins/authdata
-%dir %{krb5prefix}/man
-%dir %{krb5prefix}/man/man1
-%dir %{krb5prefix}/man/man5
-%dir %{krb5prefix}/man/man8
-%dir %{krb5prefix}/sbin
 
 # Problem-reporting tool.
-%{krb5prefix}/sbin/krb5-send-pr
-%{krb5prefix}/man/man1/krb5-send-pr.1*
-
-# KDC binaries.
-%{krb5prefix}/man/man5/kdc.conf.5*
-%{krb5prefix}/sbin/kadmin.local
-%{krb5prefix}/man/man8/kadmin.local.8*
-%{krb5prefix}/sbin/kadmind
-%{krb5prefix}/man/man8/kadmind.8*
-%{krb5prefix}/sbin/kdb5_util
-%{krb5prefix}/man/man8/kdb5_util.8*
-%{krb5prefix}/sbin/kprop
-%{krb5prefix}/man/man8/kprop.8*
-%{krb5prefix}/sbin/kpropd
-%{krb5prefix}/man/man8/kpropd.8*
-%{krb5prefix}/sbin/kproplog
-%{krb5prefix}/man/man8/kproplog.8*
-%{krb5prefix}/sbin/krb5kdc
-%{krb5prefix}/man/man8/krb5kdc.8*
+%{_sbindir}/krb5-send-pr
+%dir %{_datadir}/gnats
+%{_datadir}/gnats/mit
+%{_mandir}/man1/krb5-send-pr.1*
+
+# KDC binaries and configuration.
+%{_mandir}/man5/kdc.conf.5*
+%{_sbindir}/kadmin.local
+%{_mandir}/man8/kadmin.local.8*
+%{_sbindir}/kadmind
+%{_mandir}/man8/kadmind.8*
+%{_sbindir}/kdb5_util
+%{_mandir}/man8/kdb5_util.8*
+%{_sbindir}/kprop
+%{_mandir}/man8/kprop.8*
+%{_sbindir}/kpropd
+%{_mandir}/man8/kpropd.8*
+%{_sbindir}/kproplog
+%{_mandir}/man8/kproplog.8*
+%{_sbindir}/krb5kdc
+%{_mandir}/man8/krb5kdc.8*
 
 # This is here for people who want to test their server, and also 
 # included in devel package for similar reasons.
-%{krb5prefix}/bin/sclient
-%{krb5prefix}/man/man1/sclient.1*
-%{krb5prefix}/sbin/sserver
-%{krb5prefix}/man/man8/sserver.8*
+%{_bindir}/sclient
+%{_mandir}/man1/sclient.1*
+%{_sbindir}/sserver
+%{_mandir}/man8/sserver.8*
 
 %if %{WITH_LDAP}
 %files server-ldap
-%defattr(-,root,root)
-%docdir %{krb5prefix}/man
+%defattr(-,root,root,-)
+%docdir %{_mandir}
 %doc src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
 %doc src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema
 %doc 60kerberos.ldif
 %dir %{_libdir}/krb5
 %dir %{_libdir}/krb5/plugins
 %dir %{_libdir}/krb5/plugins/kdb
-%dir %{krb5prefix}
-%dir %{krb5prefix}/man
-%dir %{krb5prefix}/man/man8
-%dir %{krb5prefix}/sbin
 %{_libdir}/krb5/plugins/kdb/kldap.so
 %{_libdir}/libkdb_ldap.so
 %{_libdir}/libkdb_ldap.so.*
-%{krb5prefix}/man/man8/kdb5_ldap_util.8.gz
-%{krb5prefix}/sbin/kdb5_ldap_util
+%{_mandir}/man8/kdb5_ldap_util.8.gz
+%{_sbindir}/kdb5_ldap_util
 %endif
 
 %files libs
-%defattr(-,root,root)
-%doc README LICENSE
-%docdir %{krb5prefix}/man
+%defattr(-,root,root,-)
+%doc README NOTICE LICENSE
+%docdir %{_mandir}
 %verify(not md5 size mtime) %config(noreplace) /etc/krb5.conf
-/%{_mandir}/man1/tmac.doc*
 /%{_mandir}/man1/kerberos.1*
 /%{_mandir}/man5/.k5login.5*
 /%{_mandir}/man5/krb5.conf.5*
 /%{_lib}/libgssapi_krb5.so.*
 /%{_lib}/libgssrpc.so.*
 /%{_lib}/libk5crypto.so.*
-%{_libdir}/libkadm5clnt.so.*
-%{_libdir}/libkadm5srv.so.*
+%{_libdir}/libkadm5clnt_mit.so.*
+%{_libdir}/libkadm5srv_mit.so.*
 %{_libdir}/libkdb5.so.*
 /%{_lib}/libkrb5.so.*
 /%{_lib}/libkrb5support.so.*
@@ -797,7 +817,7 @@ exit 0
 
 %if %{WITH_OPENSSL}
 %files pkinit-openssl
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_libdir}/krb5
 %dir %{_libdir}/krb5/plugins
 %dir %{_libdir}/krb5/plugins/preauth
@@ -805,55 +825,58 @@ exit 0
 %endif
 
 %files devel
-%defattr(-,root,root)
-
-%config(noreplace) /etc/profile.d/krb5-devel.sh
-%config(noreplace) /etc/profile.d/krb5-devel.csh
-
-%docdir %{krb5prefix}/man
+%defattr(-,root,root,-)
+%docdir %{_mandir}
 %doc doc/api/*.pdf
+%doc doc/ccapi
 %doc doc/implement/*.pdf
 %doc doc/kadm5/*.pdf
 %doc doc/kadmin
+%doc doc/kim
 %doc doc/krb5-protocol
 %doc doc/rpc
 %doc doc/threads.txt
 
-%dir %{krb5prefix}
-%dir %{krb5prefix}/bin
-%dir %{krb5prefix}/man
-%dir %{krb5prefix}/man/man1
-%dir %{krb5prefix}/man/man8
-%dir %{krb5prefix}/sbin
-
 %{_includedir}/*
 %{_libdir}/libgssapi_krb5.so
 %{_libdir}/libgssrpc.so
 %{_libdir}/libk5crypto.so
 %{_libdir}/libkadm5clnt.so
+%{_libdir}/libkadm5clnt_mit.so
 %{_libdir}/libkadm5srv.so
+%{_libdir}/libkadm5srv_mit.so
 %{_libdir}/libkdb5.so
 %{_libdir}/libkrb5.so
 %{_libdir}/libkrb5support.so
 
-%{krb5prefix}/bin/krb5-config
-%{krb5prefix}/bin/sclient
-%{krb5prefix}/man/man1/krb5-config.1*
-%{krb5prefix}/man/man1/sclient.1*
-%{krb5prefix}/man/man8/sserver.8*
-%{krb5prefix}/sbin/sserver
+%{_bindir}/krb5-config
+%{_bindir}/sclient
+%{_mandir}/man1/krb5-config.1*
+%{_mandir}/man1/sclient.1*
+%{_mandir}/man8/sserver.8*
+%{_sbindir}/sserver
 
 # Protocol test clients.
-%{krb5prefix}/bin/sim_client
-%{krb5prefix}/bin/gss-client
-%{krb5prefix}/bin/uuclient
+%{_bindir}/sim_client
+%{_bindir}/gss-client
+%{_bindir}/uuclient
 
 # Protocol test servers.
-%{krb5prefix}/sbin/sim_server
-%{krb5prefix}/sbin/gss-server
-%{krb5prefix}/sbin/uuserver
+%{_sbindir}/sim_server
+%{_sbindir}/gss-server
+%{_sbindir}/uuserver
 
 %changelog
+* Fri Mar  5 2010 Nalin Dahyabhai <nalin at redhat.com> - 1.8-1
+- update to 1.8
+  - temporarily bundling the krb5-appl package (split upstream as of 1.8)
+    until its package review is complete
+  - profile.d scriptlets are now only needed by -workstation-clients
+  - adjust paths in init scripts
+  - drop upstreamed fix for KDC denial of service (CVE-2010-0283)
+  - drop patch to check the user's password correctly using crypt(), which
+    isn't a code path we hit when we're using PAM
+
 * Wed Mar  3 2010 Nalin Dahyabhai <nalin at redhat.com> - 1.7.1-6
 - fix a null pointer dereference and crash introduced in our PAM patch that
   would happen if ftpd was given the name of a user who wasn't known to the


Index: krb5kdc.init
===================================================================
RCS file: /cvs/extras/rpms/krb5/devel/krb5kdc.init,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -p -r1.14 -r1.15
--- krb5kdc.init	14 Jan 2010 21:14:26 -0000	1.14
+++ krb5kdc.init	5 Mar 2010 22:19:38 -0000	1.15
@@ -33,7 +33,7 @@
 
 RETVAL=0
 prog="Kerberos 5 KDC"
-krb5kdc=/usr/kerberos/sbin/krb5kdc
+krb5kdc=/usr/sbin/krb5kdc
 
 # Shell functions to cut down on useless shell instances.
 start() {


Index: sources
===================================================================
RCS file: /cvs/extras/rpms/krb5/devel/sources,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -p -r1.30 -r1.31
--- sources	3 Feb 2010 17:11:35 -0000	1.30
+++ sources	5 Mar 2010 22:19:38 -0000	1.31
@@ -1,3 +1,5 @@
-9d79efba57423008e65efc5ff75405d6  krb5-1.7.1.tar.gz
-2197cc65ed90f00f92e5a27bd514b53b  krb5-1.7.1.tar.gz.asc
-309139729539cf5ef403bb0dc7ae455b  krb5-1.7.1-pdf.tar.gz
+a3391a739009efa9734db720d34f4c07  krb5-1.8.tar.gz
+f923ec08f24df9e5a284be74895a6daa  krb5-1.8.tar.gz.asc
+4ecf03dad0df7f2ded49f0cfd9786157  krb5-appl-1.0.tar.gz
+33056e617e2cbad7c8e8b732aa0fdd91  krb5-appl-1.0.tar.gz.asc
+32f8238d4553c44ecdc41205c3cb0333  krb5-1.8-pdf.tar.gz


--- 2010-001-patch.txt DELETED ---


--- krb5-1.3-ksu-access.patch DELETED ---


--- krb5-1.3-rlogind-environ.patch DELETED ---


--- krb5-1.5-ksu-path.patch DELETED ---


--- krb5-1.6.2-key_exp.patch DELETED ---


--- krb5-1.6.2-login_chdir.patch DELETED ---


--- krb5-1.6.3-login-lpass.patch DELETED ---


--- krb5-1.7-api.patch DELETED ---


--- krb5-1.7-dirsrv-accountlock.patch DELETED ---


--- krb5-1.7-exp_warn.patch DELETED ---


--- krb5-1.7-io.patch DELETED ---


--- krb5-1.7-kprop-mktemp.patch DELETED ---


--- krb5-1.7-largefile.patch DELETED ---


--- krb5-1.7-openssl-1.0.patch DELETED ---


--- krb5-1.7-opte.patch DELETED ---


--- krb5-1.7-pam.patch DELETED ---


--- krb5-1.7-selinux-label.patch DELETED ---


--- krb5-1.7-time_t_size.patch DELETED ---


--- krb5-1.7.1-kpasswd_ccache.patch DELETED ---


--- krb5-trunk-kpasswd_tcp.patch DELETED ---


--- krb5-trunk-manpaths.patch DELETED ---



More information about the scm-commits mailing list