diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index d14a123da0..05efc50566 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ @@ -1190,6 +1190,26 @@ env PGOPTIONS='-c geqo=off' psql + + DB_USER_NAMESPACE (boolean) + + + This allows per-database user names. You can create users as + username@dbname. When username is passed by the client, + @ and the database name is appended to the user name and + that database-specific user name is looked up by the server. + When creating user names containing @, you will need + to quote the user name. + + + With this option enabled, you can still create ordinary global + users. Simply append @ when specifying the user name + in the client. The @ will be stripped off and looked up + by the server. + + + + deadlock diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 2168ddf937..83f7cb10c2 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.82 2002/06/20 20:29:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.83 2002/08/18 03:03:25 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -117,7 +117,7 @@ pg_krb4_recvauth(Port *port) version, PG_KRB4_VERSION); return STATUS_ERROR; } - if (strncmp(port->user, auth_data.pname, SM_USER) != 0) + 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,7 +290,7 @@ pg_krb5_recvauth(Port *port) } kusername = pg_an_to_ln(kusername); - if (strncmp(port->user, kusername, SM_USER)) + if (strncmp(port->user, kusername, SM_DATABASE_USER)) { elog(LOG, "pg_krb5_recvauth: user name \"%s\" != krb5 name \"%s\"", port->user, kusername); diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index f67a8b64a3..bc8b859f30 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.284 2002/08/17 15:12:06 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.285 2002/08/18 03:03:25 momjian Exp $ * * NOTES * @@ -116,7 +116,6 @@ sigset_t UnBlockSig, BlockSig, AuthBlockSig; - #else int UnBlockSig, BlockSig, @@ -191,6 +190,8 @@ int CheckPointTimeout = 300; bool HostnameLookup; /* for ps display */ bool ShowPortNumber; bool Log_connections = false; +bool Db_user_namespace = false; + /* Startup/shutdown state */ static pid_t StartupPID = 0, @@ -1155,6 +1156,26 @@ ProcessStartupPacket(Port *port, bool SSLdone) if (port->user[0] == '\0') elog(FATAL, "no PostgreSQL user name specified in startup packet"); + if (Db_user_namespace) + { + /* + * If user@, it is a global user, remove '@'. + * We only want to do this if there is an '@' at the end and no + * earlier in the user string or they may fake as a local user + * of another database attaching to this database. + */ + if (strchr(port->user, '@') == port->user + strlen(port->user)-1) + *strchr(port->user, '@') = '\0'; + else + { + /* Append '@' and dbname */ + char hold_user[SM_DATABASE_USER+1]; + snprintf(hold_user, SM_DATABASE_USER+1, "%s@%s", port->user, + port->database); + 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. @@ -2581,11 +2602,10 @@ CreateOptsFile(int argc, char *argv[]) if (FindExec(fullprogname, argv[0], "postmaster") < 0) return false; - filename = palloc(strlen(DataDir) + 20); + filename = palloc(strlen(DataDir) + 17); sprintf(filename, "%s/postmaster.opts", DataDir); - fp = fopen(filename, "w"); - if (fp == NULL) + if ((fp = fopen(filename, "w")) == NULL) { postmaster_error("cannot create file %s: %s", filename, strerror(errno)); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 3cfa84191c..a759b3f527 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -5,7 +5,7 @@ * command, configuration file, and command line options. * See src/backend/utils/misc/README for more information. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.82 2002/08/15 02:51:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.83 2002/08/18 03:03:25 momjian Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut . @@ -483,6 +483,10 @@ static struct config_bool { "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 diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index c9511ad7fb..da45660612 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -113,7 +113,6 @@ # # Message display # - #server_min_messages = notice # Values, in order of decreasing detail: # debug5, debug4, debug3, debug2, debug1, # info, notice, warning, error, log, fatal, @@ -201,3 +200,4 @@ #sql_inheritance = true #transform_null_equals = false #statement_timeout = 0 # 0 is disabled +#db_user_namespace = false diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h index 3dc0a6f4cd..1a2382026c 100644 --- a/src/include/libpq/libpq-be.h +++ b/src/include/libpq/libpq-be.h @@ -11,7 +11,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-be.h,v 1.32 2002/06/20 20:29:49 momjian Exp $ + * $Id: libpq-be.h,v 1.33 2002/08/18 03:03:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -59,7 +59,7 @@ typedef struct Port ProtocolVersion proto; char database[SM_DATABASE + 1]; - char user[SM_USER + 1]; + char user[SM_DATABASE_USER + 1]; char options[SM_OPTIONS + 1]; char tty[SM_TTY + 1]; char auth_arg[MAX_AUTH_ARG]; diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index e215e8a7f0..f0ea4e3594 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pqcomm.h,v 1.65 2002/08/12 14:35:26 tgl Exp $ + * $Id: pqcomm.h,v 1.66 2002/08/18 03:03:26 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -114,6 +114,8 @@ typedef uint32 PacketLen; #define SM_DATABASE 64 /* SM_USER should be the same size as the others. bjm 2002-06-02 */ #define SM_USER 32 +/* We append database name if db_user_namespace true. */ +#define SM_DATABASE_USER (SM_DATABASE+SM_USER+1) /* +1 for @ */ #define SM_OPTIONS 64 #define SM_UNUSED 64 #define SM_TTY 64 @@ -124,12 +126,14 @@ typedef struct StartupPacket { ProtocolVersion protoVersion; /* Protocol version */ char database[SM_DATABASE]; /* Database name */ + /* Db_user_namespace appends 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. */