Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+38-32
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)