|
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 | staticconstchar*getid(constchar*s,char*n); |
68 | 68 | staticvoidputid(char*p,constchar*s); |
69 | 69 | staticAcl*allocacl(intn); |
| 70 | +staticvoidcheck_acl(constAcl*acl); |
70 | 71 | staticconstchar*aclparse(constchar*s,AclItem*aip); |
71 | 72 | staticboolaclitem_match(constAclItem*a1,constAclItem*a2); |
72 | 73 | staticvoidcheck_circularity(constAcl*old_acl,constAclItem*mod_aip, |
@@ -359,6 +360,26 @@ allocacl(int n) |
359 | 360 | returnnew_acl; |
360 | 361 | } |
361 | 362 |
|
| 363 | +/* |
| 364 | + * Verify that an ACL array is acceptable (one-dimensional and has no nulls) |
| 365 | + */ |
| 366 | +staticvoid |
| 367 | +check_acl(constAcl*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 | intdst, |
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 | | -returnnew_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 | AclModeown_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 | inti, |
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 | returnacl; |
@@ -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 | return0; |
@@ -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 | return0; |
@@ -1151,6 +1175,8 @@ aclmembers(const Acl *acl, Oid **roleids) |
1151 | 1175 | return0; |
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 | inti, |
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) |
|