mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Run pgindent, pgperltidy, and reformat-dat-files. This set of diffs is a bit larger than typical. We've updated to pg_bsd_indent 2.1.2, which properly indents variable declarations that have multi-line initialization expressions (the continuation lines are now indented one tab stop). We've also updated to perltidy version 20230309 and changed some of its settings, which reduces its desire to add whitespace to lines to make assignments etc. line up. Going forward, that should make for fewer random-seeming changes to existing code. Discussion: https://postgr.es/m/20230428092545.qfb3y5wcu4cm75ur@alvherre.pgsql
93 lines
2.9 KiB
C
93 lines
2.9 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* usercontext.c
|
|
* Convenience functions for running code as a different database user.
|
|
*
|
|
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* src/backend/utils/init/usercontext.c
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#include "postgres.h"
|
|
|
|
#include "miscadmin.h"
|
|
#include "utils/acl.h"
|
|
#include "utils/guc.h"
|
|
#include "utils/usercontext.h"
|
|
|
|
/*
|
|
* Temporarily switch to a new user ID.
|
|
*
|
|
* If the current user doesn't have permission to SET ROLE to the new user,
|
|
* an ERROR occurs.
|
|
*
|
|
* If the new user doesn't have permission to SET ROLE to the current user,
|
|
* SECURITY_RESTRICTED_OPERATION is imposed and a new GUC nest level is
|
|
* created so that any settings changes can be rolled back.
|
|
*/
|
|
void
|
|
SwitchToUntrustedUser(Oid userid, UserContext *context)
|
|
{
|
|
/* Get the current user ID and security context. */
|
|
GetUserIdAndSecContext(&context->save_userid,
|
|
&context->save_sec_context);
|
|
|
|
/* Check that we have sufficient privileges to assume the target role. */
|
|
if (!member_can_set_role(context->save_userid, userid))
|
|
ereport(ERROR,
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
errmsg("role \"%s\" cannot SET ROLE to \"%s\"",
|
|
GetUserNameFromId(context->save_userid, false),
|
|
GetUserNameFromId(userid, false))));
|
|
|
|
/*
|
|
* Try to prevent the user to which we're switching from assuming the
|
|
* privileges of the current user, unless they can SET ROLE to that user
|
|
* anyway.
|
|
*/
|
|
if (member_can_set_role(userid, context->save_userid))
|
|
{
|
|
/*
|
|
* Each user can SET ROLE to the other, so there's no point in
|
|
* imposing any security restrictions. Just let the user do whatever
|
|
* they want.
|
|
*/
|
|
SetUserIdAndSecContext(userid, context->save_sec_context);
|
|
context->save_nestlevel = -1;
|
|
}
|
|
else
|
|
{
|
|
int sec_context = context->save_sec_context;
|
|
|
|
/*
|
|
* This user can SET ROLE to the target user, but not the other way
|
|
* around, so protect ourselves against the target user by setting
|
|
* SECURITY_RESTRICTED_OPERATION to prevent certain changes to the
|
|
* session state. Also set up a new GUC nest level, so that we can
|
|
* roll back any GUC changes that may be made by code running as the
|
|
* target user, inasmuch as they could be malicious.
|
|
*/
|
|
sec_context |= SECURITY_RESTRICTED_OPERATION;
|
|
SetUserIdAndSecContext(userid, sec_context);
|
|
context->save_nestlevel = NewGUCNestLevel();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Switch back to the original user ID.
|
|
*
|
|
* If we created a new GUC nest level, also roll back any changes that were
|
|
* made within it.
|
|
*/
|
|
void
|
|
RestoreUserContext(UserContext *context)
|
|
{
|
|
if (context->save_nestlevel != -1)
|
|
AtEOXact_GUC(false, context->save_nestlevel);
|
|
SetUserIdAndSecContext(context->save_userid, context->save_sec_context);
|
|
}
|