Skip to content

Commit aceec9a

Browse files
committed
Fix bug reported by bobson: aclinsert3 would delete the 'world' entry
from an ACL list if it had no permissions remaining, which confused aclcheck terribly. Also clean up code a little.
1 parent dfda21e commit aceec9a

File tree

1 file changed

+38
-32
lines changed
  • src/backend/utils/adt

1 file changed

+38
-32
lines changed

src/backend/utils/adt/acl.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.51 2000/10/16 17:08:08 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.52 2000/11/03 19:01:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -212,8 +212,7 @@ makeacl(int n)
212212
if (n < 0)
213213
elog(ERROR, "makeacl: invalid size: %d", n);
214214
size = ACL_N_SIZE(n);
215-
if (!(new_acl = (Acl *) palloc(size)))
216-
elog(ERROR, "makeacl: palloc failed on %d", size);
215+
new_acl = (Acl *) palloc(size);
217216
MemSet((char *) new_acl, 0, size);
218217
new_acl->size = size;
219218
new_acl->ndim = 1;
@@ -382,7 +381,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
382381

383382
/* These checks for null input are probably dead code, but... */
384383
if (!old_acl || ACL_NUM(old_acl) < 1)
385-
old_acl = makeacl(0);
384+
old_acl = makeacl(1);
386385
if (!mod_aip)
387386
{
388387
new_acl = makeacl(ACL_NUM(old_acl));
@@ -402,12 +401,13 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
402401
/* find the first element not less than the element to be inserted */
403402
for (dst = 0; dst < num && aclitemgt(mod_aip, old_aip + dst); ++dst)
404403
;
404+
405405
if (dst < num && aclitemeq(mod_aip, old_aip + dst))
406406
{
407407
/* modify in-place */
408-
new_acl = makeacl(ACL_NUM(old_acl));
409-
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
408+
new_acl = makeacl(num);
410409
new_aip = ACL_DAT(new_acl);
410+
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
411411
src = dst;
412412
}
413413
else
@@ -420,24 +420,26 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
420420
}
421421
else if (dst >= num)
422422
{ /* end */
423-
memmove((char *) new_aip,
424-
(char *) old_aip,
425-
num * sizeof(AclItem));
423+
memcpy((char *) new_aip,
424+
(char *) old_aip,
425+
num * sizeof(AclItem));
426426
}
427427
else
428428
{ /* middle */
429-
memmove((char *) new_aip,
430-
(char *) old_aip,
431-
dst * sizeof(AclItem));
432-
memmove((char *) (new_aip + dst + 1),
433-
(char *) (old_aip + dst),
434-
(num - dst) * sizeof(AclItem));
429+
memcpy((char *) new_aip,
430+
(char *) old_aip,
431+
dst * sizeof(AclItem));
432+
memcpy((char *) (new_aip + dst + 1),
433+
(char *) (old_aip + dst),
434+
(num - dst) * sizeof(AclItem));
435435
}
436436
new_aip[dst].ai_id = mod_aip->ai_id;
437437
new_aip[dst].ai_idtype = mod_aip->ai_idtype;
438438
num++; /* set num to the size of new_acl */
439-
src = 0; /* world entry */
439+
src = 0; /* if add or del, start from world entry */
440440
}
441+
442+
/* apply the permissions mod */
441443
switch (modechg)
442444
{
443445
case ACL_MODECHG_ADD:
@@ -452,11 +454,11 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
452454
}
453455

454456
/*
455-
* if the newly added entry has no permissions, delete it from the
457+
* if the adjusted entry has no permissions, delete it from the
456458
* list. For example, this helps in removing entries for users who no
457-
* longer exist...
459+
* longer exist. EXCEPTION: never remove the world entry.
458460
*/
459-
if (new_aip[dst].ai_mode == 0)
461+
if (new_aip[dst].ai_mode == 0 && dst > 0)
460462
{
461463
int i;
462464

@@ -467,7 +469,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
467469
new_aip[i - 1].ai_mode = new_aip[i].ai_mode;
468470
}
469471
ARR_DIMS(new_acl)[0] = num - 1;
470-
/* Adjust also the array size because it is used for memmove */
472+
/* Adjust also the array size because it is used for memcpy */
471473
ARR_SIZE(new_acl) -= sizeof(AclItem);
472474
}
473475

@@ -500,7 +502,7 @@ aclremove(PG_FUNCTION_ARGS)
500502

501503
/* These checks for null input should be dead code, but... */
502504
if (!old_acl || ACL_NUM(old_acl) < 1)
503-
old_acl = makeacl(0);
505+
old_acl = makeacl(1);
504506
if (!mod_aip)
505507
{
506508
new_acl = makeacl(ACL_NUM(old_acl));
@@ -511,11 +513,14 @@ aclremove(PG_FUNCTION_ARGS)
511513
old_num = ACL_NUM(old_acl);
512514
old_aip = ACL_DAT(old_acl);
513515

516+
/* Search for the matching entry */
514517
for (dst = 0; dst < old_num && !aclitemeq(mod_aip, old_aip + dst); ++dst)
515518
;
519+
516520
if (dst >= old_num)
517-
{ /* not found or empty */
518-
new_acl = makeacl(ACL_NUM(old_acl));
521+
{
522+
/* Not found, so return copy of source ACL */
523+
new_acl = makeacl(old_num);
519524
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
520525
}
521526
else
@@ -529,20 +534,21 @@ aclremove(PG_FUNCTION_ARGS)
529534
}
530535
else if (dst == old_num - 1)
531536
{ /* end */
532-
memmove((char *) new_aip,
533-
(char *) old_aip,
534-
new_num * sizeof(AclItem));
537+
memcpy((char *) new_aip,
538+
(char *) old_aip,
539+
new_num * sizeof(AclItem));
535540
}
536541
else
537542
{ /* middle */
538-
memmove((char *) new_aip,
539-
(char *) old_aip,
540-
dst * sizeof(AclItem));
541-
memmove((char *) (new_aip + dst),
542-
(char *) (old_aip + dst + 1),
543-
(new_num - dst) * sizeof(AclItem));
543+
memcpy((char *) new_aip,
544+
(char *) old_aip,
545+
dst * sizeof(AclItem));
546+
memcpy((char *) (new_aip + dst),
547+
(char *) (old_aip + dst + 1),
548+
(new_num - dst) * sizeof(AclItem));
544549
}
545550
}
551+
546552
PG_RETURN_ACL_P(new_acl);
547553
}
548554

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy