Skip to content

Commit 55a7cf8

Browse files
committed
Allow non-superuser database owners to create procedural languages.
A DBA is allowed to create a language in his database if it's marked "tmpldbacreate" in pg_pltemplate. The factory default is that this is set for all standard trusted languages, but of course a superuser may adjust the settings. In service of this, add the long-foreseen owner column to pg_language; renaming, dropping, and altering owner of a PL now follow normal ownership rules instead of being superuser-only. Jeremy Drake, with some editorialization by Tom Lane.
1 parent 66daeb0 commit 55a7cf8

File tree

17 files changed

+295
-84
lines changed

17 files changed

+295
-84
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.147 2007/03/22 15:46:56 momjian Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.148 2007/03/26 16:58:37 tgl Exp $ -->
22
<!--
33
Documentation of the system catalogs, directed toward PostgreSQL developers
44
-->
@@ -2655,6 +2655,13 @@
26552655
<entry>Name of the language</entry>
26562656
</row>
26572657

2658+
<row>
2659+
<entry><structfield>lanowner</structfield></entry>
2660+
<entry><type>oid</type></entry>
2661+
<entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
2662+
<entry>Owner of the language</entry>
2663+
</row>
2664+
26582665
<row>
26592666
<entry><structfield>lanispl</structfield></entry>
26602667
<entry><type>bool</type></entry>
@@ -3265,7 +3272,7 @@
32653272
<table>
32663273
<title><structname>pg_pltemplate</> Columns</title>
32673274

3268-
<tgroup cols=4>
3275+
<tgroup cols=3>
32693276
<thead>
32703277
<row>
32713278
<entry>Name</entry>
@@ -3287,6 +3294,12 @@
32873294
<entry>True if language is considered trusted</entry>
32883295
</row>
32893296

3297+
<row>
3298+
<entry><structfield>tmpldbacreate</structfield></entry>
3299+
<entry><type>boolean</type></entry>
3300+
<entry>True if language may be created by a database owner</entry>
3301+
</row>
3302+
32903303
<row>
32913304
<entry><structfield>tmplhandler</structfield></entry>
32923305
<entry><type>text</type></entry>

doc/src/sgml/ref/alter_language.sgml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_language.sgml,v 1.6 2006/09/16 00:30:16 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_language.sgml,v 1.7 2007/03/26 16:58:38 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -20,7 +20,8 @@ PostgreSQL documentation
2020

2121
<refsynopsisdiv>
2222
<synopsis>
23-
ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</replaceable>
23+
ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</replaceable>
24+
ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
2425
</synopsis>
2526
</refsynopsisdiv>
2627

@@ -29,8 +30,9 @@ ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</r
2930

3031
<para>
3132
<command>ALTER LANGUAGE</command> changes the definition of a
32-
language. The only functionality is to rename the language. Only
33-
a superuser can rename languages.
33+
procedural language. The only functionality is to rename the language or
34+
assign a new owner. You must be superuser or owner of the language to
35+
use <command>ALTER LANGUAGE</command>.
3436
</para>
3537
</refsect1>
3638

@@ -55,6 +57,15 @@ ALTER LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>newname</r
5557
</para>
5658
</listitem>
5759
</varlistentry>
60+
61+
<varlistentry>
62+
<term><replaceable>new_owner</replaceable></term>
63+
<listitem>
64+
<para>
65+
The new owner of the language
66+
</para>
67+
</listitem>
68+
</varlistentry>
5869
</variablelist>
5970
</refsect1>
6071

doc/src/sgml/ref/create_language.sgml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_language.sgml,v 1.43 2007/01/31 23:26:03 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_language.sgml,v 1.44 2007/03/26 16:58:38 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -34,9 +34,7 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
3434
<productname>PostgreSQL</productname> user can register a new
3535
procedural language with a <productname>PostgreSQL</productname>
3636
database. Subsequently, functions and trigger procedures can be
37-
defined in this new language. The user must have the
38-
<productname>PostgreSQL</productname> superuser privilege to
39-
register a new language.
37+
defined in this new language.
4038
</para>
4139

4240
<para>
@@ -64,6 +62,20 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
6462
old dump files, which are likely to contain out-of-date information
6563
about language support functions.
6664
</para>
65+
66+
<para>
67+
Ordinarily, the user must have the
68+
<productname>PostgreSQL</productname> superuser privilege to
69+
register a new language. However, the owner of a database can register
70+
a new language within that database if the language is listed in
71+
the <structname>pg_pltemplate</structname> catalog and is marked
72+
as allowed to be created by database owners (<structfield>tmpldbacreate</>
73+
is true). The default is that trusted languages can be created
74+
by database owners, but this can be adjusted by superusers by modifying
75+
the contents of <structname>pg_pltemplate</structname>.
76+
The creator of a language becomes its owner and can later
77+
drop it, rename it, or assign it to a new owner.
78+
</para>
6779
</refsect1>
6880

6981
<refsect1 id="sql-createlanguage-parameters">

doc/src/sgml/ref/drop_language.sgml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.24 2007/01/31 23:26:03 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_language.sgml,v 1.25 2007/03/26 16:58:38 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -31,6 +31,8 @@ DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] <replaceable class="PARAMETER">name</
3131
<command>DROP LANGUAGE</command> will remove the definition
3232
of the previously registered procedural language called
3333
<replaceable class="parameter">name</replaceable>.
34+
You must be superuser or owner of the language to
35+
use <command>DROP LANGUAGE</command>.
3436
</para>
3537
</refsect1>
3638

@@ -43,7 +45,7 @@ DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] <replaceable class="PARAMETER">name</
4345
<term><literal>IF EXISTS</literal></term>
4446
<listitem>
4547
<para>
46-
Do not throw an error if the function does not exist. A notice is issued
48+
Do not throw an error if the language does not exist. A notice is issued
4749
in this case.
4850
</para>
4951
</listitem>

src/backend/catalog/aclchk.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.137 2007/02/14 01:58:56 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.138 2007/03/26 16:58:38 tgl Exp $
1212
*
1313
* NOTES
1414
* See acl.h.
@@ -1003,11 +1003,8 @@ ExecGrant_Language(InternalGrant *istmt)
10031003
/*
10041004
* Get owner ID and working copy of existing ACL. If there's no ACL,
10051005
* substitute the proper default.
1006-
*
1007-
* Note: for now, languages are treated as owned by the bootstrap
1008-
* user. We should add an owner column to pg_language instead.
10091006
*/
1010-
ownerId = BOOTSTRAP_SUPERUSERID;
1007+
ownerId = pg_language_tuple->lanowner;
10111008
aclDatum = SysCacheGetAttr(LANGNAME, tuple, Anum_pg_language_lanacl,
10121009
&isNull);
10131010
if (isNull)
@@ -1770,8 +1767,7 @@ pg_language_aclmask(Oid lang_oid, Oid roleid,
17701767
(errcode(ERRCODE_UNDEFINED_OBJECT),
17711768
errmsg("language with OID %u does not exist", lang_oid)));
17721769

1773-
/* XXX pg_language should have an owner column, but doesn't */
1774-
ownerId = BOOTSTRAP_SUPERUSERID;
1770+
ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
17751771

17761772
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
17771773
&isNull);
@@ -2147,6 +2143,34 @@ pg_proc_ownercheck(Oid proc_oid, Oid roleid)
21472143
return has_privs_of_role(roleid, ownerId);
21482144
}
21492145

2146+
/*
2147+
* Ownership check for a procedural language (specified by OID)
2148+
*/
2149+
bool
2150+
pg_language_ownercheck(Oid lan_oid, Oid roleid)
2151+
{
2152+
HeapTuple tuple;
2153+
Oid ownerId;
2154+
2155+
/* Superusers bypass all permission checking. */
2156+
if (superuser_arg(roleid))
2157+
return true;
2158+
2159+
tuple = SearchSysCache(LANGOID,
2160+
ObjectIdGetDatum(lan_oid),
2161+
0, 0, 0);
2162+
if (!HeapTupleIsValid(tuple))
2163+
ereport(ERROR,
2164+
(errcode(ERRCODE_UNDEFINED_FUNCTION),
2165+
errmsg("language with OID %u does not exist", lan_oid)));
2166+
2167+
ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner;
2168+
2169+
ReleaseSysCache(tuple);
2170+
2171+
return has_privs_of_role(roleid, ownerId);
2172+
}
2173+
21502174
/*
21512175
* Ownership check for a namespace (specified by OID).
21522176
*/

src/backend/commands/alter.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.22 2007/01/23 05:07:17 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.23 2007/03/26 16:58:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -203,6 +203,10 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
203203
AlterFunctionOwner(stmt->object, stmt->objarg, newowner);
204204
break;
205205

206+
case OBJECT_LANGUAGE:
207+
AlterLanguageOwner((char *) linitial(stmt->object), newowner);
208+
break;
209+
206210
case OBJECT_OPERATOR:
207211
Assert(list_length(stmt->objarg) == 2);
208212
AlterOperatorOwner(stmt->object,

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