COMMAND
kth-krb
SYSTEMS AFFECTED
- MIT Kerberos 5, all releases prior to krb5-1.2.2-beta1
- MIT Kerberos 4 patch 10, and likely earlier releases as well
- Kerbnet (Cygnus implementation of Kerberos 5)
- Cygnus Network Security (CNS -- Cygnus implementation of Kerberos 4)
PROBLEM
Jouko Pynnonen and Assar Westerlund discovered and reported
following. A /tmp race condition exists in MIT-derived
implementations of Kerberos 4. On a system running login daemons
with Kerberos 4 support, a local user may be able to overwrite
arbitrary files as root, with limited contents. This could
potentially result in unauthorized root access.
A filesystem race condition exists in the ticket file handling
code in the krb4 library. This race condition has existed since
the early MIT implementations of Kerberos 4. By winning this race
condition, especially while new ticket files are being created by
login daemons running as root, a user may overwrite arbitrary
files as root, but with limited contents. The possible contents
of the overwritten files are limited to the initial contents of a
normal Kerberos 4 ticket file.
SOLUTION
The MIT krb5-1.2.2 release contains a fix for this bug. If you
are unable to upgrade to krb5-1.2.2, the best course of action is
to patch the krb4 library, and recompile or relink your login
daemons. Patches below are only provided for krb5-1.2.1;
additional patches against other releases may be generated and
posted if requested. These patches are against the krb5-1.2.1
release. They may apply against earlier releases, though. The
patches may also be found at:
http://web.mit.edu/kerberos/www/advisories/krb4tkt_121_patch.txt
Patches:
Index: lib/krb4/dest_tkt.c
===================================================================
RCS file: /cvs/krbdev/krb5/src/lib/krb4/dest_tkt.c,v
retrieving revision 1.5.8.1
retrieving revision 1.5.8.2
diff -c -r1.5.8.1 -r1.5.8.2
*** dest_tkt.c 2000/04/29 01:48:10 1.5.8.1
--- dest_tkt.c 2001/01/27 04:43:31 1.5.8.2
***************
*** 1,14 ****
/*
! * dest_tkt.c
*
! * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
! * of Technology.
*
! * For copying and distribution information, please see the file
! * <mit-copyright.h>.
*/
- #include "mit-copyright.h"
#include "krb.h"
#include <stdio.h>
#include <string.h>
--- 1,29 ----
/*
! * lib/krb4/dest_tkt.c
*
! * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
! * Institute of Technology. All Rights Reserved.
*
! * Export of this software from the United States of America may
! * require a specific license from the United States Government.
! * It is the responsibility of any person or organization contemplating
! * export to obtain such a license before exporting.
! *
! * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
! * distribute this software and its documentation for any purpose and
! * without fee is hereby granted, provided that the above copyright
! * notice appear in all copies and that both that copyright notice and
! * this permission notice appear in supporting documentation, and that
! * the name of M.I.T. not be used in advertising or publicity pertaining
! * to distribution of the software without specific, written prior
! * permission. Furthermore if you modify this software you must label
! * your software as modified software and not distribute it in such a
! * fashion that it might be confused with the original M.I.T. software.
! * M.I.T. makes no representations about the suitability of
! * this software for any purpose. It is provided "as is" without express
! * or implied warranty.
*/
#include "krb.h"
#include <stdio.h>
#include <string.h>
***************
*** 17,28 ****
--- 32,60 ----
#ifdef TKT_SHMEM
#include <sys/param.h>
#endif
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
#include <errno.h>
#ifndef O_SYNC
#define O_SYNC 0
#endif
+ #ifdef HAVE_SETEUID
+ #define do_seteuid(e) seteuid((e))
+ #else
+ #ifdef HAVE_SETRESUID
+ #define do_seteuid(e) setresuid(-1, (e), -1)
+ #else
+ #ifdef HAVE_SETREUID
+ #define do_seteuid(e) setreuid(geteuid(), (e))
+ #else
+ #define do_seteuid(e) (errno = EPERM, -1)
+ #endif
+ #endif
+ #endif
+
/*
* dest_tkt() is used to destroy the ticket store upon logout.
* If the ticket file does not exist, dest_tkt() returns RET_TKFIL.
***************
*** 38,47 ****
char *file = TKT_FILE;
int i,fd;
extern int errno;
! struct stat statb;
char buf[BUFSIZ];
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
#endif /* TKT_SHMEM */
/* If ticket cache selector is null, use default cache. */
--- 70,82 ----
char *file = TKT_FILE;
int i,fd;
extern int errno;
! int ret;
! struct stat statpre, statpost;
char buf[BUFSIZ];
+ uid_t me, metoo;
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
+ size_t shmidlen;
#endif /* TKT_SHMEM */
/* If ticket cache selector is null, use default cache. */
***************
*** 49,70 ****
file = tkt_string();
errno = 0;
! if (lstat(file,&statb) < 0)
goto out;
!
! if (!(statb.st_mode & S_IFREG)
! #ifdef notdef
! || statb.st_mode & 077
! #endif
! )
goto out;
!
! if ((fd = open(file, O_RDWR|O_SYNC, 0)) < 0)
goto out;
memset(buf, 0, BUFSIZ);
!
! for (i = 0; i < statb.st_size; i += BUFSIZ)
if (write(fd, buf, BUFSIZ) != BUFSIZ) {
#ifndef NO_FSYNC
(void) fsync(fd);
--- 84,139 ----
file = tkt_string();
errno = 0;
! ret = KSUCCESS;
! me = getuid();
! metoo = geteuid();
!
! if (lstat(file, &statpre) < 0)
! return (errno == ENOENT) ? RET_TKFIL : KFAILURE;
! /*
! * This does not guard against certain cases that are vulnerable
! * to race conditions, such as world-writable or group-writable
! * directories that are not stickybitted, or untrusted path
! * components. In all other cases, the following checks should be
! * sufficient. It is assumed that the aforementioned certain
! * vulnerable cases are unlikely to arise on a well-administered
! * system where the user is not deliberately being stupid.
! */
! if (!(statpre.st_mode & S_IFREG) || me != statpre.st_uid
! || statpre.st_nlink != 1)
! return KFAILURE;
! /*
! * Yes, we do uid twiddling here. It's not optimal, but some
! * applications may expect that the ruid is what should really own
! * the ticket file, e.g. setuid applications.
! */
! if (me != metoo && do_seteuid(me) < 0)
! return KFAILURE;
! if ((fd = open(file, O_RDWR|O_SYNC, 0)) < 0) {
! ret = (errno == ENOENT) ? RET_TKFIL : KFAILURE;
goto out;
! }
! /*
! * Do some additional paranoid things. The worst-case situation
! * is that a user may be fooled into opening a non-regular file
! * briefly if the file is in a directory with improper
! * permissions.
! */
! if (fstat(fd, &statpost) < 0) {
! (void)close(fd);
! ret = KFAILURE;
goto out;
! }
! if (statpre.st_dev != statpost.st_dev
! || statpre.st_ino != statpost.st_ino) {
! (void)close(fd);
! errno = 0;
! ret = KFAILURE;
goto out;
+ }
memset(buf, 0, BUFSIZ);
! for (i = 0; i < statpost.st_size; i += BUFSIZ)
if (write(fd, buf, BUFSIZ) != BUFSIZ) {
#ifndef NO_FSYNC
(void) fsync(fd);
***************
*** 81,97 ****
(void) unlink(file);
out:
! if (errno == ENOENT) return RET_TKFIL;
! else if (errno != 0) return KFAILURE;
#ifdef TKT_SHMEM
/*
* handle the shared memory case
*/
! (void) strncpy(shmidname, file, sizeof(shmidname) - 1);
! shmidname[sizeof(shmidname) - 1] = '\0';
! (void) strcat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname));
! if ((i = krb_shm_dest(shmidname)) != KSUCCESS)
! return(i);
! #endif /* TKT_SHMEM */
! return(KSUCCESS);
}
--- 150,171 ----
(void) unlink(file);
out:
! if (me != metoo && do_seteuid(metoo) < 0)
! return KFAILURE;
! if (ret != KSUCCESS)
! return ret;
!
#ifdef TKT_SHMEM
/*
* handle the shared memory case
*/
! shmidlen = strlen(file) + sizeof(".shm");
! if (shmidlen > sizeof(shmidname))
! return RET_TKFIL;
! (void)strcpy(shmidname, file);
! (void)strcat(shmidname, ".shm");
! return krb_shm_dest(shmidname);
! #else /* !TKT_SHMEM */
! return KSUCCESS;
! #endif /* !TKT_SHMEM */
}
Index: lib/krb4/in_tkt.c
===================================================================
RCS file: /cvs/krbdev/krb5/src/lib/krb4/in_tkt.c,v
retrieving revision 1.6.8.1
retrieving revision 1.6.8.2
diff -c -r1.6.8.1 -r1.6.8.2
*** in_tkt.c 2000/04/29 01:48:10 1.6.8.1
--- in_tkt.c 2001/01/27 04:43:32 1.6.8.2
***************
*** 1,14 ****
/*
! * in_tkt.c
*
! * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
! * of Technology.
*
! * For copying and distribution information, please see the file
! * <mit-copyright.h>.
*/
- #include "mit-copyright.h"
#include <stdio.h>
#include <string.h>
#include "krb.h"
--- 1,29 ----
/*
! * lib/krb4/in_tkt.c
*
! * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
! * Institute of Technology. All Rights Reserved.
*
! * Export of this software from the United States of America may
! * require a specific license from the United States Government.
! * It is the responsibility of any person or organization contemplating
! * export to obtain such a license before exporting.
! *
! * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
! * distribute this software and its documentation for any purpose and
! * without fee is hereby granted, provided that the above copyright
! * notice appear in all copies and that both that copyright notice and
! * this permission notice appear in supporting documentation, and that
! * the name of M.I.T. not be used in advertising or publicity pertaining
! * to distribution of the software without specific, written prior
! * permission. Furthermore if you modify this software you must label
! * your software as modified software and not distribute it in such a
! * fashion that it might be confused with the original M.I.T. software.
! * M.I.T. makes no representations about the suitability of
! * this software for any purpose. It is provided "as is" without express
! * or implied warranty.
*/
#include <stdio.h>
#include <string.h>
#include "krb.h"
***************
*** 34,40 ****
#define do_seteuid(e) seteuid((e))
#else
#ifdef HAVE_SETRESUID
! #define do_seteuid(e) setresuid(getuid(), (e), geteuid())
#else
#ifdef HAVE_SETREUID
#define do_seteuid(e) setreuid(geteuid(), (e))
--- 49,55 ----
#define do_seteuid(e) seteuid((e))
#else
#ifdef HAVE_SETRESUID
! #define do_seteuid(e) setresuid(-1, (e), -1)
#else
#ifdef HAVE_SETREUID
#define do_seteuid(e) setreuid(geteuid(), (e))
***************
*** 55,61 ****
{
int tktfile;
uid_t me, metoo, getuid(), geteuid();
! struct stat buf;
int count;
char *file = TKT_FILE;
int fd;
--- 70,76 ----
{
int tktfile;
uid_t me, metoo, getuid(), geteuid();
! struct stat statpre, statpost;
int count;
char *file = TKT_FILE;
int fd;
***************
*** 72,91 ****
me = getuid ();
metoo = geteuid();
! if (lstat(file,&buf) == 0) {
! if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
! buf.st_mode & 077) {
if (krb_debug)
fprintf(stderr,"Error initializing %s",file);
return(KFAILURE);
}
/* file already exists, and permissions appear ok, so nuke it */
! if ((fd = open(file, O_RDWR|O_SYNC, 0)) < 0)
goto out; /* can't zero it, but we can still try truncating it */
memset(charbuf, 0, sizeof(charbuf));
! for (i = 0; i < buf.st_size; i += sizeof(charbuf))
if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
#ifndef NO_FSYNC
(void) fsync(fd);
--- 87,135 ----
me = getuid ();
metoo = geteuid();
! if (lstat(file, &statpre) == 0) {
! if (statpre.st_uid != me || !(statpre.st_mode & S_IFREG)
! || statpre.st_nlink != 1 || statpre.st_mode & 077) {
if (krb_debug)
fprintf(stderr,"Error initializing %s",file);
return(KFAILURE);
}
+ /*
+ * Yes, we do uid twiddling here. It's not optimal, but some
+ * applications may expect that the ruid is what should really
+ * own the ticket file, e.g. setuid applications.
+ */
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
/* file already exists, and permissions appear ok, so nuke it */
! fd = open(file, O_RDWR|O_SYNC, 0);
! (void)unlink(file);
! if (me != metoo && do_seteuid(metoo) < 0)
! return KFAILURE;
! if (fd < 0) {
goto out; /* can't zero it, but we can still try truncating it */
+ }
+
+ /*
+ * Do some additional paranoid things. The worst-case
+ * situation is that a user may be fooled into opening a
+ * non-regular file briefly if the file is in a directory with
+ * improper permissions.
+ */
+ if (fstat(fd, &statpost) < 0) {
+ (void)close(fd);
+ goto out;
+ }
+ if (statpre.st_dev != statpost.st_dev
+ || statpre.st_ino != statpost.st_ino) {
+ (void)close(fd);
+ errno = 0;
+ goto out;
+ }
memset(charbuf, 0, sizeof(charbuf));
! for (i = 0; i < statpost.st_size; i += sizeof(charbuf))
if (write(fd, charbuf, sizeof(charbuf)) != sizeof(charbuf)) {
#ifndef NO_FSYNC
(void) fsync(fd);
***************
*** 117,128 ****
/* Set umask to ensure that we have write access on the created
ticket file. */
mask = umask(077);
! if ((tktfile = creat(file,0600)) < 0) {
! umask(mask);
! if (krb_debug)
! fprintf(stderr,"Error initializing %s",TKT_FILE);
! return(KFAILURE);
! }
umask(mask);
if (me != metoo) {
if (do_seteuid(metoo) < 0) {
--- 161,167 ----
/* Set umask to ensure that we have write access on the created
ticket file. */
mask = umask(077);
! tktfile = open(file, O_RDWR|O_SYNC|O_CREAT|O_EXCL, 0600);
umask(mask);
if (me != metoo) {
if (do_seteuid(metoo) < 0) {
***************
*** 134,152 ****
if (krb_debug)
printf("swapped UID's %d and %d\n",me,metoo);
}
! if (lstat(file,&buf) < 0) {
if (krb_debug)
fprintf(stderr,"Error initializing %s",TKT_FILE);
return(KFAILURE);
}
-
- if (buf.st_uid != me || !(buf.st_mode & S_IFREG) ||
- buf.st_mode & 077) {
- if (krb_debug)
- fprintf(stderr,"Error initializing %s",TKT_FILE);
- return(KFAILURE);
- }
-
count = strlen(pname)+1;
if (write(tktfile,pname,count) != count) {
(void) close(tktfile);
--- 173,183 ----
if (krb_debug)
printf("swapped UID's %d and %d\n",me,metoo);
}
! if (tktfile < 0) {
if (krb_debug)
fprintf(stderr,"Error initializing %s",TKT_FILE);
return(KFAILURE);
}
count = strlen(pname)+1;
if (write(tktfile,pname,count) != count) {
(void) close(tktfile);
Index: lib/krb4/tf_util.c
===================================================================
RCS file: /cvs/krbdev/krb5/src/lib/krb4/tf_util.c,v
retrieving revision 1.12.4.1
retrieving revision 1.12.4.2
diff -c -r1.12.4.1 -r1.12.4.2
*** tf_util.c 2000/04/29 01:48:11 1.12.4.1
--- tf_util.c 2001/01/27 04:43:32 1.12.4.2
***************
*** 1,20 ****
/*
! * tf_util.c
*
! * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
*
! * For copying and distribution information, please see the file
! * <mit-copyright.h>.
*/
- #include "mit-copyright.h"
-
#include "krb.h"
#include "k5-int.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
--- 1,38 ----
/*
! * lib/krb4/tf_util.c
*
! * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
! * Institute of Technology. All Rights Reserved.
*
! * Export of this software from the United States of America may
! * require a specific license from the United States Government.
! * It is the responsibility of any person or organization contemplating
! * export to obtain such a license before exporting.
! *
! * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
! * distribute this software and its documentation for any purpose and
! * without fee is hereby granted, provided that the above copyright
! * notice appear in all copies and that both that copyright notice and
! * this permission notice appear in supporting documentation, and that
! * the name of M.I.T. not be used in advertising or publicity pertaining
! * to distribution of the software without specific, written prior
! * permission. Furthermore if you modify this software you must label
! * your software as modified software and not distribute it in such a
! * fashion that it might be confused with the original M.I.T. software.
! * M.I.T. makes no representations about the suitability of
! * this software for any purpose. It is provided "as is" without express
! * or implied warranty.
*/
#include "krb.h"
#include "k5-int.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
#include <sys/stat.h>
#include <fcntl.h>
***************
*** 44,50 ****
#ifdef NEED_UTIMES
#include <sys/time.h>
- #include <unistd.h>
#ifdef __SCO__
#include <utime.h>
#endif
--- 62,67 ----
***************
*** 62,67 ****
--- 79,98 ----
}
#endif
+ #ifdef HAVE_SETEUID
+ #define do_seteuid(e) seteuid((e))
+ #else
+ #ifdef HAVE_SETRESUID
+ #define do_seteuid(e) setresuid(-1, (e), -1)
+ #else
+ #ifdef HAVE_SETREUID
+ #define do_seteuid(e) setreuid(geteuid(), (e))
+ #else
+ #define do_seteuid(e) (errno = EPERM, -1)
+ #endif
+ #endif
+ #endif
+
/*
* fd must be initialized to something that won't ever occur as a real
* file descriptor. Since open(2) returns only non-negative numbers as
***************
*** 149,155 ****
int rw;
{
int wflag;
! uid_t me= getuid();
struct stat stat_buf, stat_buffd;
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
--- 180,186 ----
int rw;
{
int wflag;
! uid_t me, metoo;
struct stat stat_buf, stat_buffd;
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
***************
*** 163,168 ****
--- 194,200 ----
}
me = getuid();
+ metoo = geteuid();
switch (rw) {
case R_TKT_FIL:
***************
*** 196,203 ****
--- 228,257 ----
curpos = sizeof(tfbfr);
#ifdef TKT_SHMEM
+ if (lstat(shmidname, &stat_buf) < 0) {
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ }
+ if (stat_buf.st_uid != me || !(stat_buf.st_mode & S_IFREG)
+ || stat_buf.st_nlink != 1 || stat_buf.st_mode & 077) {
+ return TKT_FIL_ACC;
+ }
+
+ /*
+ * Yes, we do uid twiddling here. It's not optimal, but some
+ * applications may expect that the ruid is what should really own
+ * the ticket file, e.g. setuid applications.
+ */
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
sfp = fopen(shmidname, "r"); /* only need read/write on the
actual tickets */
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
if (sfp == 0) {
switch(errno) {
case ENOENT:
***************
*** 207,216 ****
}
}
! /* lstat() and fstat() the file to check that the file we opened is the *
! * one we think it is, and to check ownership. */
! if ((fstat(sfp->_file, &stat_buffd) < 0) ||
! (lstat(shmidname, &stat_buf) < 0)) {
(void) close(fd);
fd = -1;
switch(errno) {
--- 261,271 ----
}
}
! /*
! * fstat() the file to check that the file we opened is the one we
! * think it is.
! */
! if (fstat(fileno(sfp), &stat_buffd) < 0) {
(void) close(fd);
fd = -1;
switch(errno) {
***************
*** 271,278 ****
--- 326,350 ----
tmp_shm_addr = krb_shm_addr;
#endif /* TKT_SHMEM */
+ if (lstat(tf_name, &stat_buf) < 0) {
+ switch (errno) {
+ case ENOENT:
+ return NO_TKT_FIL;
+ default:
+ return TKT_FIL_ACC;
+ }
+ }
+ if (stat_buf.st_uid != me || !(stat_buf.st_mode & S_IFREG)
+ || stat_buf.st_nlink != 1 || stat_buf.st_mode & 077) {
+ return TKT_FIL_ACC;
+ }
+
if (wflag) {
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
fd = open(tf_name, O_RDWR, 0600);
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
if (fd < 0) {
switch(errno) {
case ENOENT:
***************
*** 281,290 ****
return TKT_FIL_ACC;
}
}
! /* lstat() and fstat() the file to check that the file we opened is the *
! * one we think it is, and to check ownership. */
! if ((fstat(fd, &stat_buffd) < 0) ||
! (lstat(tf_name, &stat_buf) < 0)) {
(void) close(fd);
fd = -1;
switch(errno) {
--- 353,363 ----
return TKT_FIL_ACC;
}
}
! /*
! * fstat() the file to check that the file we opened is the
! * one we think it is, and to check ownership.
! */
! if (fstat(fd, &stat_buffd) < 0) {
(void) close(fd);
fd = -1;
switch(errno) {
***************
*** 327,333 ****
--- 400,410 ----
* for read-only operations and locked for shared access.
*/
+ if (me != metoo && do_seteuid(me) < 0)
+ return KFAILURE;
fd = open(tf_name, O_RDONLY, 0600);
+ if (me != metoo && do_seteuid(metoo) < 0)
+ return KFAILURE;
if (fd < 0) {
switch(errno) {
case ENOENT:
***************
*** 336,345 ****
return TKT_FIL_ACC;
}
}
! /* lstat() and fstat() the file to check that the file we opened is the *
! * one we think it is, and to check ownership. */
! if ((fstat(fd, &stat_buffd) < 0) ||
! (lstat(tf_name, &stat_buf) < 0)) {
(void) close(fd);
fd = -1;
switch(errno) {
--- 413,423 ----
return TKT_FIL_ACC;
}
}
! /*
! * fstat() the file to check that the file we opened is the one we
! * think it is, and to check ownership.
! */
! if (fstat(fd, &stat_buffd) < 0) {
(void) close(fd);
fd = -1;
switch(errno) {
For Red Hat:
ftp://updates.redhat.com/6.2/SRPMS/krb5-1.1.1-26.src.rpm
ftp://updates.redhat.com/6.2/alpha/krb5-configs-1.1.1-26.alpha.rpm
ftp://updates.redhat.com/6.2/alpha/krb5-devel-1.1.1-26.alpha.rpm
ftp://updates.redhat.com/6.2/alpha/krb5-libs-1.1.1-26.alpha.rpm
ftp://updates.redhat.com/6.2/alpha/krb5-server-1.1.1-26.alpha.rpm
ftp://updates.redhat.com/6.2/alpha/krb5-workstation-1.1.1-26.alpha.rpm
ftp://updates.redhat.com/6.2/i386/krb5-configs-1.1.1-26.i386.rpm
ftp://updates.redhat.com/6.2/i386/krb5-devel-1.1.1-26.i386.rpm
ftp://updates.redhat.com/6.2/i386/krb5-libs-1.1.1-26.i386.rpm
ftp://updates.redhat.com/6.2/i386/krb5-server-1.1.1-26.i386.rpm
ftp://updates.redhat.com/6.2/i386/krb5-workstation-1.1.1-26.i386.rpm
ftp://updates.redhat.com/6.2/sparc/krb5-configs-1.1.1-26.sparc.rpm
ftp://updates.redhat.com/6.2/sparc/krb5-devel-1.1.1-26.sparc.rpm
ftp://updates.redhat.com/6.2/sparc/krb5-libs-1.1.1-26.sparc.rpm
ftp://updates.redhat.com/6.2/sparc/krb5-server-1.1.1-26.sparc.rpm
ftp://updates.redhat.com/6.2/sparc/krb5-workstation-1.1.1-26.sparc.rpm
ftp://updates.redhat.com/7.0/SRPMS/krb5-1.2.2-3.src.rpm
ftp://updates.redhat.com/7.0/SRPMS/pam_krb5-1.29-1.src.rpm
ftp://updates.redhat.com/7.0/alpha/krb5-devel-1.2.2-3.alpha.rpm
ftp://updates.redhat.com/7.0/alpha/krb5-libs-1.2.2-3.alpha.rpm
ftp://updates.redhat.com/7.0/alpha/krb5-server-1.2.2-3.alpha.rpm
ftp://updates.redhat.com/7.0/alpha/krb5-workstation-1.2.2-3.alpha.rpm
ftp://updates.redhat.com/7.0/alpha/pam_krb5-1.29-1.alpha.rpm
ftp://updates.redhat.com/7.0/i386/krb5-devel-1.2.2-3.i386.rpm
ftp://updates.redhat.com/7.0/i386/krb5-libs-1.2.2-3.i386.rpm
ftp://updates.redhat.com/7.0/i386/krb5-server-1.2.2-3.i386.rpm
ftp://updates.redhat.com/7.0/i386/krb5-workstation-1.2.2-3.i386.rpm
ftp://updates.redhat.com/7.0/i386/pam_krb5-1.29-1.i386.rpm
For Immunix:
http://immunix.org/ImmunixOS/6.2/updates/RPMS/krb5-configs-1.1.1-26_StackGuard.i386.rpm
http://immunix.org/ImmunixOS/6.2/updates/RPMS/krb5-devel-1.1.1-26_StackGuard.i386.rpm
http://immunix.org/ImmunixOS/6.2/updates/RPMS/krb5-libs-1.1.1-26_StackGuard.i386.rpm
http://immunix.org/ImmunixOS/6.2/updates/RPMS/krb5-server-1.1.1-26_StackGuard.i386.rpm
http://immunix.org/ImmunixOS/6.2/updates/RPMS/krb5-workstation-1.1.1-26_StackGuard.i386.rpm
http://immunix.org/ImmunixOS/6.2/updates/SRPMS/krb5-1.1.1-26_StackGuard.src.rpm
http://immunix.org/ImmunixOS/7.0/updates/RPMS/krb5-devel-1.2.2-3_imnx.i386.rpm
http://immunix.org/ImmunixOS/7.0/updates/RPMS/krb5-libs-1.2.2-3_imnx.i386.rpm
http://immunix.org/ImmunixOS/7.0/updates/RPMS/krb5-server-1.2.2-3_imnx.i386.rpm
http://immunix.org/ImmunixOS/7.0/updates/RPMS/krb5-workstation-1.2.2-3_imnx.i386.rpm
http://immunix.org/ImmunixOS/7.0/updates/RPMS/pam_krb5-1.29-1_imnx.i386.rpm
http://immunix.org/ImmunixOS/7.0/updates/SRPMS/krb5-1.2.2-3_imnx.src.rpm
http://immunix.org/ImmunixOS/7.0/updates/SRPMS/pam_krb5-1.29-1_imnx.src.rpm