summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xtrans.c4
-rw-r--r--Xtransint.h2
-rw-r--r--Xtranssock.c2
-rw-r--r--Xtransutil.c119
4 files changed, 103 insertions, 24 deletions
diff --git a/Xtrans.c b/Xtrans.c
index 3912634..4c00875 100644
--- a/Xtrans.c
+++ b/Xtrans.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/lib/xtrans/Xtrans.c,v 1.1.4.3.4.1 2004/03/04 17:47:15 eich Exp $ */
+/* $XdotOrg: xc/lib/xtrans/Xtrans.c,v 1.3 2004/07/17 01:13:31 alanc Exp $ */
/* $Xorg: Xtrans.c,v 1.4 2001/02/09 02:04:06 xorgcvs Exp $ */
/*
@@ -1132,7 +1132,7 @@ TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret,
*partial = (*count_ret < complete_network_count());
PRMSG (5,
- "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n",
+ "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
*partial, *count_ret, complete_network_count());
if (*count_ret > 0)
diff --git a/Xtransint.h b/Xtransint.h
index 166a889..dad0d8a 100644
--- a/Xtransint.h
+++ b/Xtransint.h
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/lib/xtrans/Xtransint.h,v 1.1.4.3.4.1 2004/03/04 17:47:15 eich Exp $ */
+/* $XdotOrg: xc/lib/xtrans/Xtransint.h,v 1.2 2004/04/23 18:44:27 eich Exp $ */
/* $Xorg: Xtransint.h,v 1.4 2001/02/09 02:04:06 xorgcvs Exp $ */
/*
diff --git a/Xtranssock.c b/Xtranssock.c
index 83a7b91..4c18324 100644
--- a/Xtranssock.c
+++ b/Xtranssock.c
@@ -1,4 +1,4 @@
-/* $XdotOrg: xc/lib/xtrans/Xtranssock.c,v 1.1.4.6.2.1 2004/03/04 17:47:15 eich Exp $ */
+/* $XdotOrg: xc/lib/xtrans/Xtranssock.c,v 1.2 2004/04/23 18:44:27 eich Exp $ */
/* $Xorg: Xtranssock.c,v 1.11 2001/02/09 02:04:06 xorgcvs Exp $ */
/*
diff --git a/Xtransutil.c b/Xtransutil.c
index 865c20f..2432ba7 100644
--- a/Xtransutil.c
+++ b/Xtransutil.c
@@ -190,7 +190,7 @@ TRANS(ConvertAddress)(int *familyp, int *addrlenp, Xtransaddr **addrp)
*familyp=FamilyLocal;
break;
}
-#endif /* defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN*/
+#endif /* defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)*/
default:
@@ -501,31 +501,74 @@ is_numeric (char *str)
#define lstat(a,b) stat(a,b)
#endif
+#define FAIL_IF_NOMODE 1
+#define FAIL_IF_NOT_ROOT 2
+#define WARN_NO_ACCESS 4
+
+/*
+ * We make the assumption that when the 'sticky' (t) bit is requested
+ * it's not save if the directory has non-root ownership or the sticky
+ * bit cannot be set and fail.
+ */
static int
trans_mkdir(char *path, int mode)
{
struct stat buf;
- if (mkdir(path, mode) == 0) {
- chmod(path, mode);
- return 0;
- }
- /* If mkdir failed with EEXIST, test if it is a directory with
- the right modes, else fail */
- if (errno == EEXIST) {
- if (lstat(path, &buf) != 0) {
- PRMSG(1, "mkdir: (l)stat failed for %s (%d)\n",
+ if (lstat(path, &buf) != 0) {
+ if (errno != ENOENT) {
+ PRMSG(1, "mkdir: ERROR: (l)stat failed for %s (%d)\n",
path, errno, 0);
return -1;
}
+ /* Dir doesn't exist. Try to create it */
+
+ /*
+ * 'sticky' bit requested: assume application makes
+ * certain security implications. If effective user ID
+ * is != 0: fail as we may not be able to meet them.
+ */
+ if (geteuid() != 0) {
+ if (mode & 01000) {
+ PRMSG(1, "mkdir: ERROR: euid != 0,"
+ "directory %s will not be created.\n",
+ path, 0, 0);
+#ifdef FAIL_HARD
+ return -1;
+#endif
+ } else {
+ PRMSG(1, "mkdir: Cannot create %s with root ownership\n",
+ path, 0, 0);
+ }
+ }
+
+ if (mkdir(path, mode) == 0) {
+ if (chmod(path, mode)) {
+ PRMSG(1, "mkdir: ERROR: Mode of %s should be set to %04o\n",
+ path, mode, 0);
+#ifdef FAIL_HARD
+ return -1;
+#endif
+ }
+ } else {
+ PRMSG(1, "mkdir: ERROR: Cannot create %s\n",
+ path, 0, 0);
+ return -1;
+ }
+
+ return 0;
+
+ } else {
if (S_ISDIR(buf.st_mode)) {
int updateOwner = 0;
int updateMode = 0;
int updatedOwner = 0;
int updatedMode = 0;
+ int status = 0;
/* Check if the directory's ownership is OK. */
if (buf.st_uid != 0)
updateOwner = 1;
+
/*
* Check if the directory's mode is OK. An exact match isn't
* required, just a mode that isn't more permissive than the
@@ -533,9 +576,29 @@ trans_mkdir(char *path, int mode)
*/
if ((~mode) & 0077 & buf.st_mode)
updateMode = 1;
- if ((mode & 01000) &&
- (buf.st_mode & 0002) && !(buf.st_mode & 01000))
+
+ /*
+ * If the directory is not writeable not everybody may
+ * be able to create sockets. Therefore warn if mode
+ * cannot be fixed.
+ */
+ if ((~buf.st_mode) & 0022 & mode) {
updateMode = 1;
+ status |= WARN_NO_ACCESS;
+ }
+
+ /*
+ * If 'sticky' bit is requested fail if owner isn't root
+ * as we assume the caller makes certain security implications
+ */
+ if (mode & 01000) {
+ status |= FAIL_IF_NOT_ROOT;
+ if (!(buf.st_mode & 01000)) {
+ status |= FAIL_IF_NOMODE;
+ updateMode = 1;
+ }
+ }
+
#ifdef HAS_FCHOWN
/*
* If fchown(2) and fchmod(2) are available, try to correct the
@@ -547,7 +610,7 @@ trans_mkdir(char *path, int mode)
struct stat fbuf;
if ((fd = open(path, O_RDONLY)) != -1) {
if (fstat(fd, &fbuf) == -1) {
- PRMSG(1, "mkdir: fstat failed for %s (%d)\n",
+ PRMSG(1, "mkdir: ERROR: fstat failed for %s (%d)\n",
path, errno, 0);
return -1;
}
@@ -558,7 +621,7 @@ trans_mkdir(char *path, int mode)
if (!S_ISDIR(fbuf.st_mode) ||
buf.st_dev != fbuf.st_dev ||
buf.st_ino != fbuf.st_ino) {
- PRMSG(1, "mkdir: inode for %s changed\n",
+ PRMSG(1, "mkdir: ERROR: inode for %s changed\n",
path, 0, 0);
return -1;
}
@@ -570,23 +633,39 @@ trans_mkdir(char *path, int mode)
}
}
#endif
+
if (updateOwner && !updatedOwner) {
+#ifdef FAIL_HARD
+ if (status & FAIL_IF_NOT_ROOT) {
+ PRMSG(1, "mkdir: ERROR: Owner of %s must be set to root\n",
+ path, 0, 0);
+ return -1;
+ }
+#endif
PRMSG(1, "mkdir: Owner of %s should be set to root\n",
path, 0, 0);
-#if 0 && !defined(__CYGWIN__) && !defined(__DARWIN__)
- sleep(5);
-#endif
}
+
if (updateMode && !updatedMode) {
+#ifdef FAIL_HARD
+ if (status & FAIL_IF_NOMODE) {
+ PRMSG(1, "mkdir: ERROR: Mode of %s must be set to %04o\n",
+ path, mode, 0);
+ return -1;
+ }
+#endif
PRMSG(1, "mkdir: Mode of %s should be set to %04o\n",
path, mode, 0);
-#if 0 && !defined(__CYGWIN__) && !defined(__DARWIN__)
- sleep(5);
-#endif
+ if (status & WARN_NO_ACCESS) {
+ PRMSG(1, "mkdir: this may cause subsequent errors\n",
+ 0, 0, 0);
+ }
}
return 0;
}
+ return -1;
}
+
/* In all other cases, fail */
return -1;
}