88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.84 2003/07/21 01:59:07 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.85 2003/08/01 00:15:19 tgl Exp $
1212 *
1313 * NOTES
1414 * See acl.h.
@@ -223,7 +223,7 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
223223if (stmt -> is_grant
224224&& !pg_class_ownercheck (relOid ,GetUserId ())
225225&& pg_class_aclcheck (relOid ,GetUserId (),ACL_GRANT_OPTION_FOR (privileges ))!= ACLCHECK_OK )
226- aclcheck_error (ACLCHECK_NO_PRIV ,relvar -> relname );
226+ aclcheck_error (ACLCHECK_NO_PRIV ,ACL_KIND_CLASS , relvar -> relname );
227227
228228/* Not sensible to grant on an index */
229229if (pg_class_tuple -> relkind == RELKIND_INDEX )
@@ -329,7 +329,8 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
329329if (stmt -> is_grant
330330&& pg_database_tuple -> datdba != GetUserId ()
331331&& pg_database_aclcheck (HeapTupleGetOid (tuple ),GetUserId (),ACL_GRANT_OPTION_FOR (privileges ))!= ACLCHECK_OK )
332- aclcheck_error (ACLCHECK_NO_PRIV ,NameStr (pg_database_tuple -> datname ));
332+ aclcheck_error (ACLCHECK_NO_PRIV ,ACL_KIND_DATABASE ,
333+ NameStr (pg_database_tuple -> datname ));
333334
334335/*
335336 * If there's no ACL, create a default.
@@ -424,7 +425,7 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
424425if (stmt -> is_grant
425426&& !pg_proc_ownercheck (oid ,GetUserId ())
426427&& pg_proc_aclcheck (oid ,GetUserId (),ACL_GRANT_OPTION_FOR (privileges ))!= ACLCHECK_OK )
427- aclcheck_error (ACLCHECK_NO_PRIV ,
428+ aclcheck_error (ACLCHECK_NO_PRIV ,ACL_KIND_PROC ,
428429NameStr (pg_proc_tuple -> proname ));
429430
430431/*
@@ -525,7 +526,8 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
525526if (stmt -> is_grant
526527&& !superuser ()
527528&& pg_language_aclcheck (HeapTupleGetOid (tuple ),GetUserId (),ACL_GRANT_OPTION_FOR (privileges ))!= ACLCHECK_OK )
528- aclcheck_error (ACLCHECK_NO_PRIV ,NameStr (pg_language_tuple -> lanname ));
529+ aclcheck_error (ACLCHECK_NO_PRIV ,ACL_KIND_LANGUAGE ,
530+ NameStr (pg_language_tuple -> lanname ));
529531
530532/*
531533 * If there's no ACL, create a default.
@@ -619,7 +621,8 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
619621if (stmt -> is_grant
620622&& !pg_namespace_ownercheck (HeapTupleGetOid (tuple ),GetUserId ())
621623&& pg_namespace_aclcheck (HeapTupleGetOid (tuple ),GetUserId (),ACL_GRANT_OPTION_FOR (privileges ))!= ACLCHECK_OK )
622- aclcheck_error (ACLCHECK_NO_PRIV ,nspname );
624+ aclcheck_error (ACLCHECK_NO_PRIV ,ACL_KIND_NAMESPACE ,
625+ nspname );
623626
624627/*
625628 * If there's no ACL, create a default using the
@@ -848,9 +851,59 @@ aclcheck(Acl *acl, AclId userid, AclMode mode)
848851
849852/*
850853 * Standardized reporting of aclcheck permissions failures.
854+ *
855+ * Note: we do not double-quote the %s's below, because many callers
856+ * supply strings that might be already quoted.
851857 */
858+
859+ static const char * const no_priv_msg [MAX_ACL_KIND ]=
860+ {
861+ /* ACL_KIND_CLASS */
862+ gettext_noop ("permission denied for relation %s" ),
863+ /* ACL_KIND_DATABASE */
864+ gettext_noop ("permission denied for database %s" ),
865+ /* ACL_KIND_PROC */
866+ gettext_noop ("permission denied for function %s" ),
867+ /* ACL_KIND_OPER */
868+ gettext_noop ("permission denied for operator %s" ),
869+ /* ACL_KIND_TYPE */
870+ gettext_noop ("permission denied for type %s" ),
871+ /* ACL_KIND_LANGUAGE */
872+ gettext_noop ("permission denied for language %s" ),
873+ /* ACL_KIND_NAMESPACE */
874+ gettext_noop ("permission denied for schema %s" ),
875+ /* ACL_KIND_OPCLASS */
876+ gettext_noop ("permission denied for operator class %s" ),
877+ /* ACL_KIND_CONVERSION */
878+ gettext_noop ("permission denied for conversion %s" )
879+ };
880+
881+ static const char * const not_owner_msg [MAX_ACL_KIND ]=
882+ {
883+ /* ACL_KIND_CLASS */
884+ gettext_noop ("must be owner of relation %s" ),
885+ /* ACL_KIND_DATABASE */
886+ gettext_noop ("must be owner of database %s" ),
887+ /* ACL_KIND_PROC */
888+ gettext_noop ("must be owner of function %s" ),
889+ /* ACL_KIND_OPER */
890+ gettext_noop ("must be owner of operator %s" ),
891+ /* ACL_KIND_TYPE */
892+ gettext_noop ("must be owner of type %s" ),
893+ /* ACL_KIND_LANGUAGE */
894+ gettext_noop ("must be owner of language %s" ),
895+ /* ACL_KIND_NAMESPACE */
896+ gettext_noop ("must be owner of schema %s" ),
897+ /* ACL_KIND_OPCLASS */
898+ gettext_noop ("must be owner of operator class %s" ),
899+ /* ACL_KIND_CONVERSION */
900+ gettext_noop ("must be owner of conversion %s" )
901+ };
902+
903+
852904void
853- aclcheck_error (AclResult aclerr ,const char * objectname )
905+ aclcheck_error (AclResult aclerr ,AclObjectKind objectkind ,
906+ const char * objectname )
854907{
855908switch (aclerr )
856909{
@@ -860,12 +913,12 @@ aclcheck_error(AclResult aclerr, const char *objectname)
860913case ACLCHECK_NO_PRIV :
861914ereport (ERROR ,
862915(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
863- errmsg ("permission denied for \"%s\"" ,objectname )));
916+ errmsg (no_priv_msg [ objectkind ] ,objectname )));
864917break ;
865918case ACLCHECK_NOT_OWNER :
866919ereport (ERROR ,
867920(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
868- errmsg ("must be owner of \"%s\"" ,objectname )));
921+ errmsg (not_owner_msg [ objectkind ] ,objectname )));
869922break ;
870923default :
871924elog (ERROR ,"unrecognized AclResult: %d" , (int )aclerr );