99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.40 2005/11/22 18:17:09 momjian Exp $
12+ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.41 2006/01/13 18:10:25 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -119,11 +119,24 @@ DefineOpClass(CreateOpClassStmt *stmt)
119119ReleaseSysCache (tup );
120120
121121/*
122+ * The question of appropriate permissions for CREATE OPERATOR CLASS is
123+ * interesting. Creating an opclass is tantamount to granting public
124+ * execute access on the functions involved, since the index machinery
125+ * generally does not check access permission before using the functions.
126+ * A minimum expectation therefore is that the caller have execute
127+ * privilege with grant option. Since we don't have a way to make the
128+ * opclass go away if the grant option is revoked, we choose instead to
129+ * require ownership of the functions. It's also not entirely clear what
130+ * permissions should be required on the datatype, but ownership seems
131+ * like a safe choice.
132+ *
122133 * Currently, we require superuser privileges to create an opclass. This
123134 * seems necessary because we have no way to validate that the offered set
124135 * of operators and functions are consistent with the AM's expectations.
125136 * It would be nice to provide such a check someday, if it can be done
126137 * without solving the halting problem :-(
138+ *
139+ * XXX re-enable NOT_USED code sections below if you remove this test.
127140 */
128141if (!superuser ())
129142ereport (ERROR ,
@@ -156,7 +169,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
156169Oid operOid ;
157170Oid funcOid ;
158171OpClassMember * member ;
159- AclResult aclresult ;
160172
161173Assert (IsA (item ,CreateOpClassItem ));
162174switch (item -> itemtype )
@@ -184,13 +196,19 @@ DefineOpClass(CreateOpClassStmt *stmt)
184196operOid = LookupOperName (item -> name ,typeoid ,typeoid ,
185197 false);
186198}
187- /* Caller must have execute permission on operators */
199+
200+ #ifdef NOT_USED
201+ /* XXX this is unnecessary given the superuser check above */
202+ /* Caller must own operator and its underlying function */
203+ if (!pg_oper_ownercheck (operOid ,GetUserId ()))
204+ aclcheck_error (ACLCHECK_NOT_OWNER ,ACL_KIND_OPER ,
205+ get_opname (operOid ));
188206funcOid = get_opcode (operOid );
189- aclresult = pg_proc_aclcheck (funcOid ,GetUserId (),
190- ACL_EXECUTE );
191- if (aclresult != ACLCHECK_OK )
192- aclcheck_error (aclresult ,ACL_KIND_PROC ,
207+ if (!pg_proc_ownercheck (funcOid ,GetUserId ()))
208+ aclcheck_error (ACLCHECK_NOT_OWNER ,ACL_KIND_PROC ,
193209get_func_name (funcOid ));
210+ #endif
211+
194212/* Save the info */
195213member = (OpClassMember * )palloc0 (sizeof (OpClassMember ));
196214member -> object = operOid ;
@@ -208,12 +226,14 @@ DefineOpClass(CreateOpClassStmt *stmt)
208226item -> number ,numProcs )));
209227funcOid = LookupFuncNameTypeNames (item -> name ,item -> args ,
210228 false);
211- /* Caller must have execute permission on functions */
212- aclresult = pg_proc_aclcheck ( funcOid , GetUserId (),
213- ACL_EXECUTE );
214- if (aclresult != ACLCHECK_OK )
215- aclcheck_error (aclresult ,ACL_KIND_PROC ,
229+ #ifdef NOT_USED
230+ /* XXX this is unnecessary given the superuser check above */
231+ /* Caller must own function */
232+ if (! pg_proc_ownercheck ( funcOid , GetUserId ()) )
233+ aclcheck_error (ACLCHECK_NOT_OWNER ,ACL_KIND_PROC ,
216234get_func_name (funcOid ));
235+ #endif
236+
217237/* Save the info */
218238member = (OpClassMember * )palloc0 (sizeof (OpClassMember ));
219239member -> object = funcOid ;
@@ -227,6 +247,14 @@ DefineOpClass(CreateOpClassStmt *stmt)
227247(errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
228248errmsg ("storage type specified more than once" )));
229249storageoid = typenameTypeId (item -> storedtype );
250+
251+ #ifdef NOT_USED
252+ /* XXX this is unnecessary given the superuser check above */
253+ /* Check we have ownership of the datatype */
254+ if (!pg_type_ownercheck (storageoid ,GetUserId ()))
255+ aclcheck_error (ACLCHECK_NOT_OWNER ,ACL_KIND_TYPE ,
256+ format_type_be (storageoid ));
257+ #endif
230258break ;
231259default :
232260elog (ERROR ,"unrecognized item type: %d" ,item -> itemtype );