Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)