OSDN Git Service

Accept SET SESSION AUTHORIZATION DEFAULT and RESET SESSION AUTHORIZATION
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 May 2002 19:47:30 +0000 (19:47 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 May 2002 19:47:30 +0000 (19:47 +0000)
to reset session userid to the originally-authenticated name.  Also,
relax SET SESSION AUTHORIZATION to allow specifying one's own username
even if one is not superuser, so as to avoid unnecessary error messages
when loading a pg_dump file that uses this command.  Per discussion from
several months ago.

doc/src/sgml/ref/set_session_auth.sgml
src/backend/commands/variable.c
src/backend/parser/gram.y
src/backend/utils/init/miscinit.c

index fa427c1..7cd0d7d 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/set_session_auth.sgml,v 1.4 2002/01/20 22:19:57 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/set_session_auth.sgml,v 1.5 2002/05/06 19:47:30 tgl Exp $ -->
 <refentry id="SQL-SET-SESSION-AUTHORIZATION">
  <docinfo>
   <date>2001-04-21</date>
@@ -16,7 +16,9 @@
 
  <refsynopsisdiv>
 <synopsis>
-SET SESSION AUTHORIZATION '<parameter>username</parameter>'
+SET SESSION AUTHORIZATION <parameter>username</parameter>
+SET SESSION AUTHORIZATION DEFAULT
+RESET SESSION AUTHORIZATION
 </synopsis>
  </refsynopsisdiv>
 
@@ -26,7 +28,11 @@ SET SESSION AUTHORIZATION '<parameter>username</parameter>'
   <para>
    This command sets the session user identifier and the current user
    identifier of the current SQL-session context to be
-   <parameter>username</parameter>.
+   <parameter>username</parameter>.  The user name may be written as
+   either an identifier or a string literal.
+   The session user identifier is valid 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.
   </para>
 
   <para>
@@ -39,12 +45,18 @@ SET SESSION AUTHORIZATION '<parameter>username</parameter>'
   </para>
 
   <para>
-   Execution of this command is only permitted if the initial session
+   The session user identifier may be changed only if the initial session
    user (the <firstterm>authenticated user</firstterm>) 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.
+   superuser privilege.  Otherwise, the command is accepted only if it
+   specifies the authenticated username.
   </para>
+
+  <para>
+   The <literal>DEFAULT</> and <literal>RESET</> forms reset the session
+   and current user identifiers to be the originally authenticated user
+   name.  These forms are always accepted.
+  </para>
+
  </refsect1>
 
  <refsect1>
index 301a3c8..de42538 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.65 2002/04/22 15:13:53 thomas Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.66 2002/05/06 19:47:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -815,6 +815,15 @@ reset_server_encoding(void)
 }
 
 
+static bool
+show_session_authorization(void)
+{
+       elog(INFO, "Current session authorization is '%s'",
+                GetUserName(GetSessionUserId()));
+       return TRUE;
+}
+
+
 
 /* SetPGVariable()
  * Dispatcher for handling SET commands.
@@ -902,6 +911,8 @@ GetPGVariable(const char *name)
                show_server_encoding();
        else if (strcasecmp(name, "seed") == 0)
                show_random_seed();
+       else if (strcasecmp(name, "session_authorization") == 0)
+               show_session_authorization();
        else if (strcasecmp(name, "all") == 0)
        {
                ShowAllGUCConfig();
@@ -935,6 +946,8 @@ ResetPGVariable(const char *name)
                reset_server_encoding();
        else if (strcasecmp(name, "seed") == 0)
                reset_random_seed();
+       else if (strcasecmp(name, "session_authorization") == 0)
+               SetSessionAuthorization(NULL);
        else if (strcasecmp(name, "all") == 0)
        {
                reset_random_seed();
@@ -942,6 +955,7 @@ ResetPGVariable(const char *name)
                reset_client_encoding();
                reset_datestyle();
                reset_timezone();
+               /* should we reset session authorization here? */
 
                ResetAllOptions(false);
        }
index 1d1b7a7..258a11c 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.312 2002/05/03 00:32:16 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.313 2002/05/06 19:47:30 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -281,7 +281,7 @@ static void doNegateFloat(Value *v);
 %type <ival>   Iconst
 %type <str>            Sconst, comment_text
 %type <str>            UserId, opt_boolean, ColId_or_Sconst
-%type <list>   var_list
+%type <list>   var_list, var_list_or_default
 %type <str>            ColId, ColLabel, type_name
 %type <node>   var_value, zone_value
 
@@ -833,14 +833,14 @@ schema_stmt: CreateStmt
  *
  *****************************************************************************/
 
-VariableSetStmt:  SET ColId TO var_list
+VariableSetStmt:  SET ColId TO var_list_or_default
                                {
                                        VariableSetStmt *n = makeNode(VariableSetStmt);
                                        n->name  = $2;
                                        n->args = $4;
                                        $$ = (Node *) n;
                                }
-               | SET ColId '=' var_list
+               | SET ColId '=' var_list_or_default
                                {
                                        VariableSetStmt *n = makeNode(VariableSetStmt);
                                        n->name  = $2;
@@ -884,14 +884,25 @@ VariableSetStmt:  SET ColId TO var_list
                                        n->args = makeList1(makeStringConst($4, NULL));
                                        $$ = (Node *) n;
                                }
+               | SET SESSION AUTHORIZATION DEFAULT
+                               {
+                                       VariableSetStmt *n = makeNode(VariableSetStmt);
+                                       n->name = "session_authorization";
+                                       n->args = NIL;
+                                       $$ = (Node *) n;
+                               }
+               ;
+
+var_list_or_default:  var_list
+                               { $$ = $1; }
+               | DEFAULT
+                               { $$ = NIL; }
                ;
 
 var_list:  var_value
                                {       $$ = makeList1($1); }
                | var_list ',' var_value
                                {       $$ = lappend($1, $3); }
-               | DEFAULT
-                               { $$ = NIL; }
                ;
 
 var_value:  opt_boolean
@@ -1017,6 +1028,12 @@ VariableResetStmt:       RESET ColId
                                        n->name  = "XactIsoLevel";
                                        $$ = (Node *) n;
                                }
+               | RESET SESSION AUTHORIZATION
+                               {
+                                       VariableResetStmt *n = makeNode(VariableResetStmt);
+                                       n->name = "session_authorization";
+                                       $$ = (Node *) n;
+                               }
                | RESET ALL
                                {
                                        VariableResetStmt *n = makeNode(VariableResetStmt);
index 91c5a3e..4cc9d39 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.89 2002/05/05 00:03:29 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.90 2002/05/06 19:47:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -529,15 +529,17 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir)
 /* ----------------------------------------------------------------
  *     User ID things
  *
- * The session user is determined at connection start and never
- * changes.  The current user may change when "setuid" functions
+ * The authenticated user is determined at connection start and never
+ * changes.  The session user can be changed only by SET SESSION
+ * AUTHORIZATION.  The current user may change when "setuid" functions
  * are implemented.  Conceptually there is a stack, whose bottom
  * is the session user.  You are yourself responsible to save and
  * restore the current user id if you need to change it.
  * ----------------------------------------------------------------
  */
-static Oid     CurrentUserId = InvalidOid;
+static Oid     AuthenticatedUserId = InvalidOid;
 static Oid     SessionUserId = InvalidOid;
+static Oid     CurrentUserId = InvalidOid;
 
 static bool AuthenticatedUserIsSuperuser = false;
 
@@ -588,6 +590,7 @@ InitializeSessionUserId(const char *username)
        HeapTuple       userTup;
        Datum           datum;
        bool            isnull;
+       Oid                     usesysid;
 
        /*
         * Don't do scans if we're bootstrapping, none of the system catalogs
@@ -596,7 +599,7 @@ InitializeSessionUserId(const char *username)
        AssertState(!IsBootstrapProcessingMode());
 
        /* call only once */
-       AssertState(!OidIsValid(SessionUserId));
+       AssertState(!OidIsValid(AuthenticatedUserId));
 
        userTup = SearchSysCache(SHADOWNAME,
                                                         PointerGetDatum(username),
@@ -604,10 +607,14 @@ InitializeSessionUserId(const char *username)
        if (!HeapTupleIsValid(userTup))
                elog(FATAL, "user \"%s\" does not exist", username);
 
-       SetSessionUserId(((Form_pg_shadow) GETSTRUCT(userTup))->usesysid);
+       usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
 
+       AuthenticatedUserId = usesysid;
        AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
 
+       SetSessionUserId(usesysid);     /* sets CurrentUserId too */
+
+
        /*
         * Set up user-specific configuration variables.  This is a good
         * place to do it so we don't have to read pg_shadow twice during
@@ -633,25 +640,36 @@ InitializeSessionUserIdStandalone(void)
        AssertState(!IsUnderPostmaster);
 
        /* call only once */
-       AssertState(!OidIsValid(SessionUserId));
+       AssertState(!OidIsValid(AuthenticatedUserId));
 
-       SetSessionUserId(BOOTSTRAP_USESYSID);
+       AuthenticatedUserId = BOOTSTRAP_USESYSID;
        AuthenticatedUserIsSuperuser = true;
+
+       SetSessionUserId(BOOTSTRAP_USESYSID);
 }
 
 
 /*
  * Change session auth ID while running
+ *
+ * Only a superuser may set auth ID to something other than himself.
+ *
+ * username == NULL implies reset to default (AuthenticatedUserId).
  */
 void
 SetSessionAuthorization(const char *username)
 {
-       int32           userid;
-
-       if (!AuthenticatedUserIsSuperuser)
-               elog(ERROR, "permission denied");
+       Oid             userid;
 
-       userid = get_usesysid(username);
+       if (username == NULL)
+               userid = AuthenticatedUserId;
+       else
+       {
+               userid = get_usesysid(username);
+               if (userid != AuthenticatedUserId &&
+                       !AuthenticatedUserIsSuperuser)
+                       elog(ERROR, "permission denied");
+       }
 
        SetSessionUserId(userid);
        SetUserId(userid);