Commit 7415e083 authored by Alvaro Herrera's avatar Alvaro Herrera

Refactor some bits in aclchk.c in order to reduce code duplication.

parent 164442fe
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.122 2005/11/22 18:17:07 momjian Exp $ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.123 2005/12/01 02:03:00 alvherre Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
...@@ -42,28 +42,22 @@ ...@@ -42,28 +42,22 @@
#include "utils/syscache.h" #include "utils/syscache.h"
static void ExecGrant_Relation(bool is_grant, List *objects, bool all_privs, static void ExecGrant_Relation(InternalGrant *grantStmt);
AclMode privileges, List *grantees, bool grant_option, static void ExecGrant_Database(InternalGrant *grantStmt);
DropBehavior behavior); static void ExecGrant_Function(InternalGrant *grantStmt);
static void ExecGrant_Database(bool is_grant, List *objects, bool all_privs, static void ExecGrant_Language(InternalGrant *grantStmt);
AclMode privileges, List *grantees, bool grant_option, static void ExecGrant_Namespace(InternalGrant *grantStmt);
DropBehavior behavior); static void ExecGrant_Tablespace(InternalGrant *grantStmt);
static void ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior);
static void ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior);
static void ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior);
static void ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior);
static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
static List *objectNamesToOids(GrantObjectType objtype, List *objnames);
static AclMode string_to_privilege(const char *privname); static AclMode string_to_privilege(const char *privname);
static const char *privilege_to_string(AclMode privilege); static const char *privilege_to_string(AclMode privilege);
static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions,
bool all_privs, AclMode privileges,
Oid objectId, Oid grantorId,
AclObjectKind objkind, char *objname);
static AclMode pg_aclmask(AclObjectKind objkind, Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how);
#ifdef ACLDEBUG #ifdef ACLDEBUG
...@@ -153,6 +147,91 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant, ...@@ -153,6 +147,91 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
return new_acl; return new_acl;
} }
/*
* Restrict the privileges to what we can actually grant, and emit
* the standards-mandated warning and error messages.
*/
static AclMode
restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs,
AclMode privileges, Oid objectId, Oid grantorId,
AclObjectKind objkind, char *objname)
{
AclMode this_privileges;
AclMode whole_mask;
switch (objkind)
{
case ACL_KIND_CLASS:
whole_mask = ACL_ALL_RIGHTS_RELATION;
break;
case ACL_KIND_DATABASE:
whole_mask = ACL_ALL_RIGHTS_DATABASE;
break;
case ACL_KIND_PROC:
whole_mask = ACL_ALL_RIGHTS_FUNCTION;
break;
case ACL_KIND_LANGUAGE:
whole_mask = ACL_ALL_RIGHTS_LANGUAGE;
break;
case ACL_KIND_NAMESPACE:
whole_mask = ACL_ALL_RIGHTS_NAMESPACE;
break;
case ACL_KIND_TABLESPACE:
whole_mask = ACL_ALL_RIGHTS_TABLESPACE;
break;
default:
elog(ERROR, "unrecognized object kind: %d", objkind);
/* not reached, but keep compiler quiet */
return ACL_NO_RIGHTS;
}
/*
* If we found no grant options, consider whether to issue a hard
* error. Per spec, having any privilege at all on the object will
* get you by here.
*/
if (avail_goptions == ACL_NO_RIGHTS)
{
if (pg_aclmask(objkind, objectId, grantorId,
whole_mask | ACL_GRANT_OPTION_FOR(whole_mask),
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, objkind, objname);
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
if (is_grant)
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
return this_privileges;
}
/* /*
* Called to execute the utility commands GRANT and REVOKE * Called to execute the utility commands GRANT and REVOKE
...@@ -160,13 +239,24 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant, ...@@ -160,13 +239,24 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
void void
ExecuteGrantStmt(GrantStmt *stmt) ExecuteGrantStmt(GrantStmt *stmt)
{ {
List *objects; InternalGrant istmt;
List *grantees = NIL;
AclMode privileges;
ListCell *cell; ListCell *cell;
bool all_privs; char *errormsg;
AclMode all_privileges = (AclMode) 0; AclMode all_privileges;
char *errormsg = NULL;
/*
* Turn the regular GrantStmt into the InternalGrant form.
*/
istmt.is_grant = stmt->is_grant;
istmt.objtype = stmt->objtype;
istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects);
/* all_privs to be filled below */
/* privileges to be filled below */
istmt.grantees = NIL;
/* filled below */
istmt.grant_option = stmt->grant_option;
istmt.behavior = stmt->behavior;
/* /*
* Convert the PrivGrantee list into an Oid list. Note that at this point * Convert the PrivGrantee list into an Oid list. Note that at this point
...@@ -180,15 +270,15 @@ ExecuteGrantStmt(GrantStmt *stmt) ...@@ -180,15 +270,15 @@ ExecuteGrantStmt(GrantStmt *stmt)
PrivGrantee *grantee = (PrivGrantee *) lfirst(cell); PrivGrantee *grantee = (PrivGrantee *) lfirst(cell);
if (grantee->rolname == NULL) if (grantee->rolname == NULL)
grantees = lappend_oid(grantees, ACL_ID_PUBLIC); istmt.grantees = lappend_oid(istmt.grantees, ACL_ID_PUBLIC);
else else
grantees = lappend_oid(grantees, istmt.grantees =
get_roleid_checked(grantee->rolname)); lappend_oid(istmt.grantees,
get_roleid_checked(grantee->rolname));
} }
/* /*
* Convert stmt->privileges, a textual list, into an AclMode bitmask * Convert stmt->privileges, a textual list, into an AclMode bitmask.
* appropiate for the given object class.
*/ */
switch (stmt->objtype) switch (stmt->objtype)
{ {
...@@ -217,19 +307,26 @@ ExecuteGrantStmt(GrantStmt *stmt) ...@@ -217,19 +307,26 @@ ExecuteGrantStmt(GrantStmt *stmt)
errormsg = _("invalid privilege type %s for tablespace"); errormsg = _("invalid privilege type %s for tablespace");
break; break;
default: default:
/* keep compiler quiet */
all_privileges = ACL_NO_RIGHTS;
errormsg = NULL;
elog(ERROR, "unrecognized GrantStmt.objtype: %d", elog(ERROR, "unrecognized GrantStmt.objtype: %d",
(int) stmt->objtype); (int) stmt->objtype);
} }
if (stmt->privileges == NIL) if (stmt->privileges == NIL)
{ {
all_privs = true; istmt.all_privs = true;
privileges = all_privileges; /*
* will be turned into ACL_ALL_RIGHTS_* by the internal routines
* depending on the object type
*/
istmt.privileges = ACL_NO_RIGHTS;
} }
else else
{ {
all_privs = false; istmt.all_privs = false;
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));
...@@ -241,61 +338,44 @@ ExecuteGrantStmt(GrantStmt *stmt) ...@@ -241,61 +338,44 @@ ExecuteGrantStmt(GrantStmt *stmt)
errmsg(errormsg, errmsg(errormsg,
privilege_to_string(priv)))); privilege_to_string(priv))));
privileges |= priv; istmt.privileges |= priv;
} }
} }
/* Turn the list of object names into an Oid list */ ExecGrantStmt_oids(&istmt);
objects = objectNamesToOids(stmt->objtype, stmt->objects);
ExecGrantStmt_oids(stmt->is_grant, stmt->objtype, objects, all_privs,
privileges, grantees, stmt->grant_option,
stmt->behavior);
} }
/* /*
* ExecGrantStmt_oids * ExecGrantStmt_oids
* *
* "Internal" entrypoint for granting and revoking privileges. The arguments * "Internal" entrypoint for granting and revoking privileges.
* it receives are lists of Oids or have been otherwise converted from text
* format to internal format.
*/ */
void void
ExecGrantStmt_oids(bool is_grant, GrantObjectType objtype, List *objects, ExecGrantStmt_oids(InternalGrant *istmt)
bool all_privs, AclMode privileges, List *grantees,
bool grant_option, DropBehavior behavior)
{ {
switch (objtype) switch (istmt->objtype)
{ {
case ACL_OBJECT_RELATION: case ACL_OBJECT_RELATION:
ExecGrant_Relation(is_grant, objects, all_privs, privileges, ExecGrant_Relation(istmt);
grantees, grant_option, behavior);
break; break;
case ACL_OBJECT_DATABASE: case ACL_OBJECT_DATABASE:
ExecGrant_Database(is_grant, objects, all_privs, privileges, ExecGrant_Database(istmt);
grantees, grant_option, behavior);
break; break;
case ACL_OBJECT_FUNCTION: case ACL_OBJECT_FUNCTION:
ExecGrant_Function(is_grant, objects, all_privs, privileges, ExecGrant_Function(istmt);
grantees, grant_option, behavior);
break; break;
case ACL_OBJECT_LANGUAGE: case ACL_OBJECT_LANGUAGE:
ExecGrant_Language(is_grant, objects, all_privs, privileges, ExecGrant_Language(istmt);
grantees, grant_option, behavior);
break; break;
case ACL_OBJECT_NAMESPACE: case ACL_OBJECT_NAMESPACE:
ExecGrant_Namespace(is_grant, objects, all_privs, ExecGrant_Namespace(istmt);
privileges, grantees, grant_option,
behavior);
break; break;
case ACL_OBJECT_TABLESPACE: case ACL_OBJECT_TABLESPACE:
ExecGrant_Tablespace(is_grant, objects, all_privs, ExecGrant_Tablespace(istmt);
privileges, grantees, grant_option,
behavior);
break; break;
default: default:
elog(ERROR, "unrecognized GrantStmt.objtype: %d", elog(ERROR, "unrecognized GrantStmt.objtype: %d",
(int) objtype); (int) istmt->objtype);
} }
} }
...@@ -444,19 +524,17 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) ...@@ -444,19 +524,17 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
} }
static void static void
ExecGrant_Relation(bool is_grant, List *objects, bool all_privs, ExecGrant_Relation(InternalGrant *istmt)
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior)
{ {
Relation relation; Relation relation;
ListCell *cell; ListCell *cell;
if (all_privs && privileges == ACL_NO_RIGHTS) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
privileges = ACL_ALL_RIGHTS_RELATION; istmt->privileges = ACL_ALL_RIGHTS_RELATION;
relation = heap_open(RelationRelationId, RowExclusiveLock); relation = heap_open(RelationRelationId, RowExclusiveLock);
foreach(cell, objects) foreach(cell, istmt->objects)
{ {
Oid relOid = lfirst_oid(cell); Oid relOid = lfirst_oid(cell);
Datum aclDatum; Datum aclDatum;
...@@ -512,56 +590,19 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs, ...@@ -512,56 +590,19 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
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(), privileges, select_best_grantor(GetUserId(), istmt->privileges,
old_acl, ownerId, old_acl, ownerId,
&grantorId, &avail_goptions); &grantorId, &avail_goptions);
/* /*
* If we found no grant options, consider whether to issue a hard * Restrict the privileges to what we can actually grant, and emit
* error. Per spec, having any privilege at all on the object will * the standards-mandated warning and error messages.
* get you by here.
*/ */
if (avail_goptions == ACL_NO_RIGHTS) this_privileges =
{ restrict_and_check_grant(istmt->is_grant, avail_goptions,
if (pg_class_aclmask(relOid, istmt->all_privs, istmt->privileges,
grantorId, relOid, grantorId, ACL_KIND_CLASS,
ACL_ALL_RIGHTS_RELATION | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_RELATION), NameStr(pg_class_tuple->relname));
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
NameStr(pg_class_tuple->relname));
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
if (is_grant)
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
/* /*
* Generate new ACL. * Generate new ACL.
...@@ -571,9 +612,9 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs, ...@@ -571,9 +612,9 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
*/ */
noldmembers = aclmembers(old_acl, &oldmembers); noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, is_grant, new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
grant_option, behavior, istmt->grant_option, istmt->behavior,
grantees, this_privileges, istmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
...@@ -595,7 +636,7 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs, ...@@ -595,7 +636,7 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
/* Update the shared dependency ACL info */ /* Update the shared dependency ACL info */
updateAclDependencies(RelationRelationId, relOid, updateAclDependencies(RelationRelationId, relOid,
ownerId, is_grant, ownerId, istmt->is_grant,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
...@@ -611,19 +652,17 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs, ...@@ -611,19 +652,17 @@ ExecGrant_Relation(bool is_grant, List *objects, bool all_privs,
} }
static void static void
ExecGrant_Database(bool is_grant, List *objects, bool all_privs, ExecGrant_Database(InternalGrant *istmt)
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior)
{ {
Relation relation; Relation relation;
ListCell *cell; ListCell *cell;
if (all_privs && privileges == ACL_NO_RIGHTS) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
privileges = ACL_ALL_RIGHTS_DATABASE; istmt->privileges = ACL_ALL_RIGHTS_DATABASE;
relation = heap_open(DatabaseRelationId, RowExclusiveLock); relation = heap_open(DatabaseRelationId, RowExclusiveLock);
foreach(cell, objects) foreach(cell, istmt->objects)
{ {
Oid datId = lfirst_oid(cell); Oid datId = lfirst_oid(cell);
Form_pg_database pg_database_tuple; Form_pg_database pg_database_tuple;
...@@ -675,56 +714,19 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs, ...@@ -675,56 +714,19 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
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(), privileges, select_best_grantor(GetUserId(), istmt->privileges,
old_acl, ownerId, old_acl, ownerId,
&grantorId, &avail_goptions); &grantorId, &avail_goptions);
/* /*
* If we found no grant options, consider whether to issue a hard * Restrict the privileges to what we can actually grant, and emit
* error. Per spec, having any privilege at all on the object will * the standards-mandated warning and error messages.
* get you by here.
*/
if (avail_goptions == ACL_NO_RIGHTS)
{
if (pg_database_aclmask(HeapTupleGetOid(tuple),
grantorId,
ACL_ALL_RIGHTS_DATABASE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_DATABASE),
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_DATABASE,
NameStr(pg_database_tuple->datname));
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/ */
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions); this_privileges =
if (is_grant) restrict_and_check_grant(istmt->is_grant, avail_goptions,
{ istmt->all_privs, istmt->privileges,
if (this_privileges == 0) datId, grantorId, ACL_KIND_DATABASE,
ereport(WARNING, NameStr(pg_database_tuple->datname));
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
/* /*
* Generate new ACL. * Generate new ACL.
...@@ -734,9 +736,9 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs, ...@@ -734,9 +736,9 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
*/ */
noldmembers = aclmembers(old_acl, &oldmembers); noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, is_grant, new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
grant_option, behavior, istmt->grant_option, istmt->behavior,
grantees, this_privileges, istmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
...@@ -759,7 +761,7 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs, ...@@ -759,7 +761,7 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
/* Update the shared dependency ACL info */ /* Update the shared dependency ACL info */
updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple), updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple),
ownerId, is_grant, ownerId, istmt->is_grant,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
...@@ -775,19 +777,17 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs, ...@@ -775,19 +777,17 @@ ExecGrant_Database(bool is_grant, List *objects, bool all_privs,
} }
static void static void
ExecGrant_Function(bool is_grant, List *objects, bool all_privs, ExecGrant_Function(InternalGrant *istmt)
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior)
{ {
Relation relation; Relation relation;
ListCell *cell; ListCell *cell;
if (all_privs && privileges == ACL_NO_RIGHTS) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
privileges = ACL_ALL_RIGHTS_FUNCTION; istmt->privileges = ACL_ALL_RIGHTS_FUNCTION;
relation = heap_open(ProcedureRelationId, RowExclusiveLock); relation = heap_open(ProcedureRelationId, RowExclusiveLock);
foreach(cell, objects) foreach(cell, istmt->objects)
{ {
Oid funcId = lfirst_oid(cell); Oid funcId = lfirst_oid(cell);
Form_pg_proc pg_proc_tuple; Form_pg_proc pg_proc_tuple;
...@@ -830,56 +830,19 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs, ...@@ -830,56 +830,19 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
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(), privileges, select_best_grantor(GetUserId(), istmt->privileges,
old_acl, ownerId, old_acl, ownerId,
&grantorId, &avail_goptions); &grantorId, &avail_goptions);
/* /*
* If we found no grant options, consider whether to issue a hard * Restrict the privileges to what we can actually grant, and emit
* error. Per spec, having any privilege at all on the object will * the standards-mandated warning and error messages.
* get you by here.
*/ */
if (avail_goptions == ACL_NO_RIGHTS) this_privileges =
{ restrict_and_check_grant(istmt->is_grant, avail_goptions,
if (pg_proc_aclmask(funcId, istmt->all_privs, istmt->privileges,
grantorId, funcId, grantorId, ACL_KIND_PROC,
ACL_ALL_RIGHTS_FUNCTION | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_FUNCTION), NameStr(pg_proc_tuple->proname));
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_PROC,
NameStr(pg_proc_tuple->proname));
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
if (is_grant)
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
/* /*
* Generate new ACL. * Generate new ACL.
...@@ -889,9 +852,9 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs, ...@@ -889,9 +852,9 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
*/ */
noldmembers = aclmembers(old_acl, &oldmembers); noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, is_grant, new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
grant_option, behavior, istmt->grant_option, istmt->behavior,
grantees, this_privileges, istmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
...@@ -914,7 +877,7 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs, ...@@ -914,7 +877,7 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
/* Update the shared dependency ACL info */ /* Update the shared dependency ACL info */
updateAclDependencies(ProcedureRelationId, funcId, updateAclDependencies(ProcedureRelationId, funcId,
ownerId, is_grant, ownerId, istmt->is_grant,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
...@@ -930,21 +893,19 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs, ...@@ -930,21 +893,19 @@ ExecGrant_Function(bool is_grant, List *objects, bool all_privs,
} }
static void static void
ExecGrant_Language(bool is_grant, List *objects, bool all_privs, ExecGrant_Language(InternalGrant *istmt)
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior)
{ {
Relation relation; Relation relation;
ListCell *cell; ListCell *cell;
if (all_privs && privileges == ACL_NO_RIGHTS) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
privileges = ACL_ALL_RIGHTS_LANGUAGE; istmt->privileges = ACL_ALL_RIGHTS_LANGUAGE;
relation = heap_open(LanguageRelationId, RowExclusiveLock); relation = heap_open(LanguageRelationId, RowExclusiveLock);
foreach(cell, objects) foreach(cell, istmt->objects)
{ {
Oid langid = lfirst_oid(cell); Oid langId = lfirst_oid(cell);
Form_pg_language pg_language_tuple; Form_pg_language pg_language_tuple;
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
...@@ -965,10 +926,10 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs, ...@@ -965,10 +926,10 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
Oid *newmembers; Oid *newmembers;
tuple = SearchSysCache(LANGOID, tuple = SearchSysCache(LANGOID,
ObjectIdGetDatum(langid), ObjectIdGetDatum(langId),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for language %u", langid); elog(ERROR, "cache lookup failed for language %u", langId);
pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple); pg_language_tuple = (Form_pg_language) GETSTRUCT(tuple);
...@@ -995,56 +956,19 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs, ...@@ -995,56 +956,19 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
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(), privileges, select_best_grantor(GetUserId(), istmt->privileges,
old_acl, ownerId, old_acl, ownerId,
&grantorId, &avail_goptions); &grantorId, &avail_goptions);
/* /*
* If we found no grant options, consider whether to issue a hard * Restrict the privileges to what we can actually grant, and emit
* error. Per spec, having any privilege at all on the object will * the standards-mandated warning and error messages.
* get you by here.
*/ */
if (avail_goptions == ACL_NO_RIGHTS) this_privileges =
{ restrict_and_check_grant(istmt->is_grant, avail_goptions,
if (pg_language_aclmask(HeapTupleGetOid(tuple), istmt->all_privs, istmt->privileges,
grantorId, langId, grantorId, ACL_KIND_LANGUAGE,
ACL_ALL_RIGHTS_LANGUAGE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_LANGUAGE), NameStr(pg_language_tuple->lanname));
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_LANGUAGE,
NameStr(pg_language_tuple->lanname));
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
if (is_grant)
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
/* /*
* Generate new ACL. * Generate new ACL.
...@@ -1054,9 +978,9 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs, ...@@ -1054,9 +978,9 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
*/ */
noldmembers = aclmembers(old_acl, &oldmembers); noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, is_grant, new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
grant_option, behavior, istmt->grant_option, istmt->behavior,
grantees, this_privileges, istmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
...@@ -1079,7 +1003,7 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs, ...@@ -1079,7 +1003,7 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
/* Update the shared dependency ACL info */ /* Update the shared dependency ACL info */
updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple), updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple),
ownerId, is_grant, ownerId, istmt->is_grant,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
...@@ -1095,19 +1019,17 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs, ...@@ -1095,19 +1019,17 @@ ExecGrant_Language(bool is_grant, List *objects, bool all_privs,
} }
static void static void
ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs, ExecGrant_Namespace(InternalGrant *istmt)
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior)
{ {
Relation relation; Relation relation;
ListCell *cell; ListCell *cell;
if (all_privs && privileges == ACL_NO_RIGHTS) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
privileges = ACL_ALL_RIGHTS_NAMESPACE; istmt->privileges = ACL_ALL_RIGHTS_NAMESPACE;
relation = heap_open(NamespaceRelationId, RowExclusiveLock); relation = heap_open(NamespaceRelationId, RowExclusiveLock);
foreach(cell, objects) foreach(cell, istmt->objects)
{ {
Oid nspid = lfirst_oid(cell); Oid nspid = lfirst_oid(cell);
Form_pg_namespace pg_namespace_tuple; Form_pg_namespace pg_namespace_tuple;
...@@ -1151,56 +1073,19 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs, ...@@ -1151,56 +1073,19 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
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(), privileges, select_best_grantor(GetUserId(), istmt->privileges,
old_acl, ownerId, old_acl, ownerId,
&grantorId, &avail_goptions); &grantorId, &avail_goptions);
/* /*
* If we found no grant options, consider whether to issue a hard * Restrict the privileges to what we can actually grant, and emit
* error. Per spec, having any privilege at all on the object will * the standards-mandated warning and error messages.
* get you by here.
*/
if (avail_goptions == ACL_NO_RIGHTS)
{
if (pg_namespace_aclmask(HeapTupleGetOid(tuple),
grantorId,
ACL_ALL_RIGHTS_NAMESPACE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_NAMESPACE),
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_NAMESPACE,
NameStr(pg_namespace_tuple->nspname));
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/ */
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions); this_privileges =
if (is_grant) restrict_and_check_grant(istmt->is_grant, avail_goptions,
{ istmt->all_privs, istmt->privileges,
if (this_privileges == 0) nspid, grantorId, ACL_KIND_NAMESPACE,
ereport(WARNING, NameStr(pg_namespace_tuple->nspname));
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
/* /*
* Generate new ACL. * Generate new ACL.
...@@ -1210,9 +1095,9 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs, ...@@ -1210,9 +1095,9 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
*/ */
noldmembers = aclmembers(old_acl, &oldmembers); noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, is_grant, new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
grant_option, behavior, istmt->grant_option, istmt->behavior,
grantees, this_privileges, istmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
...@@ -1235,7 +1120,7 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs, ...@@ -1235,7 +1120,7 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
/* Update the shared dependency ACL info */ /* Update the shared dependency ACL info */
updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple), updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple),
ownerId, is_grant, ownerId, istmt->is_grant,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
...@@ -1251,19 +1136,17 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs, ...@@ -1251,19 +1136,17 @@ ExecGrant_Namespace(bool is_grant, List *objects, bool all_privs,
} }
static void static void
ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs, ExecGrant_Tablespace(InternalGrant *istmt)
AclMode privileges, List *grantees, bool grant_option,
DropBehavior behavior)
{ {
Relation relation; Relation relation;
ListCell *cell; ListCell *cell;
if (all_privs && privileges == ACL_NO_RIGHTS) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
privileges = ACL_ALL_RIGHTS_TABLESPACE; istmt->privileges = ACL_ALL_RIGHTS_TABLESPACE;
relation = heap_open(TableSpaceRelationId, RowExclusiveLock); relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
foreach(cell, objects) foreach(cell, istmt->objects)
{ {
Oid tblId = lfirst_oid(cell); Oid tblId = lfirst_oid(cell);
Form_pg_tablespace pg_tablespace_tuple; Form_pg_tablespace pg_tablespace_tuple;
...@@ -1313,56 +1196,19 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs, ...@@ -1313,56 +1196,19 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
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(), privileges, select_best_grantor(GetUserId(), istmt->privileges,
old_acl, ownerId, old_acl, ownerId,
&grantorId, &avail_goptions); &grantorId, &avail_goptions);
/* /*
* If we found no grant options, consider whether to issue a hard * Restrict the privileges to what we can actually grant, and emit
* error. Per spec, having any privilege at all on the object will * the standards-mandated warning and error messages.
* get you by here.
*/ */
if (avail_goptions == ACL_NO_RIGHTS) this_privileges =
{ restrict_and_check_grant(istmt->is_grant, avail_goptions,
if (pg_tablespace_aclmask(HeapTupleGetOid(tuple), istmt->all_privs, istmt->privileges,
grantorId, tblId, grantorId, ACL_KIND_TABLESPACE,
ACL_ALL_RIGHTS_TABLESPACE | ACL_GRANT_OPTION_FOR(ACL_ALL_RIGHTS_TABLESPACE), NameStr(pg_tablespace_tuple->spcname));
ACLMASK_ANY) == ACL_NO_RIGHTS)
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE,
NameStr(pg_tablespace_tuple->spcname));
}
/*
* Restrict the operation to what we can actually grant or revoke, and
* issue a warning if appropriate. (For REVOKE this isn't quite what
* the spec says to do: the spec seems to want a warning only if no
* privilege bits actually change in the ACL. In practice that
* behavior seems much too noisy, as well as inconsistent with the
* GRANT case.)
*/
this_privileges = privileges & ACL_OPTION_TO_PRIVS(avail_goptions);
if (is_grant)
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("no privileges were granted")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
errmsg("not all privileges were granted")));
}
else
{
if (this_privileges == 0)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("no privileges could be revoked")));
else if (!all_privs && this_privileges != privileges)
ereport(WARNING,
(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
errmsg("not all privileges could be revoked")));
}
/* /*
* Generate new ACL. * Generate new ACL.
...@@ -1372,9 +1218,9 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs, ...@@ -1372,9 +1218,9 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
*/ */
noldmembers = aclmembers(old_acl, &oldmembers); noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, is_grant, new_acl = merge_acl_with_grant(old_acl, istmt->is_grant,
grant_option, behavior, istmt->grant_option, istmt->behavior,
grantees, this_privileges, istmt->grantees, this_privileges,
grantorId, ownerId); grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers); nnewmembers = aclmembers(new_acl, &newmembers);
...@@ -1397,7 +1243,7 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs, ...@@ -1397,7 +1243,7 @@ ExecGrant_Tablespace(bool is_grant, List *objects, bool all_privs,
/* Update the shared dependency ACL info */ /* Update the shared dependency ACL info */
updateAclDependencies(TableSpaceRelationId, tblId, updateAclDependencies(TableSpaceRelationId, tblId,
ownerId, is_grant, ownerId, istmt->is_grant,
noldmembers, oldmembers, noldmembers, oldmembers,
nnewmembers, newmembers); nnewmembers, newmembers);
...@@ -1583,6 +1429,34 @@ has_rolcatupdate(Oid roleid) ...@@ -1583,6 +1429,34 @@ has_rolcatupdate(Oid roleid)
return rolcatupdate; return rolcatupdate;
} }
/*
* Relay for the various pg_*_mask routines depending on object kind
*/
static AclMode
pg_aclmask(AclObjectKind objkind, Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
switch (objkind)
{
case ACL_KIND_CLASS:
return pg_class_aclmask(table_oid, roleid, mask, how);
case ACL_KIND_DATABASE:
return pg_database_aclmask(table_oid, roleid, mask, how);
case ACL_KIND_PROC:
return pg_proc_aclmask(table_oid, roleid, mask, how);
case ACL_KIND_LANGUAGE:
return pg_language_aclmask(table_oid, roleid, mask, how);
case ACL_KIND_NAMESPACE:
return pg_namespace_aclmask(table_oid, roleid, mask, how);
case ACL_KIND_TABLESPACE:
return pg_tablespace_aclmask(table_oid, roleid, mask, how);
default:
elog(ERROR, "unrecognized objkind: %d",
(int) objkind);
/* not reached, but keep compiler quiet */
return ACL_NO_RIGHTS;
}
}
/* /*
* Exported routine for examining a user's privileges for a table * Exported routine for examining a user's privileges for a table
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.5 2005/11/22 18:17:08 momjian Exp $ * $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.6 2005/12/01 02:03:00 alvherre Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1122,6 +1122,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior) ...@@ -1122,6 +1122,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
{ {
ObjectAddress obj; ObjectAddress obj;
GrantObjectType objtype; GrantObjectType objtype;
InternalGrant istmt;
/* Shouldn't happen */ /* Shouldn't happen */
case SHARED_DEPENDENCY_PIN: case SHARED_DEPENDENCY_PIN:
...@@ -1132,22 +1133,22 @@ shdepDropOwned(List *roleids, DropBehavior behavior) ...@@ -1132,22 +1133,22 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
switch (sdepForm->classid) switch (sdepForm->classid)
{ {
case RelationRelationId: case RelationRelationId:
objtype = ACL_OBJECT_RELATION; istmt.objtype = ACL_OBJECT_RELATION;
break; break;
case DatabaseRelationId: case DatabaseRelationId:
objtype = ACL_OBJECT_DATABASE; istmt.objtype = ACL_OBJECT_DATABASE;
break; break;
case ProcedureRelationId: case ProcedureRelationId:
objtype = ACL_OBJECT_FUNCTION; istmt.objtype = ACL_OBJECT_FUNCTION;
break; break;
case LanguageRelationId: case LanguageRelationId:
objtype = ACL_OBJECT_LANGUAGE; istmt.objtype = ACL_OBJECT_LANGUAGE;
break; break;
case NamespaceRelationId: case NamespaceRelationId:
objtype = ACL_OBJECT_NAMESPACE; istmt.objtype = ACL_OBJECT_NAMESPACE;
break; break;
case TableSpaceRelationId: case TableSpaceRelationId:
objtype = ACL_OBJECT_TABLESPACE; istmt.objtype = ACL_OBJECT_TABLESPACE;
break; break;
default: default:
elog(ERROR, "unexpected object type %d", elog(ERROR, "unexpected object type %d",
...@@ -1156,11 +1157,15 @@ shdepDropOwned(List *roleids, DropBehavior behavior) ...@@ -1156,11 +1157,15 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
objtype = (GrantObjectType) 0; objtype = (GrantObjectType) 0;
break; break;
} }
istmt.is_grant = false;
ExecGrantStmt_oids(false, objtype, istmt.objects = list_make1_oid(sdepForm->objid);
list_make1_oid(sdepForm->objid), true, istmt.all_privs = true;
ACL_NO_RIGHTS, list_make1_oid(roleid), istmt.privileges = ACL_NO_RIGHTS;
false, DROP_CASCADE); istmt.grantees = list_make1_oid(roleid);
istmt.grant_option = false;
istmt.behavior = DROP_CASCADE;
ExecGrantStmt_oids(&istmt);
break; break;
case SHARED_DEPENDENCY_OWNER: case SHARED_DEPENDENCY_OWNER:
......
...@@ -7,7 +7,7 @@ ...@@ -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.90 2005/11/22 18:17:31 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.91 2005/12/01 02:03:01 alvherre 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
...@@ -181,6 +181,26 @@ typedef enum AclObjectKind ...@@ -181,6 +181,26 @@ typedef enum AclObjectKind
MAX_ACL_KIND /* MUST BE LAST */ MAX_ACL_KIND /* MUST BE LAST */
} AclObjectKind; } AclObjectKind;
/*
* The information about one Grant/Revoke statement, in internal format: object
* and grantees names have been turned into Oids, the privilege list is an
* AclMode bitmask. If 'privileges' is ACL_NO_RIGHTS (the 0 value) and
* all_privs is true, it will be internally turned into the right kind of
* ACL_ALL_RIGHTS_*, depending on the object type (NB - this will modify the
* InternalGrant struct!)
*/
typedef struct
{
bool is_grant;
GrantObjectType objtype;
List *objects;
bool all_privs;
AclMode privileges;
List *grantees;
bool grant_option;
DropBehavior behavior;
} InternalGrant;
/* /*
* routines used internally * routines used internally
*/ */
...@@ -221,9 +241,7 @@ extern Datum hash_aclitem(PG_FUNCTION_ARGS); ...@@ -221,9 +241,7 @@ extern Datum hash_aclitem(PG_FUNCTION_ARGS);
* prototypes for functions in aclchk.c * prototypes for functions in aclchk.c
*/ */
extern void ExecuteGrantStmt(GrantStmt *stmt); extern void ExecuteGrantStmt(GrantStmt *stmt);
extern void ExecGrantStmt_oids(bool is_grant, GrantObjectType objtype, extern void ExecGrantStmt_oids(InternalGrant *istmt);
List *objects, bool all_privs, AclMode privileges,
List *grantees, bool grant_option, DropBehavior behavior);
extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how); AclMode mask, AclMaskHow how);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment