aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/acl.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-06-05 19:34:56 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-06-05 19:34:56 +0000
commitfb97d2b6bf03929ea70293fee37539e132ec8519 (patch)
tree7a3cbe1ccc7690e2c78fa87ce151e44da677b1f2 /src/backend/utils/adt/acl.c
parentcdd230d62899455cc07ba1caf68387fb834d5bd2 (diff)
downloadpostgresql-fb97d2b6bf03929ea70293fee37539e132ec8519.tar.gz
postgresql-fb97d2b6bf03929ea70293fee37539e132ec8519.zip
Correct permissions-checking bugs associated with ancient decision to
copy PUBLIC access rights into each newly created ACL entry. Instead treat each ACL entry as independent flags. Also clean up some ugliness in acl.h API.
Diffstat (limited to 'src/backend/utils/adt/acl.c')
-rw-r--r--src/backend/utils/adt/acl.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index f4e3fe9986d..1da525bd032 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,14 +8,14 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.59 2001/05/27 09:59:30 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.60 2001/06/05 19:34:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-#include <ctype.h>
-
#include "postgres.h"
+#include <ctype.h>
+
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/pg_shadow.h"
@@ -392,7 +392,8 @@ acldefault(char *relname, AclId ownerid)
/*
- * Add or replace an item in an ACL array.
+ * Add or replace an item in an ACL array. The result is a modified copy;
+ * the input object is not changed.
*
* NB: caller is responsible for having detoasted the input ACL, if needed.
*/
@@ -402,8 +403,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
Acl *new_acl;
AclItem *old_aip,
*new_aip;
- int src,
- dst,
+ int dst,
num;
/* These checks for null input are probably dead code, but... */
@@ -431,14 +431,14 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
if (dst < num && aclitemeq(mod_aip, old_aip + dst))
{
- /* modify in-place */
+ /* found a match, so modify existing item */
new_acl = makeacl(num);
new_aip = ACL_DAT(new_acl);
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
- src = dst;
}
else
{
+ /* need to insert a new item */
new_acl = makeacl(num + 1);
new_aip = ACL_DAT(new_acl);
if (dst == 0)
@@ -460,20 +460,21 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
(char *) (old_aip + dst),
(num - dst) * sizeof(AclItem));
}
+ /* initialize the new entry with no permissions */
new_aip[dst].ai_id = mod_aip->ai_id;
new_aip[dst].ai_idtype = mod_aip->ai_idtype;
+ new_aip[dst].ai_mode = 0;
num++; /* set num to the size of new_acl */
- src = 0; /* if add or del, start from world entry */
}
/* apply the permissions mod */
switch (modechg)
{
case ACL_MODECHG_ADD:
- new_aip[dst].ai_mode = old_aip[src].ai_mode | mod_aip->ai_mode;
+ new_aip[dst].ai_mode |= mod_aip->ai_mode;
break;
case ACL_MODECHG_DEL:
- new_aip[dst].ai_mode = old_aip[src].ai_mode & ~mod_aip->ai_mode;
+ new_aip[dst].ai_mode &= ~mod_aip->ai_mode;
break;
case ACL_MODECHG_EQL:
new_aip[dst].ai_mode = mod_aip->ai_mode;
@@ -487,16 +488,10 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
*/
if (new_aip[dst].ai_mode == 0 && dst > 0)
{
- int i;
-
- for (i = dst + 1; i < num; i++)
- {
- new_aip[i - 1].ai_id = new_aip[i].ai_id;
- new_aip[i - 1].ai_idtype = new_aip[i].ai_idtype;
- new_aip[i - 1].ai_mode = new_aip[i].ai_mode;
- }
+ memmove((char *) (new_aip + dst),
+ (char *) (new_aip + dst + 1),
+ (num - dst - 1) * sizeof(AclItem));
ARR_DIMS(new_acl)[0] = num - 1;
- /* Adjust also the array size because it is used for memcpy */
ARR_SIZE(new_acl) -= sizeof(AclItem);
}