1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-08 11:42:09 +03:00

Create an ALTER DEFAULT PRIVILEGES command, which allows users to adjust

the privileges that will be applied to subsequently-created objects.

Such adjustments are always per owning role, and can be restricted to objects
created in particular schemas too.  A notable benefit is that users can
override the traditional default privilege settings, eg, the PUBLIC EXECUTE
privilege traditionally granted by default for functions.

Petr Jelinek
This commit is contained in:
Tom Lane
2009-10-05 19:24:49 +00:00
parent 41f89e3bbc
commit 249724cb01
48 changed files with 2240 additions and 180 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.149 2009/08/03 21:11:39 joe Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.150 2009/10/05 19:24:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -77,6 +77,7 @@ static Acl *allocacl(int n);
static void check_acl(const Acl *acl);
static const char *aclparse(const char *s, AclItem *aip);
static bool aclitem_match(const AclItem *a1, const AclItem *a2);
static int aclitemComparator(const void *arg1, const void *arg2);
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
Oid ownerId);
static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs,
@ -382,6 +383,15 @@ allocacl(int n)
return new_acl;
}
/*
* Create a zero-entry ACL
*/
Acl *
make_empty_acl(void)
{
return allocacl(0);
}
/*
* Copy an ACL
*/
@ -423,6 +433,98 @@ aclconcat(const Acl *left_acl, const Acl *right_acl)
return result_acl;
}
/*
* Merge two ACLs
*
* This produces a properly merged ACL with no redundant entries.
* Returns NULL on NULL input.
*/
Acl *
aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
{
Acl *result_acl;
AclItem *aip;
int i,
num;
/* Check for cases where one or both are empty/null */
if (left_acl == NULL || ACL_NUM(left_acl) == 0)
{
if (right_acl == NULL || ACL_NUM(right_acl) == 0)
return NULL;
else
return aclcopy(right_acl);
}
else
{
if (right_acl == NULL || ACL_NUM(right_acl) == 0)
return aclcopy(left_acl);
}
/* Merge them the hard way, one item at a time */
result_acl = aclcopy(left_acl);
aip = ACL_DAT(right_acl);
num = ACL_NUM(right_acl);
for (i = 0; i < num; i++, aip++)
{
Acl *tmp_acl;
tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD,
ownerId, DROP_RESTRICT);
pfree(result_acl);
result_acl = tmp_acl;
}
return result_acl;
}
/*
* Sort the items in an ACL (into an arbitrary but consistent order)
*/
void
aclitemsort(Acl *acl)
{
if (acl != NULL && ACL_NUM(acl) > 1)
qsort(ACL_DAT(acl), ACL_NUM(acl), sizeof(AclItem), aclitemComparator);
}
/*
* Check if two ACLs are exactly equal
*
* This will not detect equality if the two arrays contain the same items
* in different orders. To handle that case, sort both inputs first,
* using aclitemsort().
*/
bool
aclequal(const Acl *left_acl, const Acl *right_acl)
{
/* Check for cases where one or both are empty/null */
if (left_acl == NULL || ACL_NUM(left_acl) == 0)
{
if (right_acl == NULL || ACL_NUM(right_acl) == 0)
return true;
else
return false;
}
else
{
if (right_acl == NULL || ACL_NUM(right_acl) == 0)
return false;
}
if (ACL_NUM(left_acl) != ACL_NUM(right_acl))
return false;
if (memcmp(ACL_DAT(left_acl),
ACL_DAT(right_acl),
ACL_NUM(left_acl) * sizeof(AclItem)) == 0)
return true;
return false;
}
/*
* Verify that an ACL array is acceptable (one-dimensional and has no nulls)
*/
@ -555,6 +657,31 @@ aclitem_match(const AclItem *a1, const AclItem *a2)
a1->ai_grantor == a2->ai_grantor;
}
/*
* aclitemComparator
* qsort comparison function for AclItems
*/
static int
aclitemComparator(const void *arg1, const void *arg2)
{
const AclItem *a1 = (const AclItem *) arg1;
const AclItem *a2 = (const AclItem *) arg2;
if (a1->ai_grantee > a2->ai_grantee)
return 1;
if (a1->ai_grantee < a2->ai_grantee)
return -1;
if (a1->ai_grantor > a2->ai_grantor)
return 1;
if (a1->ai_grantor < a2->ai_grantor)
return -1;
if (a1->ai_privs > a2->ai_privs)
return 1;
if (a1->ai_privs < a2->ai_privs)
return -1;
return 0;
}
/*
* aclitem equality operator
*/
@ -593,6 +720,9 @@ hash_aclitem(PG_FUNCTION_ARGS)
*
* Change this routine if you want to alter the default access policy for
* newly-created objects (or any object with a NULL acl entry).
*
* Note that these are the hard-wired "defaults" that are used in the
* absence of any pg_default_acl entry.
*/
Acl *
acldefault(GrantObjectType objtype, Oid ownerId)