Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/runtime.sgml,v
retrieving revision 1.124
diff -c -r1.124 runtime.sgml
*** doc/src/sgml/runtime.sgml 12 Aug 2002 00:36:11 -0000 1.124
--- doc/src/sgml/runtime.sgml 14 Aug 2002 01:30:15 -0000
***************
*** 1191,1196 ****
--- 1191,1208 ----
+ DB_USER_NAMESPACE (boolean)
+
+
+ Prepends the database name and a period to the username when
+ connecting to the database. This allows per-database users.
+ The user who ran initdb> is excluded from this
+ handling.
+
+
+
+
+
deadlock
timeout
Index: src/backend/libpq/auth.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/libpq/auth.c,v
retrieving revision 1.82
diff -c -r1.82 auth.c
*** src/backend/libpq/auth.c 20 Jun 2002 20:29:28 -0000 1.82
--- src/backend/libpq/auth.c 14 Aug 2002 01:30:15 -0000
***************
*** 117,123 ****
version, PG_KRB4_VERSION);
return STATUS_ERROR;
}
! if (strncmp(port->user, auth_data.pname, SM_USER) != 0)
{
elog(LOG, "pg_krb4_recvauth: name \"%s\" != \"%s\"",
port->user, auth_data.pname);
--- 117,123 ----
version, PG_KRB4_VERSION);
return STATUS_ERROR;
}
! if (strncmp(port->user, auth_data.pname, SM_DATABASE_USER) != 0)
{
elog(LOG, "pg_krb4_recvauth: name \"%s\" != \"%s\"",
port->user, auth_data.pname);
***************
*** 290,296 ****
}
kusername = pg_an_to_ln(kusername);
! if (strncmp(port->user, kusername, SM_USER))
{
elog(LOG, "pg_krb5_recvauth: user name \"%s\" != krb5 name \"%s\"",
port->user, kusername);
--- 290,296 ----
}
kusername = pg_an_to_ln(kusername);
! if (strncmp(port->user, kusername, SM_DATABASE_USER))
{
elog(LOG, "pg_krb5_recvauth: user name \"%s\" != krb5 name \"%s\"",
port->user, kusername);
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.283
diff -c -r1.283 postmaster.c
*** src/backend/postmaster/postmaster.c 10 Aug 2002 20:29:18 -0000 1.283
--- src/backend/postmaster/postmaster.c 14 Aug 2002 01:30:17 -0000
***************
*** 116,122 ****
sigset_t UnBlockSig,
BlockSig,
AuthBlockSig;
-
#else
int UnBlockSig,
BlockSig,
--- 116,121 ----
***************
*** 191,196 ****
--- 190,197 ----
bool HostnameLookup; /* for ps display */
bool ShowPortNumber;
bool Log_connections = false;
+ bool Db_user_namespace = false;
+
/* Startup/shutdown state */
static pid_t StartupPID = 0,
***************
*** 208,213 ****
--- 209,216 ----
bool ClientAuthInProgress = false; /* T during new-client authentication */
+ static char InstallUser[SM_USER+1];
+
/*
* State for assigning random salts and cancel keys.
* Also, the global MyCancelKey passes the cancel key assigned to a given
***************
*** 258,263 ****
--- 261,267 ----
static void SignalChildren(int signal);
static int CountChildren(void);
static bool CreateOptsFile(int argc, char *argv[]);
+ static bool GetInstallUser(void);
static pid_t SSDataBase(int xlop);
void
postmaster_error(const char *fmt,...)
***************
*** 690,695 ****
--- 694,702 ----
if (!CreateOptsFile(argc, argv))
ExitPostmaster(1);
+ if (!GetInstallUser())
+ ExitPostmaster(1);
+
/*
* Set up signal handlers for the postmaster process.
*
***************
*** 1161,1166 ****
--- 1168,1182 ----
if (port->user[0] == '\0')
elog(FATAL, "no PostgreSQL user name specified in startup packet");
+ /* Prefix database name for per-db user namespace */
+ if (Db_user_namespace && strcmp(port->user, InstallUser))
+ {
+ char hold_user[SM_DATABASE_USER];
+ snprintf(hold_user, SM_DATABASE_USER, "%s.%s", port->database,
+ port->user);
+ strcpy(port->user, hold_user);
+ }
+
/*
* If we're going to reject the connection due to database state, say
* so now instead of wasting cycles on an authentication exchange.
***************
*** 2587,2597 ****
if (FindExec(fullprogname, argv[0], "postmaster") < 0)
return false;
! filename = palloc(strlen(DataDir) + 20);
sprintf(filename, "%s/postmaster.opts", DataDir);
! fp = fopen(filename, "w");
! if (fp == NULL)
{
postmaster_error("cannot create file %s: %s",
filename, strerror(errno));
--- 2603,2612 ----
if (FindExec(fullprogname, argv[0], "postmaster") < 0)
return false;
! filename = palloc(strlen(DataDir) + 17);
sprintf(filename, "%s/postmaster.opts", DataDir);
! if ((fp = fopen(filename, "w")) == NULL)
{
postmaster_error("cannot create file %s: %s",
filename, strerror(errno));
***************
*** 2614,2619 ****
--- 2629,2669 ----
return true;
}
+ /*
+ * Load install user so db_user_namespace can skip it.
+ */
+ static bool
+ GetInstallUser(void)
+ {
+ char *filename;
+ FILE *fp;
+
+ filename = palloc(strlen(DataDir) + 14);
+ sprintf(filename, "%s/PG_INSTALLER", DataDir);
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ postmaster_error("cannot open file %s: %s",
+ filename, strerror(errno));
+ return false;
+ }
+
+ if (fgets(InstallUser, SM_USER+1, fp) == NULL)
+ {
+ postmaster_error("cannot read file %s: %s",
+ filename, strerror(errno));
+ return false;
+ }
+
+ /* Trim off trailing newline */
+ if (strchr(InstallUser, '\n') != NULL)
+ *strchr(InstallUser, '\n') = '\0';
+
+ fclose(fp);
+ return true;
+ }
+
+
/*
* This should be used only for reporting "interactive" errors (ie, errors
* during startup. Once the postmaster is launched, use elog.
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v
retrieving revision 1.79
diff -c -r1.79 guc.c
*** src/backend/utils/misc/guc.c 12 Aug 2002 00:36:11 -0000 1.79
--- src/backend/utils/misc/guc.c 14 Aug 2002 01:30:20 -0000
***************
*** 482,487 ****
--- 482,491 ----
{ "transform_null_equals", PGC_USERSET }, &Transform_null_equals,
false, NULL, NULL
},
+ {
+ { "db_user_namespace", PGC_SIGHUP }, &Db_user_namespace,
+ false, NULL, NULL
+ },
{
{ NULL, 0 }, NULL, false, NULL, NULL
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.44
diff -c -r1.44 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample 12 Aug 2002 00:36:12 -0000 1.44
--- src/backend/utils/misc/postgresql.conf.sample 14 Aug 2002 01:30:20 -0000
***************
*** 113,119 ****
#
# Message display
#
-
#server_min_messages = notice # Values, in order of decreasing detail:
# debug5, debug4, debug3, debug2, debug1,
# info, notice, warning, error, log, fatal,
--- 113,118 ----
***************
*** 201,203 ****
--- 200,203 ----
#sql_inheritance = true
#transform_null_equals = false
#statement_timeout = 0 # 0 is disabled
+ #db_user_namespace = false
Index: src/bin/initdb/initdb.sh
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.sh,v
retrieving revision 1.165
diff -c -r1.165 initdb.sh
*** src/bin/initdb/initdb.sh 8 Aug 2002 19:39:05 -0000 1.165
--- src/bin/initdb/initdb.sh 14 Aug 2002 01:30:20 -0000
***************
*** 603,608 ****
--- 603,613 ----
# Top level PG_VERSION is checked by bootstrapper, so make it first
echo "$short_version" > "$PGDATA/PG_VERSION" || exit_nicely
+ # Top level PG_INSTALLER is used by db_user_namespace to prevent username
+ # mapping just for the install user.
+ echo "$POSTGRES_SUPERUSERNAME" > "$PGDATA/PG_INSTALLER" || exit_nicely
+
+
cat "$POSTGRES_BKI" \
| sed -e "s/POSTGRES/$POSTGRES_SUPERUSERNAME/g" \
-e "s/ENCODING/$MULTIBYTEID/g" \
Index: src/include/libpq/libpq-be.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/libpq/libpq-be.h,v
retrieving revision 1.32
diff -c -r1.32 libpq-be.h
*** src/include/libpq/libpq-be.h 20 Jun 2002 20:29:49 -0000 1.32
--- src/include/libpq/libpq-be.h 14 Aug 2002 01:30:20 -0000
***************
*** 59,65 ****
ProtocolVersion proto;
char database[SM_DATABASE + 1];
! char user[SM_USER + 1];
char options[SM_OPTIONS + 1];
char tty[SM_TTY + 1];
char auth_arg[MAX_AUTH_ARG];
--- 59,65 ----
ProtocolVersion proto;
char database[SM_DATABASE + 1];
! char user[SM_DATABASE_USER + 1];
char options[SM_OPTIONS + 1];
char tty[SM_TTY + 1];
char auth_arg[MAX_AUTH_ARG];
***************
*** 72,78 ****
SSL *ssl;
X509 *peer;
char peer_dn[128 + 1];
! char peer_cn[SM_USER + 1];
unsigned long count;
#endif
} Port;
--- 72,78 ----
SSL *ssl;
X509 *peer;
char peer_dn[128 + 1];
! char peer_cn[SM_DATABASE_USER + 1];
unsigned long count;
#endif
} Port;
Index: src/include/libpq/pqcomm.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/libpq/pqcomm.h,v
retrieving revision 1.65
diff -c -r1.65 pqcomm.h
*** src/include/libpq/pqcomm.h 12 Aug 2002 14:35:26 -0000 1.65
--- src/include/libpq/pqcomm.h 14 Aug 2002 01:30:20 -0000
***************
*** 114,119 ****
--- 114,121 ----
#define SM_DATABASE 64
/* SM_USER should be the same size as the others. bjm 2002-06-02 */
#define SM_USER 32
+ /* We prepend database name if db_user_namespace true. */
+ #define SM_DATABASE_USER (SM_DATABASE+SM_USER)
#define SM_OPTIONS 64
#define SM_UNUSED 64
#define SM_TTY 64
***************
*** 124,135 ****
--- 126,139 ----
{
ProtocolVersion protoVersion; /* Protocol version */
char database[SM_DATABASE]; /* Database name */
+ /* Db_user_namespace prepends dbname */
char user[SM_USER]; /* User name */
char options[SM_OPTIONS]; /* Optional additional args */
char unused[SM_UNUSED]; /* Unused */
char tty[SM_TTY]; /* Tty for debug output */
} StartupPacket;
+ extern bool Db_user_namespace;
/* These are the authentication requests sent by the backend. */