aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/functioncmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/functioncmds.c')
-rw-r--r--src/backend/commands/functioncmds.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 86b7cd50ec7..ce4b43b5936 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.2 2002/04/21 00:26:42 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.3 2002/04/27 03:45:01 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@@ -86,6 +86,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
else
{
Oid namespaceId;
+ AclResult aclresult;
char *typname;
if (languageOid == SQLlanguageId)
@@ -94,6 +95,10 @@ compute_return_type(TypeName *returnType, Oid languageOid,
typnam);
namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
&typname);
+ aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
+ ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, get_namespace_name(namespaceId));
rettype = TypeShellMake(typname, namespaceId);
if (!OidIsValid(rettype))
elog(ERROR, "could not create type %s", typnam);
@@ -295,6 +300,7 @@ CreateFunction(ProcedureStmt *stmt)
Oid languageOid;
char *funcname;
Oid namespaceId;
+ AclResult aclresult;
int parameterCount;
Oid parameterTypes[FUNC_MAX_ARGS];
int32 byte_pct,
@@ -311,6 +317,11 @@ CreateFunction(ProcedureStmt *stmt)
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
&funcname);
+ /* Check we have creation rights in target namespace */
+ aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, get_namespace_name(namespaceId));
+
/* Convert language name to canonical case */
case_translate_language_name(stmt->language, languageName);
@@ -324,10 +335,21 @@ CreateFunction(ProcedureStmt *stmt)
languageOid = languageTuple->t_data->t_oid;
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
- if (!((languageStruct->lanpltrusted
- && pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE) == ACLCHECK_OK)
- || superuser()))
- elog(ERROR, "permission denied");
+ if (languageStruct->lanpltrusted)
+ {
+ /* if trusted language, need USAGE privilege */
+ AclResult aclresult;
+
+ aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, NameStr(languageStruct->lanname));
+ }
+ else
+ {
+ /* if untrusted language, must be superuser */
+ if (!superuser())
+ aclcheck_error(ACLCHECK_NO_PRIV, NameStr(languageStruct->lanname));
+ }
ReleaseSysCache(languageTuple);
@@ -404,9 +426,11 @@ RemoveFunction(List *functionName, /* function name to be removed */
elog(ERROR, "RemoveFunction: couldn't find tuple for function %s",
NameListToString(functionName));
- if (!pg_proc_ownercheck(funcOid, GetUserId()))
- elog(ERROR, "RemoveFunction: function '%s': permission denied",
- NameListToString(functionName));
+ /* Permission check: must own func or its namespace */
+ if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
+ !pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
+ GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(functionName));
if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
elog(ERROR, "RemoveFunction: function '%s' is an aggregate"