From d1bfa6c72e8087de21a2a2fd0c9c0b7da9e8fc20 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 1 Nov 2000 21:14:03 +0000
Subject: [PATCH] Add runtime configuration options to control permission bits
 and group owner of unix socket.

---
 doc/src/sgml/runtime.sgml           | 53 +++++++++++++++++++++++-
 src/backend/libpq/pqcomm.c          | 64 ++++++++++++++++++++++++++++-
 src/backend/postmaster/postmaster.c |  6 +--
 src/backend/utils/misc/guc.c        | 11 ++++-
 src/include/libpq/pqcomm.h          | 10 ++++-
 5 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 31810dc19d8..7544a6489ce 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.30 2000/10/20 14:00:49 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.31 2000/11/01 21:14:00 petere Exp $
 -->
 
 <Chapter Id="runtime">
@@ -1031,6 +1031,57 @@ env PGOPTIONS='--geqo=off' psql
        </para>
       </listitem>
      </varlistentry>
+
+     <varlistentry>
+      <term>UNIX_SOCKET_GROUP (<type>string</type>)</term>
+      <listitem>
+       <para>
+        Sets the group owner of the Unix domain socket.  (The owning
+        user of the socket is always the user that starts the
+        postmaster.)  In combination with the option
+        <option>UNIX_SOCKET_PERMISSIONS</option> this can be used as
+        an additional access control mechanism for this socket type.
+        By default this is the empty string, which uses the default
+        group for the current user.  This option can only be set at
+        server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>UNIX_SOCKET_PERMISSIONS (<type>integer</type>)</term>
+      <listitem>
+       <para>
+        Sets the access permissions of the Unix domain socket.  Unix
+        domain sockets use the usual Unix file system permission set.
+        The option value is expected to be an numeric mode
+        specification in the form accepted by the
+        <function>chmod</function> and <function>umask</function>
+        system calls.  (To use the customary octal format the number
+        must start with a <literal>0</literal> (zero).)
+       </para>
+
+       <para>
+        The default permissions are <literal>0777</literal>, meaning
+        anyone can connect.  Reasonable alternatives would be
+        <literal>0770</literal> (only user and group, see also under
+        <option>UNIX_SOCKET_GROUP</option>) and
+        <literal>0700</literal> (only user).  (Note that actually for
+        a Unix socket, only write permission matters and there is no
+        point in setting or revoking read or execute permissions.)
+       </para>
+
+       <para>
+        This access control mechanism is independent from the one
+        described in <xref linkend="client-authentication">.
+       </para>
+
+       <para>
+        This option can only be set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
     </variablelist>
    </para>
    </sect2>
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 0916d16c964..355144937a5 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -29,7 +29,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$Id: pqcomm.c,v 1.108 2000/10/23 14:48:50 momjian Exp $
+ *	$Id: pqcomm.c,v 1.109 2000/11/01 21:14:01 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -84,6 +85,13 @@
 #endif
 
 
+/*
+ * Configuration options
+ */
+int Unix_socket_permissions;
+char * Unix_socket_group;
+
+
 /*
  * Buffers for low-level I/O
  */
@@ -295,8 +303,60 @@ StreamServerPort(int family, unsigned short portName, int *fdP)
 	 */
 
 	*fdP = fd;
+
 	if (family == AF_UNIX)
-		chmod(sock_path, 0777);
+	{
+		Assert(Unix_socket_group);
+		if (Unix_socket_group[0] != '\0')
+		{
+			char *endptr;
+			unsigned long int val;
+			gid_t gid;
+
+			val = strtoul(Unix_socket_group, &endptr, 10);
+			if (*endptr == '\0')
+			{
+				/* numeric group id */
+				gid = val;
+			}
+			else
+			{
+				/* convert group name to id */
+				struct group *gr;
+
+				gr = getgrnam(Unix_socket_group);
+				if (!gr)
+				{
+					snprintf(PQerrormsg, PQERRORMSG_LENGTH,
+							 "FATAL:  no such group '%s'\n",
+							 Unix_socket_group);
+					fputs(PQerrormsg, stderr);
+					pqdebug("%s", PQerrormsg);
+					return STATUS_ERROR;
+				}
+				gid = gr->gr_gid;
+			}
+			if (chown(sock_path, -1, gid) == -1)
+			{
+				snprintf(PQerrormsg, PQERRORMSG_LENGTH,
+						 "FATAL:  could not set group of %s: %s\n",
+						 sock_path, strerror(errno));
+				fputs(PQerrormsg, stderr);
+				pqdebug("%s", PQerrormsg);
+				return STATUS_ERROR;
+			}
+		}
+
+		if (chmod(sock_path, Unix_socket_permissions) == -1)
+		{
+			snprintf(PQerrormsg, PQERRORMSG_LENGTH,
+					 "FATAL:  could not set permissions on %s: %s\n",
+					 sock_path, strerror(errno));
+			fputs(PQerrormsg, stderr);
+			pqdebug("%s", PQerrormsg);
+			return STATUS_ERROR;
+		}
+	}
 	return STATUS_OK;
 }
 
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index d74cbf9e84a..eb7daeb7dbe 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.176 2000/10/28 18:27:55 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.177 2000/11/01 21:14:02 petere Exp $
  *
  * NOTES
  *
@@ -588,7 +588,7 @@ PostmasterMain(int argc, char *argv[])
 		{
 			fprintf(stderr, "%s: cannot create INET stream port\n",
 					progname);
-			exit(1);
+			ExitPostmaster(1);
 		}
 	}
 
@@ -598,7 +598,7 @@ PostmasterMain(int argc, char *argv[])
 	{
 		fprintf(stderr, "%s: cannot create UNIX stream port\n",
 				progname);
-		exit(1);
+		ExitPostmaster(1);
 	}
 #endif
 	/* set up shared memory and semaphores */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9ed8f9c16d3..54d858c0ce3 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4,7 +4,7 @@
  * Support for grand unified configuration scheme, including SET
  * command, configuration file, and command line options.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.14 2000/10/11 17:58:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.15 2000/11/01 21:14:03 petere Exp $
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -22,6 +22,7 @@
 
 #include "commands/async.h"
 #include "libpq/auth.h"
+#include "libpq/pqcomm.h"
 #include "miscadmin.h"
 #include "optimizer/cost.h"
 #include "optimizer/geqo.h"
@@ -253,6 +254,9 @@ ConfigureNamesInt[] =
 	{"max_expr_depth",          PGC_USERSET,            &max_expr_depth,
 	 DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX},
 
+	{"unix_socket_permissions", PGC_POSTMASTER,         &Unix_socket_permissions,
+	 0777, 0000, 0777},
+
     {NULL, 0, NULL, 0, 0, 0}
 };
 
@@ -281,9 +285,12 @@ ConfigureNamesReal[] =
 static struct config_string
 ConfigureNamesString[] =
 {
-	{"krb_server_keyfile",        PGC_USERSET,       &pg_krb_server_keyfile,
+	{"krb_server_keyfile",        PGC_POSTMASTER,       &pg_krb_server_keyfile,
 	 PG_KRB_SRVTAB, NULL},
 
+	{"unix_socket_group",         PGC_POSTMASTER,       &Unix_socket_group,
+	 "", NULL},
+
 	{NULL, 0, NULL, NULL, NULL}
 };
 
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index dbe6761576e..bb64862922b 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pqcomm.h,v 1.42 2000/09/27 15:17:56 petere Exp $
+ * $Id: pqcomm.h,v 1.43 2000/11/01 21:14:03 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -169,4 +169,12 @@ typedef struct CancelRequestPacket
  */
 #define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679)
 
+
+/*
+ * Configuration options
+ */
+extern int Unix_socket_permissions;
+
+extern char * Unix_socket_group;
+
 #endif	 /* PQCOMM_H */
-- 
GitLab