Add GRANT ON SEQUENCE syntax to support sequence-only permissions.
Continue to support GRANT ON [TABLE] for sequences for backward compatibility; issue warning for invalid sequence permissions. [Backward compatibility warning message.] Add USAGE permission for sequences that allows only currval() and nextval(), not setval(). Mention object name in grant/revoke warnings because of possible multi-object operations.
This commit is contained in:
parent
33feb55c47
commit
4789e98801
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.50 2005/10/20 19:18:01 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/grant.sgml,v 1.51 2006/01/21 02:16:18 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -25,6 +25,11 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
|
|||||||
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
|
ON [ TABLE ] <replaceable class="PARAMETER">tablename</replaceable> [, ...]
|
||||||
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
||||||
|
|
||||||
|
GRANT { { USAGE | SELECT | UPDATE }
|
||||||
|
[,...] | ALL [ PRIVILEGES ] }
|
||||||
|
ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...]
|
||||||
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
||||||
|
|
||||||
GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
|
GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
|
||||||
ON DATABASE <replaceable>dbname</replaceable> [, ...]
|
ON DATABASE <replaceable>dbname</replaceable> [, ...]
|
||||||
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
TO { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
|
||||||
@ -260,6 +265,10 @@ GRANT <replaceable class="PARAMETER">role</replaceable> [, ...]
|
|||||||
also met). Essentially this allows the grantee to <quote>look up</>
|
also met). Essentially this allows the grantee to <quote>look up</>
|
||||||
objects within the schema.
|
objects within the schema.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
For sequences, this privilege allows the use of the
|
||||||
|
<function>currval</function> and <function>nextval</function> functions.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -511,7 +520,7 @@ GRANT <replaceable class="PARAMETER">privileges</replaceable>
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <literal>RULE</literal> privilege, and privileges on
|
The <literal>RULE</literal> privilege, and privileges on
|
||||||
databases, tablespaces, schemas, languages, and sequences are
|
databases, tablespaces, schemas, and languages are
|
||||||
<productname>PostgreSQL</productname> extensions.
|
<productname>PostgreSQL</productname> extensions.
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.35 2005/10/20 19:18:01 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/revoke.sgml,v 1.36 2006/01/21 02:16:18 momjian Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -27,6 +27,13 @@ REVOKE [ GRANT OPTION FOR ]
|
|||||||
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
[ CASCADE | RESTRICT ]
|
[ CASCADE | RESTRICT ]
|
||||||
|
|
||||||
|
REVOKE [ GRANT OPTION FOR ]
|
||||||
|
{ { USAGE | SELECT | UPDATE }
|
||||||
|
[,...] | ALL [ PRIVILEGES ] }
|
||||||
|
ON SEQUENCE <replaceable class="PARAMETER">sequencename</replaceable> [, ...]
|
||||||
|
FROM { <replaceable class="PARAMETER">username</replaceable> | GROUP <replaceable class="PARAMETER">groupname</replaceable> | PUBLIC } [, ...]
|
||||||
|
[ CASCADE | RESTRICT ]
|
||||||
|
|
||||||
REVOKE [ GRANT OPTION FOR ]
|
REVOKE [ GRANT OPTION FOR ]
|
||||||
{ { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
|
{ { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
|
||||||
ON DATABASE <replaceable>dbname</replaceable> [, ...]
|
ON DATABASE <replaceable>dbname</replaceable> [, ...]
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.123 2005/12/01 02:03:00 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.124 2006/01/21 02:16:18 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -164,6 +164,9 @@ restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
|
|||||||
case ACL_KIND_CLASS:
|
case ACL_KIND_CLASS:
|
||||||
whole_mask = ACL_ALL_RIGHTS_RELATION;
|
whole_mask = ACL_ALL_RIGHTS_RELATION;
|
||||||
break;
|
break;
|
||||||
|
case ACL_KIND_SEQUENCE:
|
||||||
|
whole_mask = ACL_ALL_RIGHTS_SEQUENCE;
|
||||||
|
break;
|
||||||
case ACL_KIND_DATABASE:
|
case ACL_KIND_DATABASE:
|
||||||
whole_mask = ACL_ALL_RIGHTS_DATABASE;
|
whole_mask = ACL_ALL_RIGHTS_DATABASE;
|
||||||
break;
|
break;
|
||||||
@ -212,22 +215,22 @@ restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
|
|||||||
if (this_privileges == 0)
|
if (this_privileges == 0)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
|
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
|
||||||
errmsg("no privileges were granted")));
|
errmsg("no privileges were granted for \"%s\"", objname)));
|
||||||
else if (!all_privs && this_privileges != privileges)
|
else if (!all_privs && this_privileges != privileges)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
|
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
|
||||||
errmsg("not all privileges were granted")));
|
errmsg("not all privileges were granted for \"%s\"", objname)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this_privileges == 0)
|
if (this_privileges == 0)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
|
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
|
||||||
errmsg("no privileges could be revoked")));
|
errmsg("no privileges could be revoked for \"%s\"", objname)));
|
||||||
else if (!all_privs && this_privileges != privileges)
|
else if (!all_privs && this_privileges != privileges)
|
||||||
ereport(WARNING,
|
ereport(WARNING,
|
||||||
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
|
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
|
||||||
errmsg("not all privileges could be revoked")));
|
errmsg("not all privileges could be revoked for \"%s\"", objname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this_privileges;
|
return this_privileges;
|
||||||
@ -282,9 +285,18 @@ ExecuteGrantStmt(GrantStmt *stmt)
|
|||||||
*/
|
*/
|
||||||
switch (stmt->objtype)
|
switch (stmt->objtype)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Because this might be a sequence, we test both relation
|
||||||
|
* and sequence bits, and later do a more limited test
|
||||||
|
* when we know the object type.
|
||||||
|
*/
|
||||||
case ACL_OBJECT_RELATION:
|
case ACL_OBJECT_RELATION:
|
||||||
all_privileges = ACL_ALL_RIGHTS_RELATION;
|
all_privileges = ACL_ALL_RIGHTS_RELATION | ACL_ALL_RIGHTS_SEQUENCE;
|
||||||
errormsg = _("invalid privilege type %s for table");
|
errormsg = _("invalid privilege type %s for relation");
|
||||||
|
break;
|
||||||
|
case ACL_OBJECT_SEQUENCE:
|
||||||
|
all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
|
||||||
|
errormsg = _("invalid privilege type %s for sequence");
|
||||||
break;
|
break;
|
||||||
case ACL_OBJECT_DATABASE:
|
case ACL_OBJECT_DATABASE:
|
||||||
all_privileges = ACL_ALL_RIGHTS_DATABASE;
|
all_privileges = ACL_ALL_RIGHTS_DATABASE;
|
||||||
@ -327,6 +339,7 @@ ExecuteGrantStmt(GrantStmt *stmt)
|
|||||||
{
|
{
|
||||||
istmt.all_privs = false;
|
istmt.all_privs = false;
|
||||||
istmt.privileges = ACL_NO_RIGHTS;
|
istmt.privileges = ACL_NO_RIGHTS;
|
||||||
|
|
||||||
foreach(cell, stmt->privileges)
|
foreach(cell, stmt->privileges)
|
||||||
{
|
{
|
||||||
char *privname = strVal(lfirst(cell));
|
char *privname = strVal(lfirst(cell));
|
||||||
@ -356,6 +369,7 @@ ExecGrantStmt_oids(InternalGrant *istmt)
|
|||||||
switch (istmt->objtype)
|
switch (istmt->objtype)
|
||||||
{
|
{
|
||||||
case ACL_OBJECT_RELATION:
|
case ACL_OBJECT_RELATION:
|
||||||
|
case ACL_OBJECT_SEQUENCE:
|
||||||
ExecGrant_Relation(istmt);
|
ExecGrant_Relation(istmt);
|
||||||
break;
|
break;
|
||||||
case ACL_OBJECT_DATABASE:
|
case ACL_OBJECT_DATABASE:
|
||||||
@ -395,6 +409,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
|
|||||||
switch (objtype)
|
switch (objtype)
|
||||||
{
|
{
|
||||||
case ACL_OBJECT_RELATION:
|
case ACL_OBJECT_RELATION:
|
||||||
|
case ACL_OBJECT_SEQUENCE:
|
||||||
foreach(cell, objnames)
|
foreach(cell, objnames)
|
||||||
{
|
{
|
||||||
Oid relOid;
|
Oid relOid;
|
||||||
@ -523,15 +538,15 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
|
|||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This processes both sequences and non-sequences.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
ExecGrant_Relation(InternalGrant *istmt)
|
ExecGrant_Relation(InternalGrant *istmt)
|
||||||
{
|
{
|
||||||
Relation relation;
|
Relation relation;
|
||||||
ListCell *cell;
|
ListCell *cell;
|
||||||
|
|
||||||
if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
|
|
||||||
istmt->privileges = ACL_ALL_RIGHTS_RELATION;
|
|
||||||
|
|
||||||
relation = heap_open(RelationRelationId, RowExclusiveLock);
|
relation = heap_open(RelationRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
foreach(cell, istmt->objects)
|
foreach(cell, istmt->objects)
|
||||||
@ -577,6 +592,69 @@ ExecGrant_Relation(InternalGrant *istmt)
|
|||||||
errmsg("\"%s\" is a composite type",
|
errmsg("\"%s\" is a composite type",
|
||||||
NameStr(pg_class_tuple->relname))));
|
NameStr(pg_class_tuple->relname))));
|
||||||
|
|
||||||
|
/* Used GRANT SEQUENCE on a non-sequence? */
|
||||||
|
if (istmt->objtype == ACL_OBJECT_SEQUENCE &&
|
||||||
|
pg_class_tuple->relkind != RELKIND_SEQUENCE)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
|
errmsg("\"%s\" is not a sequence",
|
||||||
|
NameStr(pg_class_tuple->relname))));
|
||||||
|
|
||||||
|
/* Adjust the default permissions based on whether it is a sequence */
|
||||||
|
if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
|
||||||
|
{
|
||||||
|
if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
|
||||||
|
this_privileges = ACL_ALL_RIGHTS_SEQUENCE;
|
||||||
|
else
|
||||||
|
this_privileges = ACL_ALL_RIGHTS_RELATION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this_privileges = istmt->privileges;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The GRANT TABLE syntax can be used for sequences and
|
||||||
|
* non-sequences, so we have to look at the relkind to
|
||||||
|
* determine the supported permissions. The OR of
|
||||||
|
* table and sequence permissions were already checked.
|
||||||
|
*/
|
||||||
|
if (istmt->objtype == ACL_OBJECT_RELATION)
|
||||||
|
{
|
||||||
|
if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* For backward compatibility, throw just a warning
|
||||||
|
* for invalid sequence permissions when using the
|
||||||
|
* non-sequence GRANT syntax is used.
|
||||||
|
*/
|
||||||
|
if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_SEQUENCE))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Mention the object name because the user needs to
|
||||||
|
* know which operations succeeded. This is required
|
||||||
|
* because WARNING allows the command to continue.
|
||||||
|
*/
|
||||||
|
ereport(WARNING,
|
||||||
|
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
|
||||||
|
errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE",
|
||||||
|
NameStr(pg_class_tuple->relname))));
|
||||||
|
this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
|
||||||
|
/*
|
||||||
|
* USAGE is the only permission supported by sequences
|
||||||
|
* but not by non-sequences. Don't mention the object
|
||||||
|
* name because we didn't in the combined TABLE |
|
||||||
|
* SEQUENCE check.
|
||||||
|
*/
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
|
||||||
|
errmsg("invalid privilege type USAGE for table")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get owner ID and working copy of existing ACL. If there's no ACL,
|
* Get owner ID and working copy of existing ACL. If there's no ACL,
|
||||||
* substitute the proper default.
|
* substitute the proper default.
|
||||||
@ -585,12 +663,14 @@ ExecGrant_Relation(InternalGrant *istmt)
|
|||||||
aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
|
aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
|
||||||
&isNull);
|
&isNull);
|
||||||
if (isNull)
|
if (isNull)
|
||||||
old_acl = acldefault(ACL_OBJECT_RELATION, ownerId);
|
old_acl = acldefault(pg_class_tuple->relkind == RELKIND_SEQUENCE ?
|
||||||
|
ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
|
||||||
|
ownerId);
|
||||||
else
|
else
|
||||||
old_acl = DatumGetAclPCopy(aclDatum);
|
old_acl = DatumGetAclPCopy(aclDatum);
|
||||||
|
|
||||||
/* Determine ID to do the grant as, and available grant options */
|
/* Determine ID to do the grant as, and available grant options */
|
||||||
select_best_grantor(GetUserId(), istmt->privileges,
|
select_best_grantor(GetUserId(), this_privileges,
|
||||||
old_acl, ownerId,
|
old_acl, ownerId,
|
||||||
&grantorId, &avail_goptions);
|
&grantorId, &avail_goptions);
|
||||||
|
|
||||||
@ -600,8 +680,10 @@ ExecGrant_Relation(InternalGrant *istmt)
|
|||||||
*/
|
*/
|
||||||
this_privileges =
|
this_privileges =
|
||||||
restrict_and_check_grant(istmt->is_grant, avail_goptions,
|
restrict_and_check_grant(istmt->is_grant, avail_goptions,
|
||||||
istmt->all_privs, istmt->privileges,
|
istmt->all_privs, this_privileges,
|
||||||
relOid, grantorId, ACL_KIND_CLASS,
|
relOid, grantorId,
|
||||||
|
pg_class_tuple->relkind == RELKIND_SEQUENCE
|
||||||
|
? ACL_KIND_SEQUENCE : ACL_KIND_CLASS,
|
||||||
NameStr(pg_class_tuple->relname));
|
NameStr(pg_class_tuple->relname));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1336,6 +1418,8 @@ static const char *const no_priv_msg[MAX_ACL_KIND] =
|
|||||||
{
|
{
|
||||||
/* ACL_KIND_CLASS */
|
/* ACL_KIND_CLASS */
|
||||||
gettext_noop("permission denied for relation %s"),
|
gettext_noop("permission denied for relation %s"),
|
||||||
|
/* ACL_KIND_SEQUENCE */
|
||||||
|
gettext_noop("permission denied for sequence %s"),
|
||||||
/* ACL_KIND_DATABASE */
|
/* ACL_KIND_DATABASE */
|
||||||
gettext_noop("permission denied for database %s"),
|
gettext_noop("permission denied for database %s"),
|
||||||
/* ACL_KIND_PROC */
|
/* ACL_KIND_PROC */
|
||||||
@ -1360,6 +1444,8 @@ static const char *const not_owner_msg[MAX_ACL_KIND] =
|
|||||||
{
|
{
|
||||||
/* ACL_KIND_CLASS */
|
/* ACL_KIND_CLASS */
|
||||||
gettext_noop("must be owner of relation %s"),
|
gettext_noop("must be owner of relation %s"),
|
||||||
|
/* ACL_KIND_SEQUENCE */
|
||||||
|
gettext_noop("must be owner of sequence %s"),
|
||||||
/* ACL_KIND_DATABASE */
|
/* ACL_KIND_DATABASE */
|
||||||
gettext_noop("must be owner of database %s"),
|
gettext_noop("must be owner of database %s"),
|
||||||
/* ACL_KIND_PROC */
|
/* ACL_KIND_PROC */
|
||||||
@ -1439,6 +1525,7 @@ pg_aclmask(AclObjectKind objkind, Oid table_oid, Oid roleid,
|
|||||||
switch (objkind)
|
switch (objkind)
|
||||||
{
|
{
|
||||||
case ACL_KIND_CLASS:
|
case ACL_KIND_CLASS:
|
||||||
|
case ACL_KIND_SEQUENCE:
|
||||||
return pg_class_aclmask(table_oid, roleid, mask, how);
|
return pg_class_aclmask(table_oid, roleid, mask, how);
|
||||||
case ACL_KIND_DATABASE:
|
case ACL_KIND_DATABASE:
|
||||||
return pg_database_aclmask(table_oid, roleid, mask, how);
|
return pg_database_aclmask(table_oid, roleid, mask, how);
|
||||||
@ -1500,9 +1587,9 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
|
|||||||
*
|
*
|
||||||
* As of 7.4 we have some updatable system views; those shouldn't be
|
* As of 7.4 we have some updatable system views; those shouldn't be
|
||||||
* protected in this way. Assume the view rules can take care of
|
* protected in this way. Assume the view rules can take care of
|
||||||
* themselves.
|
* themselves. ACL_USAGE is if we ever have system sequences.
|
||||||
*/
|
*/
|
||||||
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
|
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE)) &&
|
||||||
IsSystemClass(classForm) &&
|
IsSystemClass(classForm) &&
|
||||||
classForm->relkind != RELKIND_VIEW &&
|
classForm->relkind != RELKIND_VIEW &&
|
||||||
!has_rolcatupdate(roleid) &&
|
!has_rolcatupdate(roleid) &&
|
||||||
@ -1511,7 +1598,7 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
|
|||||||
#ifdef ACLDEBUG
|
#ifdef ACLDEBUG
|
||||||
elog(DEBUG2, "permission denied for system catalog update");
|
elog(DEBUG2, "permission denied for system catalog update");
|
||||||
#endif
|
#endif
|
||||||
mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE);
|
mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1536,7 +1623,9 @@ pg_class_aclmask(Oid table_oid, Oid roleid,
|
|||||||
if (isNull)
|
if (isNull)
|
||||||
{
|
{
|
||||||
/* No ACL, so build default ACL */
|
/* No ACL, so build default ACL */
|
||||||
acl = acldefault(ACL_OBJECT_RELATION, ownerId);
|
acl = acldefault(classForm->relkind == RELKIND_SEQUENCE ?
|
||||||
|
ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
|
||||||
|
ownerId);
|
||||||
aclDatum = (Datum) 0;
|
aclDatum = (Datum) 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.6 2005/12/01 02:03:00 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.7 2006/01/21 02:16:18 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1133,8 +1133,25 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
|
|||||||
switch (sdepForm->classid)
|
switch (sdepForm->classid)
|
||||||
{
|
{
|
||||||
case RelationRelationId:
|
case RelationRelationId:
|
||||||
istmt.objtype = ACL_OBJECT_RELATION;
|
{
|
||||||
|
/* is it a sequence or non-sequence? */
|
||||||
|
Form_pg_class pg_class_tuple;
|
||||||
|
HeapTuple tuple;
|
||||||
|
|
||||||
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(sdepForm->objid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cache lookup failed for relation %u",
|
||||||
|
sdepForm->objid);
|
||||||
|
pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
|
if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
|
||||||
|
istmt.objtype = ACL_OBJECT_SEQUENCE;
|
||||||
|
else
|
||||||
|
istmt.objtype = ACL_OBJECT_RELATION;
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DatabaseRelationId:
|
case DatabaseRelationId:
|
||||||
istmt.objtype = ACL_OBJECT_DATABASE;
|
istmt.objtype = ACL_OBJECT_DATABASE;
|
||||||
break;
|
break;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.126 2005/11/22 18:17:09 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.127 2006/01/21 02:16:18 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -422,7 +422,8 @@ nextval_internal(Oid relid)
|
|||||||
/* open and AccessShareLock sequence */
|
/* open and AccessShareLock sequence */
|
||||||
init_sequence(relid, &elm, &seqrel);
|
init_sequence(relid, &elm, &seqrel);
|
||||||
|
|
||||||
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
|
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK &&
|
||||||
|
pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("permission denied for sequence %s",
|
errmsg("permission denied for sequence %s",
|
||||||
@ -613,7 +614,8 @@ currval_oid(PG_FUNCTION_ARGS)
|
|||||||
/* open and AccessShareLock sequence */
|
/* open and AccessShareLock sequence */
|
||||||
init_sequence(relid, &elm, &seqrel);
|
init_sequence(relid, &elm, &seqrel);
|
||||||
|
|
||||||
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
|
||||||
|
pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("permission denied for sequence %s",
|
errmsg("permission denied for sequence %s",
|
||||||
@ -657,7 +659,8 @@ lastval(PG_FUNCTION_ARGS)
|
|||||||
/* nextval() must have already been called for this sequence */
|
/* nextval() must have already been called for this sequence */
|
||||||
Assert(last_used_seq->increment != 0);
|
Assert(last_used_seq->increment != 0);
|
||||||
|
|
||||||
if (pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
|
if (pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
|
||||||
|
pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("permission denied for sequence %s",
|
errmsg("permission denied for sequence %s",
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.521 2005/12/29 04:53:18 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.522 2006/01/21 02:16:19 momjian Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -3322,6 +3322,13 @@ privilege_target:
|
|||||||
n->objs = $2;
|
n->objs = $2;
|
||||||
$$ = n;
|
$$ = n;
|
||||||
}
|
}
|
||||||
|
| SEQUENCE qualified_name_list
|
||||||
|
{
|
||||||
|
PrivTarget *n = makeNode(PrivTarget);
|
||||||
|
n->objtype = ACL_OBJECT_SEQUENCE;
|
||||||
|
n->objs = $2;
|
||||||
|
$$ = n;
|
||||||
|
}
|
||||||
| FUNCTION function_with_argtypes_list
|
| FUNCTION function_with_argtypes_list
|
||||||
{
|
{
|
||||||
PrivTarget *n = makeNode(PrivTarget);
|
PrivTarget *n = makeNode(PrivTarget);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.129 2005/11/18 02:38:23 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.130 2006/01/21 02:16:19 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -545,6 +545,10 @@ acldefault(GrantObjectType objtype, Oid ownerId)
|
|||||||
world_default = ACL_NO_RIGHTS;
|
world_default = ACL_NO_RIGHTS;
|
||||||
owner_default = ACL_ALL_RIGHTS_RELATION;
|
owner_default = ACL_ALL_RIGHTS_RELATION;
|
||||||
break;
|
break;
|
||||||
|
case ACL_OBJECT_SEQUENCE:
|
||||||
|
world_default = ACL_NO_RIGHTS;
|
||||||
|
owner_default = ACL_ALL_RIGHTS_SEQUENCE;
|
||||||
|
break;
|
||||||
case ACL_OBJECT_DATABASE:
|
case ACL_OBJECT_DATABASE:
|
||||||
world_default = ACL_CREATE_TEMP; /* not NO_RIGHTS! */
|
world_default = ACL_CREATE_TEMP; /* not NO_RIGHTS! */
|
||||||
owner_default = ACL_ALL_RIGHTS_DATABASE;
|
owner_default = ACL_ALL_RIGHTS_DATABASE;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.24 2006/01/11 21:24:30 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/dumputils.c,v 1.25 2006/01/21 02:16:20 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,8 +22,7 @@
|
|||||||
#define supports_grant_options(version) ((version) >= 70400)
|
#define supports_grant_options(version) ((version) >= 70400)
|
||||||
|
|
||||||
static bool parseAclItem(const char *item, const char *type, const char *name,
|
static bool parseAclItem(const char *item, const char *type, const char *name,
|
||||||
int remoteVersion,
|
int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
|
||||||
PQExpBuffer grantee, PQExpBuffer grantor,
|
|
||||||
PQExpBuffer privs, PQExpBuffer privswgo);
|
PQExpBuffer privs, PQExpBuffer privswgo);
|
||||||
static char *copyAclUserName(PQExpBuffer output, char *input);
|
static char *copyAclUserName(PQExpBuffer output, char *input);
|
||||||
static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
|
static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
|
||||||
@ -326,7 +325,7 @@ parsePGArray(const char *atext, char ***itemarray, int *nitems)
|
|||||||
*
|
*
|
||||||
* name: the object name, in the form to use in the commands (already quoted)
|
* name: the object name, in the form to use in the commands (already quoted)
|
||||||
* type: the object type (as seen in GRANT command: must be one of
|
* type: the object type (as seen in GRANT command: must be one of
|
||||||
* TABLE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
|
* TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
|
||||||
* acls: the ACL string fetched from the database
|
* acls: the ACL string fetched from the database
|
||||||
* owner: username of object owner (will be passed through fmtId); can be
|
* owner: username of object owner (will be passed through fmtId); can be
|
||||||
* NULL or empty string to indicate "no owner known"
|
* NULL or empty string to indicate "no owner known"
|
||||||
@ -515,8 +514,7 @@ buildACLCommands(const char *name, const char *type,
|
|||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
parseAclItem(const char *item, const char *type, const char *name,
|
parseAclItem(const char *item, const char *type, const char *name,
|
||||||
int remoteVersion,
|
int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
|
||||||
PQExpBuffer grantee, PQExpBuffer grantor,
|
|
||||||
PQExpBuffer privs, PQExpBuffer privswgo)
|
PQExpBuffer privs, PQExpBuffer privswgo)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -547,6 +545,7 @@ parseAclItem(const char *item, const char *type, const char *name,
|
|||||||
|
|
||||||
/* privilege codes */
|
/* privilege codes */
|
||||||
#define CONVERT_PRIV(code, keywd) \
|
#define CONVERT_PRIV(code, keywd) \
|
||||||
|
do { \
|
||||||
if ((pos = strchr(eqpos + 1, code))) \
|
if ((pos = strchr(eqpos + 1, code))) \
|
||||||
{ \
|
{ \
|
||||||
if (*(pos + 1) == '*') \
|
if (*(pos + 1) == '*') \
|
||||||
@ -561,29 +560,38 @@ parseAclItem(const char *item, const char *type, const char *name,
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
all_with_go = all_without_go = false
|
all_with_go = all_without_go = false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
resetPQExpBuffer(privs);
|
resetPQExpBuffer(privs);
|
||||||
resetPQExpBuffer(privswgo);
|
resetPQExpBuffer(privswgo);
|
||||||
|
|
||||||
if (strcmp(type, "TABLE") == 0)
|
if (strcmp(type, "TABLE") == 0 || strcmp(type, "SEQUENCE") == 0)
|
||||||
{
|
{
|
||||||
CONVERT_PRIV('a', "INSERT");
|
|
||||||
CONVERT_PRIV('r', "SELECT");
|
CONVERT_PRIV('r', "SELECT");
|
||||||
CONVERT_PRIV('R', "RULE");
|
|
||||||
|
if (strcmp(type, "SEQUENCE") == 0)
|
||||||
if (remoteVersion >= 70200)
|
/* sequence only */
|
||||||
{
|
CONVERT_PRIV('U', "USAGE");
|
||||||
CONVERT_PRIV('w', "UPDATE");
|
|
||||||
CONVERT_PRIV('d', "DELETE");
|
|
||||||
CONVERT_PRIV('x', "REFERENCES");
|
|
||||||
CONVERT_PRIV('t', "TRIGGER");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* table only */
|
||||||
|
CONVERT_PRIV('a', "INSERT");
|
||||||
|
CONVERT_PRIV('R', "RULE");
|
||||||
|
if (remoteVersion >= 70200)
|
||||||
|
{
|
||||||
|
CONVERT_PRIV('d', "DELETE");
|
||||||
|
CONVERT_PRIV('x', "REFERENCES");
|
||||||
|
CONVERT_PRIV('t', "TRIGGER");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UPDATE */
|
||||||
|
if (remoteVersion >= 70200 || strcmp(type, "SEQUENCE") == 0)
|
||||||
|
CONVERT_PRIV('w', "UPDATE");
|
||||||
|
else
|
||||||
/* 7.0 and 7.1 have a simpler worldview */
|
/* 7.0 and 7.1 have a simpler worldview */
|
||||||
CONVERT_PRIV('w', "UPDATE,DELETE");
|
CONVERT_PRIV('w', "UPDATE,DELETE");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (strcmp(type, "FUNCTION") == 0)
|
else if (strcmp(type, "FUNCTION") == 0)
|
||||||
CONVERT_PRIV('X', "EXECUTE");
|
CONVERT_PRIV('X', "EXECUTE");
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.118 2005/11/22 18:17:28 momjian Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.119 2006/01/21 02:16:20 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1889,7 +1889,8 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt, bool include_acls)
|
|||||||
if (strcmp(ropt->schemaNames, te->namespace) != 0)
|
if (strcmp(ropt->schemaNames, te->namespace) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((strcmp(te->desc, "TABLE") == 0) || (strcmp(te->desc, "TABLE DATA") == 0))
|
if (strcmp(te->desc, "TABLE") == 0 ||
|
||||||
|
strcmp(te->desc, "TABLE DATA") == 0)
|
||||||
{
|
{
|
||||||
if (!ropt->selTable)
|
if (!ropt->selTable)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2276,8 +2277,7 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
|
|||||||
const char *type = te->desc;
|
const char *type = te->desc;
|
||||||
|
|
||||||
/* Use ALTER TABLE for views and sequences */
|
/* Use ALTER TABLE for views and sequences */
|
||||||
if (strcmp(type, "VIEW") == 0 ||
|
if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0)
|
||||||
strcmp(type, "SEQUENCE") == 0)
|
|
||||||
type = "TABLE";
|
type = "TABLE";
|
||||||
|
|
||||||
/* objects named by a schema and name */
|
/* objects named by a schema and name */
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* by PostgreSQL
|
* by PostgreSQL
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.426 2006/01/09 21:16:17 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.427 2006/01/21 02:16:20 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -6788,7 +6788,8 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
|
|||||||
|
|
||||||
/* Handle the ACL here */
|
/* Handle the ACL here */
|
||||||
namecopy = strdup(fmtId(tbinfo->dobj.name));
|
namecopy = strdup(fmtId(tbinfo->dobj.name));
|
||||||
dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
|
dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
|
||||||
|
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE",
|
||||||
namecopy, tbinfo->dobj.name,
|
namecopy, tbinfo->dobj.name,
|
||||||
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
|
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
|
||||||
tbinfo->relacl);
|
tbinfo->relacl);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.298 2005/12/07 15:20:55 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.299 2006/01/21 02:16:20 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -884,7 +884,8 @@ typedef struct AlterDomainStmt
|
|||||||
*/
|
*/
|
||||||
typedef enum GrantObjectType
|
typedef enum GrantObjectType
|
||||||
{
|
{
|
||||||
ACL_OBJECT_RELATION, /* table, view, sequence */
|
ACL_OBJECT_RELATION, /* table, view */
|
||||||
|
ACL_OBJECT_SEQUENCE, /* sequence */
|
||||||
ACL_OBJECT_DATABASE, /* database */
|
ACL_OBJECT_DATABASE, /* database */
|
||||||
ACL_OBJECT_FUNCTION, /* function */
|
ACL_OBJECT_FUNCTION, /* function */
|
||||||
ACL_OBJECT_LANGUAGE, /* procedural language */
|
ACL_OBJECT_LANGUAGE, /* procedural language */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.91 2005/12/01 02:03:01 alvherre Exp $
|
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.92 2006/01/21 02:16:21 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* An ACL array is simply an array of AclItems, representing the union
|
* An ACL array is simply an array of AclItems, representing the union
|
||||||
@ -143,6 +143,7 @@ typedef ArrayType Acl;
|
|||||||
* Bitmasks defining "all rights" for each supported object type
|
* Bitmasks defining "all rights" for each supported object type
|
||||||
*/
|
*/
|
||||||
#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
|
#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
|
||||||
|
#define ACL_ALL_RIGHTS_SEQUENCE (ACL_USAGE|ACL_SELECT|ACL_UPDATE)
|
||||||
#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP)
|
#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP)
|
||||||
#define ACL_ALL_RIGHTS_FUNCTION (ACL_EXECUTE)
|
#define ACL_ALL_RIGHTS_FUNCTION (ACL_EXECUTE)
|
||||||
#define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE)
|
#define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE)
|
||||||
@ -169,6 +170,7 @@ typedef enum
|
|||||||
typedef enum AclObjectKind
|
typedef enum AclObjectKind
|
||||||
{
|
{
|
||||||
ACL_KIND_CLASS, /* pg_class */
|
ACL_KIND_CLASS, /* pg_class */
|
||||||
|
ACL_KIND_SEQUENCE, /* pg_sequence */
|
||||||
ACL_KIND_DATABASE, /* pg_database */
|
ACL_KIND_DATABASE, /* pg_database */
|
||||||
ACL_KIND_PROC, /* pg_proc */
|
ACL_KIND_PROC, /* pg_proc */
|
||||||
ACL_KIND_OPER, /* pg_operator */
|
ACL_KIND_OPER, /* pg_operator */
|
||||||
|
@ -90,7 +90,7 @@ ERROR: permission denied for relation atest2
|
|||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
||||||
WARNING: no privileges were granted
|
WARNING: no privileges were granted for "atest1"
|
||||||
-- checks in subquery, both ok
|
-- checks in subquery, both ok
|
||||||
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
||||||
a | b
|
a | b
|
||||||
@ -227,7 +227,7 @@ ERROR: language "c" is not trusted
|
|||||||
HINT: Only superusers may use untrusted languages.
|
HINT: Only superusers may use untrusted languages.
|
||||||
SET SESSION AUTHORIZATION regressuser1;
|
SET SESSION AUTHORIZATION regressuser1;
|
||||||
GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
|
GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
|
||||||
WARNING: no privileges were granted
|
WARNING: no privileges were granted for "sql"
|
||||||
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
|
CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
|
||||||
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
|
CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
|
||||||
REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
|
REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
|
||||||
@ -551,7 +551,7 @@ GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
|
|||||||
SET SESSION AUTHORIZATION regressuser2;
|
SET SESSION AUTHORIZATION regressuser2;
|
||||||
GRANT SELECT ON atest4 TO regressuser3;
|
GRANT SELECT ON atest4 TO regressuser3;
|
||||||
GRANT UPDATE ON atest4 TO regressuser3; -- fail
|
GRANT UPDATE ON atest4 TO regressuser3; -- fail
|
||||||
WARNING: no privileges were granted
|
WARNING: no privileges were granted for "atest4"
|
||||||
SET SESSION AUTHORIZATION regressuser1;
|
SET SESSION AUTHORIZATION regressuser1;
|
||||||
REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
|
REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
|
||||||
SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
|
SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user