summaryrefslogtreecommitdiffstats
path: root/src/lib/krb4/tf_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb4/tf_util.c')
-rw-r--r--src/lib/krb4/tf_util.c118
1 files changed, 98 insertions, 20 deletions
diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c
index f77a2994a8..71706c0e19 100644
--- a/src/lib/krb4/tf_util.c
+++ b/src/lib/krb4/tf_util.c
@@ -1,20 +1,38 @@
/*
- * tf_util.c
+ * lib/krb4/tf_util.c
*
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
+ * Institute of Technology. All Rights Reserved.
*
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * 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 "mit-copyright.h"
-
#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,7 +62,6 @@ char *shmat();
#ifdef NEED_UTIMES
#include <sys/time.h>
-#include <unistd.h>
#ifdef __SCO__
#include <utime.h>
#endif
@@ -62,6 +79,20 @@ int utimes(path, times)
}
#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,7 +180,7 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
int rw;
{
int wflag;
- uid_t me= getuid();
+ uid_t me, metoo;
struct stat stat_buf, stat_buffd;
#ifdef TKT_SHMEM
char shmidname[MAXPATHLEN];
@@ -163,6 +194,7 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
}
me = getuid();
+ metoo = geteuid();
switch (rw) {
case R_TKT_FIL:
@@ -196,8 +228,30 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
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,10 +261,11 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
}
}
- /* 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)) {
+ /*
+ * 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,8 +326,25 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
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,10 +353,11 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
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)) {
+ /*
+ * 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,7 +400,11 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
* 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,10 +413,11 @@ KRB5_DLLIMP int KRB5_CALLCONV tf_init(tf_name, rw)
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)) {
+ /*
+ * 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) {