|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.128 2005/11/17 22:14:52 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.129 2005/11/18 02:38:23 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -67,6 +67,7 @@ static List *cached_membership_roles = NIL;
|
67 | 67 | static const char *getid(const char *s, char *n);
|
68 | 68 | static void putid(char *p, const char *s);
|
69 | 69 | static Acl *allocacl(int n);
|
| 70 | +static void check_acl(const Acl *acl); |
70 | 71 | static const char *aclparse(const char *s, AclItem *aip);
|
71 | 72 | static bool aclitem_match(const AclItem *a1, const AclItem *a2);
|
72 | 73 | static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
|
@@ -359,6 +360,26 @@ allocacl(int n)
|
359 | 360 | return new_acl;
|
360 | 361 | }
|
361 | 362 |
|
| 363 | +/* |
| 364 | + * Verify that an ACL array is acceptable (one-dimensional and has no nulls) |
| 365 | + */ |
| 366 | +static void |
| 367 | +check_acl(const Acl *acl) |
| 368 | +{ |
| 369 | + if (ARR_ELEMTYPE(acl) != ACLITEMOID) |
| 370 | + ereport(ERROR, |
| 371 | + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 372 | + errmsg("ACL array contains wrong datatype"))); |
| 373 | + if (ARR_NDIM(acl) != 1) |
| 374 | + ereport(ERROR, |
| 375 | + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 376 | + errmsg("ACL arrays must be one-dimensional"))); |
| 377 | + if (ARR_HASNULL(acl)) |
| 378 | + ereport(ERROR, |
| 379 | + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 380 | + errmsg("ACL arrays must not contain nulls"))); |
| 381 | +} |
| 382 | + |
362 | 383 | /*
|
363 | 384 | * aclitemin
|
364 | 385 | * Allocates storage for, and fills in, a new AclItem given a string
|
@@ -612,15 +633,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
|
612 | 633 | int dst,
|
613 | 634 | num;
|
614 | 635 |
|
615 |
| - /* These checks for null input are probably dead code, but... */ |
616 |
| - if (!old_acl || ACL_NUM(old_acl) < 0) |
617 |
| - old_acl = allocacl(0); |
618 |
| - if (!mod_aip) |
619 |
| - { |
620 |
| - new_acl = allocacl(ACL_NUM(old_acl)); |
621 |
| - memcpy(new_acl, old_acl, ACL_SIZE(old_acl)); |
622 |
| - return new_acl; |
623 |
| - } |
| 636 | + /* Caller probably already checked old_acl, but be safe */ |
| 637 | + check_acl(old_acl); |
624 | 638 |
|
625 | 639 | /* If granting grant options, check for circularity */
|
626 | 640 | if (modechg != ACL_MODECHG_DEL &&
|
@@ -740,6 +754,8 @@ aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
|
740 | 754 | targ,
|
741 | 755 | num;
|
742 | 756 |
|
| 757 | + check_acl(old_acl); |
| 758 | + |
743 | 759 | /*
|
744 | 760 | * Make a copy of the given ACL, substituting new owner ID for old
|
745 | 761 | * wherever it appears as either grantor or grantee. Also note if the new
|
@@ -836,6 +852,8 @@ check_circularity(const Acl *old_acl, const AclItem *mod_aip,
|
836 | 852 | num;
|
837 | 853 | AclMode own_privs;
|
838 | 854 |
|
| 855 | + check_acl(old_acl); |
| 856 | + |
839 | 857 | /*
|
840 | 858 | * For now, grant options can only be granted to roles, not PUBLIC.
|
841 | 859 | * Otherwise we'd have to work a bit harder here.
|
@@ -916,6 +934,8 @@ recursive_revoke(Acl *acl,
|
916 | 934 | int i,
|
917 | 935 | num;
|
918 | 936 |
|
| 937 | + check_acl(acl); |
| 938 | + |
919 | 939 | /* The owner can never truly lose grant options, so short-circuit */
|
920 | 940 | if (grantee == ownerId)
|
921 | 941 | return acl;
|
@@ -1005,6 +1025,8 @@ aclmask(const Acl *acl, Oid roleid, Oid ownerId,
|
1005 | 1025 | if (acl == NULL)
|
1006 | 1026 | elog(ERROR, "null ACL");
|
1007 | 1027 |
|
| 1028 | + check_acl(acl); |
| 1029 | + |
1008 | 1030 | /* Quick exit for mask == 0 */
|
1009 | 1031 | if (mask == 0)
|
1010 | 1032 | return 0;
|
@@ -1091,6 +1113,8 @@ aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId,
|
1091 | 1113 | if (acl == NULL)
|
1092 | 1114 | elog(ERROR, "null ACL");
|
1093 | 1115 |
|
| 1116 | + check_acl(acl); |
| 1117 | + |
1094 | 1118 | /* Quick exit for mask == 0 */
|
1095 | 1119 | if (mask == 0)
|
1096 | 1120 | return 0;
|
@@ -1151,6 +1175,8 @@ aclmembers(const Acl *acl, Oid **roleids)
|
1151 | 1175 | return 0;
|
1152 | 1176 | }
|
1153 | 1177 |
|
| 1178 | + check_acl(acl); |
| 1179 | + |
1154 | 1180 | /* Allocate the worst-case space requirement */
|
1155 | 1181 | list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
|
1156 | 1182 | acldat = ACL_DAT(acl);
|
@@ -1240,6 +1266,7 @@ aclcontains(PG_FUNCTION_ARGS)
|
1240 | 1266 | int i,
|
1241 | 1267 | num;
|
1242 | 1268 |
|
| 1269 | + check_acl(acl); |
1243 | 1270 | num = ACL_NUM(acl);
|
1244 | 1271 | aidat = ACL_DAT(acl);
|
1245 | 1272 | for (i = 0; i < num; ++i)
|
|
0 commit comments