diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index e53bfc7452..aea2171cdf 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -1,5 +1,5 @@ @@ -98,6 +98,7 @@ Complete list of usable sgml source files in this directory. + diff --git a/doc/src/sgml/ref/set_session_auth.sgml b/doc/src/sgml/ref/set_session_auth.sgml new file mode 100644 index 0000000000..ba3ec6fb54 --- /dev/null +++ b/doc/src/sgml/ref/set_session_auth.sgml @@ -0,0 +1,103 @@ + + + + 2001-04-21 + + + + SET SESSION AUTHORIZATION + SQL - Language Statements + + + + SET SESSION AUTHORIZATION + Set the session user identifier and the current user identifier + of the current SQL-session context + + + + +SET SESSION AUTHORIZATION 'username' + + + + + Description + + + This command sets the session user identifier and the current user + identifer of the current SQL-session context to be + username. + + + + The session user identifier is initially set to be the (possibly + authenticated) user name provided by the client. The current user + identifier is normally equal to the session user identifier, but + may change temporarily in the context of setuid + functions and similar mechanisms. The current user identifer is + relevant for permission checking. + + + + Execution of this command is only permitted if the initial session + user (the authenticated user) had the + superuser privilege. This permission is kept for the duration of a + connection; for example, it is possible to temporarily become an + unprivileged user and later switch back to become a superuser. + + + + + Examples + + +SELECT SESSION_USER, CURRENT_USER; + current_user | session_user +--------------+-------------- + peter | peter + +SET SESSION AUTHORIZATION 'paul'; + +SELECT SESSION_USER, CURRENT_USER; + current_user | session_user +--------------+-------------- + paul | paul + + + + + Compatibility + + SQL99 + + + SQL99 allows some other expressions to appear in place of the + literal username which are not important in + practice. PostgreSQL allows identifier + syntax ("username"), which SQL does not. SQL + does not allow this command during a transaction; + PostgreSQL does not make + this restriction because there is no reason to. The + privileges necessary to execute this command are left + implementation-defined by the standard. + + + + + diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml index 9a977a6515..57dcc7ed28 100644 --- a/doc/src/sgml/reference.sgml +++ b/doc/src/sgml/reference.sgml @@ -1,5 +1,5 @@ @@ -84,6 +84,7 @@ PostgreSQL Reference Manual &selectInto; &set; &setConstraints; + &setSessionAuth; &setTransaction; &show; &truncate; @@ -131,7 +132,6 @@ Disable this chapter until we have more functions documented. &dropuser; &ecpgRef; &pgAccess; - &pgAdmin; &pgConfig; &pgDump; &pgDumpall; diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 420913a0e4..eb43be8f3f 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.47 2001/03/29 19:03:57 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.48 2001/05/08 21:06:42 petere Exp $ * *------------------------------------------------------------------------- */ @@ -721,6 +721,8 @@ SetPGVariable(const char *name, const char *value) parse_server_encoding(mvalue); else if (strcasecmp(name, "seed") == 0) parse_random_seed(mvalue); + else if (strcasecmp(name, "session_authorization") == 0) + SetSessionAuthorization(value); else SetConfigOption(name, value, superuser() ? PGC_SUSET : PGC_USERSET); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 40c379aca5..0f419edb17 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.223 2001/05/07 00:43:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.224 2001/05/08 21:06:42 petere Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -259,7 +259,7 @@ static void doNegateFloat(Value *v); %type Iconst %type Sconst, comment_text -%type UserId, opt_boolean, var_value, zone_value +%type UserId, opt_boolean, var_value, zone_value, Ident_or_Sconst %type ColId, ColLabel, TokenId %type TableConstraint @@ -292,7 +292,7 @@ static void doNegateFloat(Value *v); */ /* Keywords (in SQL92 reserved words) */ -%token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC, AT, +%token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC, AT, AUTHORIZATION, BEGIN_TRANS, BETWEEN, BOTH, BY, CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COALESCE, COLLATE, COLUMN, COMMIT, @@ -761,6 +761,13 @@ VariableSetStmt: SET ColId TO var_value n->value = $3; $$ = (Node *) n; } + | SET SESSION AUTHORIZATION Ident_or_Sconst + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->name = "session_authorization"; + n->value = $4; + $$ = (Node *) n; + } ; opt_level: READ COMMITTED { $$ = "committed"; } @@ -837,6 +844,10 @@ opt_encoding: Sconst { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; +Ident_or_Sconst: IDENT { $$ = $1; } + | SCONST { $$ = $1; } + + VariableShowStmt: SHOW ColId { VariableShowStmt *n = makeNode(VariableShowStmt); @@ -5459,6 +5470,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; } | AGGREGATE { $$ = "aggregate"; } | ALTER { $$ = "alter"; } | AT { $$ = "at"; } + | AUTHORIZATION { $$ = "authorization"; } | BACKWARD { $$ = "backward"; } | BEFORE { $$ = "before"; } | BEGIN_TRANS { $$ = "begin"; } diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 8ab19f86ae..6064ca8a8f 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.91 2001/05/07 00:43:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.92 2001/05/08 21:06:43 petere Exp $ * *------------------------------------------------------------------------- */ @@ -44,6 +44,7 @@ static ScanKeyword ScanKeywords[] = { {"as", AS}, {"asc", ASC}, {"at", AT}, + {"authorization", AUTHORIZATION}, {"backward", BACKWARD}, {"before", BEFORE}, {"begin", BEGIN_TRANS}, diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 33b9e11203..a07eae5129 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.65 2001/04/16 02:42:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.66 2001/05/08 21:06:43 petere Exp $ * *------------------------------------------------------------------------- */ @@ -354,6 +354,7 @@ convertstr(unsigned char *buff, int len, int dest) static Oid CurrentUserId = InvalidOid; static Oid SessionUserId = InvalidOid; +static bool AuthenticatedUserIsSuperuser = false; /* * This function is relevant for all privilege checks. @@ -397,7 +398,7 @@ SetSessionUserId(Oid newid) void -SetSessionUserIdFromUserName(const char *username) +InitializeSessionUserId(const char *username) { HeapTuple userTup; @@ -407,6 +408,9 @@ SetSessionUserIdFromUserName(const char *username) */ AssertState(!IsBootstrapProcessingMode()); + /* call only once */ + AssertState(!OidIsValid(SessionUserId)); + userTup = SearchSysCache(SHADOWNAME, PointerGetDatum(username), 0, 0, 0); @@ -415,6 +419,29 @@ SetSessionUserIdFromUserName(const char *username) SetSessionUserId(((Form_pg_shadow) GETSTRUCT(userTup))->usesysid); + AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; + + ReleaseSysCache(userTup); +} + + + +void SetSessionAuthorization(const char * username) +{ + HeapTuple userTup; + + if (!AuthenticatedUserIsSuperuser) + elog(ERROR, "permission denied"); + + userTup = SearchSysCache(SHADOWNAME, + PointerGetDatum(username), + 0, 0, 0); + if (!HeapTupleIsValid(userTup)) + elog(ERROR, "user \"%s\" does not exist", username); + + SetSessionUserId(((Form_pg_shadow) GETSTRUCT(userTup))->usesysid); + SetUserId(((Form_pg_shadow) GETSTRUCT(userTup))->usesysid); + ReleaseSysCache(userTup); } diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index f877564866..70d835aa25 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.84 2001/04/21 18:29:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.85 2001/05/08 21:06:43 petere Exp $ * * *------------------------------------------------------------------------- @@ -341,7 +341,7 @@ InitPostgres(const char *dbname, const char *username) if (bootstrap) SetSessionUserId(geteuid()); else - SetSessionUserIdFromUserName(username); + InitializeSessionUserId(username); /* * Unless we are bootstrapping, double-check that InitMyDatabaseInfo() diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index ce2a6692b7..dd323162dd 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.31 2001/05/07 19:31:33 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.32 2001/05/08 21:06:43 petere Exp $ */ /*---------------------------------------------------------------------- @@ -201,7 +201,7 @@ psql_completion(char *text, int start, int end) /* these SET arguments are known in gram.y */ "CONSTRAINTS", "NAMES", - "SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL", + "SESSION", "TRANSACTION ISOLATION LEVEL", /* these are treated in backend/commands/variable.c */ "DateStyle", @@ -646,6 +646,22 @@ psql_completion(char *text, int start, int end) COMPLETE_WITH_LIST(constraint_list); } + /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */ + else if (strcasecmp(prev2_wd, "SET") == 0 && strcasecmp(prev_wd, "SESSION") == 0) + { + char *my_list[] = {"AUTHORIZATION", + "CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL", + NULL}; + + COMPLETE_WITH_LIST(my_list); + } + /* Complete SET SESSION AUTHORIZATION with username */ + else if (strcasecmp(prev3_wd, "SET") == 0 + && strcasecmp(prev2_wd, "SESSION") == 0 + && strcasecmp(prev_wd, "AUTHORIZATION") == 0) + { + COMPLETE_WITH_QUERY(Query_for_list_of_users); + } /* Complete SET with "TO" */ else if (strcasecmp(prev2_wd, "SET") == 0 && strcasecmp(prev4_wd, "UPDATE") != 0) diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 6f90355d76..e69fba4b87 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: miscadmin.h,v 1.83 2001/03/22 04:00:25 momjian Exp $ + * $Id: miscadmin.h,v 1.84 2001/05/08 21:06:43 petere Exp $ * * NOTES * some of the information in this file should be moved to @@ -208,7 +208,8 @@ extern Oid GetUserId(void); extern void SetUserId(Oid userid); extern Oid GetSessionUserId(void); extern void SetSessionUserId(Oid userid); -extern void SetSessionUserIdFromUserName(const char *username); +extern void InitializeSessionUserId(const char *username); +extern void SetSessionAuthorization(const char *username); extern void SetDataDir(const char *dir);