Skip to content

Commit be8cebc

Browse files
committed
Prevent ALTER USER f RESET ALL from removing the settings that were put there
by a superuser -- "ALTER USER f RESET setting" already disallows removing such a setting. Apply the same treatment to ALTER DATABASE d RESET ALL when run by a database owner that's not superuser.
1 parent 92fc0db commit be8cebc

File tree

4 files changed

+124
-13
lines changed

4 files changed

+124
-13
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.223 2010/02/17 04:19:37 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.224 2010/03/25 14:44:33 alvherre Exp $ -->
22
<!--
33
Documentation of the system catalogs, directed toward PostgreSQL developers
44
-->
@@ -1188,12 +1188,6 @@
11881188
<entry>Password expiry time (only used for password authentication);
11891189
NULL if no expiration</entry>
11901190
</row>
1191-
1192-
<row>
1193-
<entry><structfield>rolconfig</structfield></entry>
1194-
<entry><type>text[]</type></entry>
1195-
<entry>Session defaults for run-time configuration variables</entry>
1196-
</row>
11971191
</tbody>
11981192
</tgroup>
11991193
</table>

src/backend/catalog/pg_db_role_setting.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1994, Regents of the University of California
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/backend/catalog/pg_db_role_setting.c,v 1.3 2010/02/26 02:00:37 momjian Exp $
9+
* $PostgreSQL: pgsql/src/backend/catalog/pg_db_role_setting.c,v 1.4 2010/03/25 14:44:33 alvherre Exp $
1010
*/
1111
#include "postgres.h"
1212

@@ -49,7 +49,8 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
4949
/*
5050
* There are three cases:
5151
*
52-
* - in RESET ALL, simply delete the pg_db_role_setting tuple (if any)
52+
* - in RESET ALL, request GUC to reset the settings array and update the
53+
* catalog if there's anything left, delete it otherwise
5354
*
5455
* - in other commands, if there's a tuple in pg_db_role_setting, update
5556
* it; if it ends up empty, delete it
@@ -60,7 +61,41 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
6061
if (setstmt->kind == VAR_RESET_ALL)
6162
{
6263
if (HeapTupleIsValid(tuple))
63-
simple_heap_delete(rel, &tuple->t_self);
64+
{
65+
ArrayType *new = NULL;
66+
Datum datum;
67+
bool isnull;
68+
69+
datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
70+
RelationGetDescr(rel), &isnull);
71+
72+
if (!isnull)
73+
new = GUCArrayReset(DatumGetArrayTypeP(datum));
74+
75+
if (new)
76+
{
77+
Datum repl_val[Natts_pg_db_role_setting];
78+
bool repl_null[Natts_pg_db_role_setting];
79+
bool repl_repl[Natts_pg_db_role_setting];
80+
HeapTuple newtuple;
81+
82+
memset(repl_repl, false, sizeof(repl_repl));
83+
84+
repl_val[Anum_pg_db_role_setting_setconfig - 1] =
85+
PointerGetDatum(new);
86+
repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
87+
repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
88+
89+
newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
90+
repl_val, repl_null, repl_repl);
91+
simple_heap_update(rel, &tuple->t_self, newtuple);
92+
93+
/* Update indexes */
94+
CatalogUpdateIndexes(rel, newtuple);
95+
}
96+
else
97+
simple_heap_delete(rel, &tuple->t_self);
98+
}
6499
}
65100
else if (HeapTupleIsValid(tuple))
66101
{

src/backend/utils/misc/guc.c

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Written by Peter Eisentraut <peter_e@gmx.net>.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.544 2010/03/21 00:17:59 petere Exp $
13+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.545 2010/03/25 14:44:33 alvherre Exp $
1414
*
1515
*--------------------------------------------------------------------
1616
*/
@@ -7099,7 +7099,7 @@ ParseLongOption(const char *string, char **name, char **value)
70997099

71007100

71017101
/*
7102-
* Handle options fetched from pg_database.datconfig, pg_authid.rolconfig,
7102+
* Handle options fetched from pg_db_role_setting.setconfig,
71037103
* pg_proc.proconfig, etc. Caller must specify proper context/source/action.
71047104
*
71057105
* The array parameter must be an array of TEXT (it must not be NULL).
@@ -7151,6 +7151,7 @@ ProcessGUCArray(ArrayType *array,
71517151
free(name);
71527152
if (value)
71537153
free(value);
7154+
pfree(s);
71547155
}
71557156
}
71567157

@@ -7285,6 +7286,7 @@ GUCArrayDelete(ArrayType *array, const char *name)
72857286
&& val[strlen(name)] == '=')
72867287
continue;
72877288

7289+
72887290
/* else add it to the output array */
72897291
if (newarray)
72907292
{
@@ -7307,6 +7309,85 @@ GUCArrayDelete(ArrayType *array, const char *name)
73077309
return newarray;
73087310
}
73097311

7312+
/*
7313+
* Given a GUC array, delete all settings from it that our permission
7314+
* level allows: if superuser, delete them all; if regular user, only
7315+
* those that are PGC_USERSET
7316+
*/
7317+
ArrayType *
7318+
GUCArrayReset(ArrayType *array)
7319+
{
7320+
ArrayType *newarray;
7321+
int i;
7322+
int index;
7323+
7324+
/* if array is currently null, nothing to do */
7325+
if (!array)
7326+
return NULL;
7327+
7328+
/* if we're superuser, we can delete everything */
7329+
if (superuser())
7330+
return NULL;
7331+
7332+
newarray = NULL;
7333+
index = 1;
7334+
7335+
for (i = 1; i <= ARR_DIMS(array)[0]; i++)
7336+
{
7337+
Datum d;
7338+
char *val;
7339+
char *eqsgn;
7340+
bool isnull;
7341+
struct config_generic *gconf;
7342+
7343+
d = array_ref(array, 1, &i,
7344+
-1 /* varlenarray */ ,
7345+
-1 /* TEXT's typlen */ ,
7346+
false /* TEXT's typbyval */ ,
7347+
'i' /* TEXT's typalign */ ,
7348+
&isnull);
7349+
7350+
if (isnull)
7351+
continue;
7352+
val = TextDatumGetCString(d);
7353+
7354+
eqsgn = strchr(val, '=');
7355+
*eqsgn = '\0';
7356+
7357+
gconf = find_option(val, false, WARNING);
7358+
if (!gconf)
7359+
continue;
7360+
7361+
/* note: superuser-ness was already checked above */
7362+
/* skip entry if OK to delete */
7363+
if (gconf->context == PGC_USERSET)
7364+
continue;
7365+
7366+
/* XXX do we need to worry about database owner? */
7367+
7368+
/* else add it to the output array */
7369+
if (newarray)
7370+
{
7371+
newarray = array_set(newarray, 1, &index,
7372+
d,
7373+
false,
7374+
-1 /* varlenarray */ ,
7375+
-1 /* TEXT's typlen */ ,
7376+
false /* TEXT's typbyval */ ,
7377+
'i' /* TEXT's typalign */ );
7378+
}
7379+
else
7380+
newarray = construct_array(&d, 1,
7381+
TEXTOID,
7382+
-1, false, 'i');
7383+
7384+
index++;
7385+
pfree(val);
7386+
}
7387+
7388+
return newarray;
7389+
}
7390+
73107391

73117392
/*
73127393
* assign_hook and show_hook subroutines

src/include/utils/guc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
88
* Written by Peter Eisentraut <peter_e@gmx.net>.
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.112 2010/01/26 16:33:40 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.113 2010/03/25 14:44:34 alvherre Exp $
1111
*--------------------------------------------------------------------
1212
*/
1313
#ifndef GUC_H
@@ -284,6 +284,7 @@ extern void ProcessGUCArray(ArrayType *array,
284284
GucContext context, GucSource source, GucAction action);
285285
extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value);
286286
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
287+
extern ArrayType *GUCArrayReset(ArrayType *array);
287288

288289
extern int GUC_complaint_elevel(GucSource source);
289290

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy