├── CHANGELOG ├── LICENSE ├── META.json ├── Makefile ├── README.md ├── acl--1.0.0--1.0.1.sql ├── acl--1.0.1--1.0.2.sql ├── acl--1.0.2--1.0.3.sql ├── acl--1.0.3--1.0.4.sql ├── acl--1.0.4.sql ├── acl.c ├── acl.control ├── acl.h ├── acl.md ├── acl_int4.c ├── acl_int8.c ├── acl_oid.c ├── acl_uuid.c ├── benchmarks ├── benchmarks.sh ├── setup.sql ├── test_int4.sql ├── test_int8.sql ├── test_oid.sql └── test_uuid.sql ├── expected ├── acl_int4.out ├── acl_int4_pg12.out ├── acl_int8.out ├── acl_int8_pg12.out ├── acl_oid.out ├── acl_uuid.out ├── acl_uuid_pg10.out └── install.out ├── sql ├── acl_int4.sql ├── acl_int4_pg12.sql ├── acl_int8.sql ├── acl_int8_pg12.sql ├── acl_oid.sql ├── acl_uuid.sql ├── acl_uuid_pg10.sql └── install.sql ├── util.c └── util.h /CHANGELOG: -------------------------------------------------------------------------------- 1 | Version 1.0.0, released 2015-08-02 2 | - initial release 3 | 4 | Version 1.0.1, released 2015-08-27 5 | - fixed the bug with NULL values 6 | 7 | Version 1.0.2, released 2016-06-12 8 | - fixed access violation in Windows 9 | 10 | Version 1.0.3, released 2023-03-30 11 | - fixed bug in acl_extract_arguments with implicit_allow argument value ignored 12 | - support for PostgreSQL 10+ 13 | 14 | Version 1.0.4, released 2023-09-24 15 | - support for PostgreSQL 16 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2023, Vladislav Arkhipov 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "acl", 3 | "abstract": "Acess Control List (ACL) Extension", 4 | "description": "This extension provides support for ACL type.", 5 | "version": "1.0.4", 6 | "release_status": "stable", 7 | "maintainer": [ 8 | "Vladislav Arkhipov " 9 | ], 10 | "license": "bsd", 11 | "provides": { 12 | "acl": { 13 | "abstract": "Access Control List (ACL) Extension", 14 | "file": "acl--1.0.4.sql", 15 | "docfile": "acl.md", 16 | "version": "1.0.4" 17 | } 18 | }, 19 | "prereqs": { 20 | "runtime": { 21 | "requires": { 22 | "PostgreSQL": ">= 9.1.0" 23 | } 24 | } 25 | }, 26 | "resources": { 27 | "homepage": "https://arkhipov.ru", 28 | "repository": { 29 | "url": "https://github.com/arkhipov/acl.git", 30 | "web": "https://github.com/arkhipov/acl", 31 | "type": "git" 32 | }, 33 | "bugtracker": { 34 | "web": "https://github.com/arkhipov/acl/issues" 35 | } 36 | }, 37 | "generated_by": "Vladislav Arkhipov", 38 | "meta-spec": { 39 | "version": "1.0.0", 40 | "url": "http://pgxn.org/meta/spec.txt" 41 | }, 42 | "tags": [ 43 | "acl", 44 | "access control list", 45 | "fine-grained security", 46 | "ace", 47 | "security", 48 | "row-level security", 49 | "access control" 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # acl/Makefile 2 | 3 | MODULE_big = acl 4 | OBJS = acl.o acl_oid.o acl_uuid.o acl_int8.o acl_int4.o util.o 5 | 6 | PG_CPPFLAGS=-Wall 7 | 8 | EXTENSION = acl 9 | DATA = acl--1.0.4.sql \ 10 | acl--1.0.0--1.0.1.sql \ 11 | acl--1.0.1--1.0.2.sql \ 12 | acl--1.0.2--1.0.3.sql \ 13 | acl--1.0.3--1.0.4.sql 14 | DOCS = acl.md 15 | 16 | PG_CONFIG = pg_config 17 | PG_VERSION := $(shell $(PG_CONFIG) --version | cut -d '.' -f 1 | cut -d ' ' -f 2) 18 | 19 | ifeq ($(shell test $(PG_VERSION) -ge 12; echo $$?), 0) 20 | REGRESS = install acl_oid acl_uuid_pg10 acl_int8_pg12 acl_int4_pg12 21 | else ifeq ($(shell test $(PG_VERSION) -ge 10; echo $$?), 0) 22 | REGRESS = install acl_oid acl_uuid_pg10 acl_int8 acl_int4 23 | else 24 | REGRESS = install acl_oid acl_uuid acl_int8 acl_int4 25 | endif 26 | 27 | PGXS := $(shell $(PG_CONFIG) --pgxs) 28 | include $(PGXS) 29 | -------------------------------------------------------------------------------- /acl--1.0.0--1.0.1.sql: -------------------------------------------------------------------------------- 1 | /* acl/acl--1.0.0--1.0.1.sql */ 2 | 3 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 4 | \echo Use "ALTER EXTENSION acl UPDATE TO '1.0.1'" to load this file.\quit 5 | 6 | ALTER FUNCTION acl_check_access(ace[], text, bool) CALLED ON NULL INPUT; 7 | 8 | ALTER FUNCTION acl_check_access(ace[], int4, bool) CALLED ON NULL INPUT; 9 | 10 | ALTER FUNCTION acl_check_access(ace[], text, oid, bool) CALLED ON NULL INPUT; 11 | 12 | ALTER FUNCTION acl_check_access(ace[], int4, oid, bool) CALLED ON NULL INPUT; 13 | 14 | ALTER FUNCTION acl_check_access(ace[], text, name, bool) CALLED ON NULL INPUT; 15 | 16 | ALTER FUNCTION acl_check_access(ace[], int4, name, bool) CALLED ON NULL INPUT; 17 | 18 | ALTER FUNCTION acl_check_access(ace_uuid[], text, uuid[], bool) CALLED ON NULL INPUT; 19 | 20 | ALTER FUNCTION acl_check_access(ace_uuid[], int4, uuid[], bool) CALLED ON NULL INPUT; 21 | 22 | ALTER FUNCTION acl_check_access(ace_int4[], text, int4[], bool) CALLED ON NULL INPUT; 23 | 24 | ALTER FUNCTION acl_check_access(ace_int4[], int4, int4[], bool) CALLED ON NULL INPUT; 25 | 26 | ALTER FUNCTION acl_check_access(ace_int8[], text, int8[], bool) CALLED ON NULL INPUT; 27 | 28 | ALTER FUNCTION acl_check_access(ace_int8[], int4, int8[], bool) CALLED ON NULL INPUT; 29 | -------------------------------------------------------------------------------- /acl--1.0.1--1.0.2.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arkhipov/acl/144959ae4068eeb36e54cb53d89cb608742f7590/acl--1.0.1--1.0.2.sql -------------------------------------------------------------------------------- /acl--1.0.2--1.0.3.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arkhipov/acl/144959ae4068eeb36e54cb53d89cb608742f7590/acl--1.0.2--1.0.3.sql -------------------------------------------------------------------------------- /acl--1.0.3--1.0.4.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arkhipov/acl/144959ae4068eeb36e54cb53d89cb608742f7590/acl--1.0.3--1.0.4.sql -------------------------------------------------------------------------------- /acl--1.0.4.sql: -------------------------------------------------------------------------------- 1 | /* acl/acl--1.0.4.sql */ 2 | 3 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 4 | \echo Use "CREATE EXTENSION acl" to load this file.\quit 5 | 6 | -- Oid-based ACE 7 | CREATE FUNCTION ace_in(cstring) 8 | RETURNS ace 9 | AS 'MODULE_PATHNAME' 10 | LANGUAGE C STRICT IMMUTABLE; 11 | 12 | CREATE FUNCTION ace_out(ace) 13 | RETURNS cstring 14 | AS 'MODULE_PATHNAME' 15 | LANGUAGE C STRICT IMMUTABLE; 16 | 17 | CREATE TYPE ace ( 18 | INTERNALLENGTH = 16, 19 | INPUT = ace_in, 20 | OUTPUT = ace_out 21 | ); 22 | 23 | COMMENT ON TYPE ace IS 'access control list entry'; 24 | 25 | CREATE FUNCTION acl_check_access(ace[], text, bool) 26 | RETURNS text 27 | AS 'MODULE_PATHNAME', 'acl_check_access_text_current_user' 28 | LANGUAGE C STABLE; 29 | 30 | COMMENT ON FUNCTION acl_check_access(ace[], text, bool) IS 'determine if an ACL grants a specified set of permissions to the current user'; 31 | 32 | CREATE FUNCTION acl_check_access(ace[], int4, bool) 33 | RETURNS int4 34 | AS 'MODULE_PATHNAME', 'acl_check_access_int4_current_user' 35 | LANGUAGE C STABLE; 36 | 37 | COMMENT ON FUNCTION acl_check_access(ace[], int4, bool) IS 'determine if an ACL grants a specified set of permissions to the current user'; 38 | 39 | CREATE FUNCTION acl_check_access(ace[], text, oid, bool) 40 | RETURNS text 41 | AS 'MODULE_PATHNAME', 'acl_check_access_text_oid' 42 | LANGUAGE C STABLE; 43 | 44 | COMMENT ON FUNCTION acl_check_access(ace[], text, oid, bool) IS 'determine if an ACL grants a specified set of permissions to the role identified by oid'; 45 | 46 | CREATE FUNCTION acl_check_access(ace[], int4, oid, bool) 47 | RETURNS int4 48 | AS 'MODULE_PATHNAME', 'acl_check_access_int4_oid' 49 | LANGUAGE C STABLE; 50 | 51 | COMMENT ON FUNCTION acl_check_access(ace[], int4, oid, bool) IS 'determine if an ACL grants a specified set of permissions to the role identified by oid'; 52 | 53 | CREATE FUNCTION acl_check_access(ace[], text, name, bool) 54 | RETURNS text 55 | AS 'MODULE_PATHNAME', 'acl_check_access_text_name' 56 | LANGUAGE C STABLE; 57 | 58 | COMMENT ON FUNCTION acl_check_access(ace[], text, name, bool) IS 'determine if an ACL grants a specified set of permissions to the role identified by name'; 59 | 60 | CREATE FUNCTION acl_check_access(ace[], int4, name, bool) 61 | RETURNS int4 62 | AS 'MODULE_PATHNAME', 'acl_check_access_int4_name' 63 | LANGUAGE C STABLE; 64 | 65 | COMMENT ON FUNCTION acl_check_access(ace[], int4, name, bool) IS 'determine if an ACL grants a specified set of permissions to the role identified by name'; 66 | 67 | CREATE FUNCTION acl_merge(ace[], ace[], bool, bool) 68 | RETURNS ace[] 69 | AS 'MODULE_PATHNAME', 'acl_merge' 70 | LANGUAGE C IMMUTABLE; 71 | 72 | COMMENT ON FUNCTION acl_merge(ace[], ace[], bool, bool) IS 'merge two ACLs'; 73 | 74 | -- UUID-based ACE 75 | CREATE FUNCTION ace_uuid_in(cstring) 76 | RETURNS ace_uuid 77 | AS 'MODULE_PATHNAME' 78 | LANGUAGE C STRICT IMMUTABLE; 79 | 80 | CREATE FUNCTION ace_uuid_out(ace_uuid) 81 | RETURNS cstring 82 | AS 'MODULE_PATHNAME' 83 | LANGUAGE C STRICT IMMUTABLE; 84 | 85 | CREATE TYPE ace_uuid ( 86 | INTERNALLENGTH = 28, 87 | INPUT = ace_uuid_in, 88 | OUTPUT = ace_uuid_out 89 | ); 90 | 91 | COMMENT ON TYPE ace_uuid IS 'access control list entry (UUID-based)'; 92 | 93 | CREATE FUNCTION acl_check_access(ace_uuid[], text, uuid[], bool) 94 | RETURNS text 95 | AS 'MODULE_PATHNAME', 'acl_uuid_check_access_text' 96 | LANGUAGE C IMMUTABLE; 97 | 98 | COMMENT ON FUNCTION acl_check_access(ace_uuid[], text, uuid[], bool) IS 'determine if an ACL grants a specified set of permissions to the principal identified by UUIDs'; 99 | 100 | CREATE FUNCTION acl_check_access(ace_uuid[], int4, uuid[], bool) 101 | RETURNS int4 102 | AS 'MODULE_PATHNAME', 'acl_uuid_check_access_int4' 103 | LANGUAGE C IMMUTABLE; 104 | 105 | COMMENT ON FUNCTION acl_check_access(ace_uuid[], int4, uuid[], bool) IS 'determine if an ACL grants a specified set of permissions to the principal identified by UUIDs'; 106 | 107 | CREATE FUNCTION acl_merge(ace_uuid[], ace_uuid[], bool, bool) 108 | RETURNS ace_uuid[] 109 | AS 'MODULE_PATHNAME', 'acl_uuid_merge' 110 | LANGUAGE C IMMUTABLE; 111 | 112 | COMMENT ON FUNCTION acl_merge(ace_uuid[], ace_uuid[], bool, bool) IS 'merge two ACLs'; 113 | 114 | -- int4-based ACE 115 | CREATE FUNCTION ace_int4_in(cstring) 116 | RETURNS ace_int4 117 | AS 'MODULE_PATHNAME' 118 | LANGUAGE C STRICT IMMUTABLE; 119 | 120 | CREATE FUNCTION ace_int4_out(ace_int4) 121 | RETURNS cstring 122 | AS 'MODULE_PATHNAME' 123 | LANGUAGE C STRICT IMMUTABLE; 124 | 125 | CREATE TYPE ace_int4 ( 126 | INTERNALLENGTH = 16, 127 | INPUT = ace_int4_in, 128 | OUTPUT = ace_int4_out 129 | ); 130 | 131 | COMMENT ON TYPE ace_int4 IS 'access control list entry (int4-based)'; 132 | 133 | CREATE FUNCTION acl_check_access(ace_int4[], text, int4[], bool) 134 | RETURNS text 135 | AS 'MODULE_PATHNAME', 'acl_int4_check_access_text' 136 | LANGUAGE C IMMUTABLE; 137 | 138 | COMMENT ON FUNCTION acl_check_access(ace_int4[], text, int4[], bool) IS 'determine if an ACL grants a specified set of permissions to the principal identified by a set of int4s'; 139 | 140 | CREATE FUNCTION acl_check_access(ace_int4[], int4, int4[], bool) 141 | RETURNS int4 142 | AS 'MODULE_PATHNAME', 'acl_int4_check_access_int4' 143 | LANGUAGE C IMMUTABLE; 144 | 145 | COMMENT ON FUNCTION acl_check_access(ace_int4[], int4, int4[], bool) IS 'determine if an ACL grants a specified set of permissions to the principal identified by a set of int4s'; 146 | 147 | CREATE FUNCTION acl_merge(ace_int4[], ace_int4[], bool, bool) 148 | RETURNS ace_int4[] 149 | AS 'MODULE_PATHNAME', 'acl_int4_merge' 150 | LANGUAGE C IMMUTABLE; 151 | 152 | COMMENT ON FUNCTION acl_merge(ace_int4[], ace_int4[], bool, bool) IS 'merge two ACLs'; 153 | 154 | -- int8-based ACE 155 | CREATE FUNCTION ace_int8_in(cstring) 156 | RETURNS ace_int8 157 | AS 'MODULE_PATHNAME' 158 | LANGUAGE C STRICT IMMUTABLE; 159 | 160 | CREATE FUNCTION ace_int8_out(ace_int8) 161 | RETURNS cstring 162 | AS 'MODULE_PATHNAME' 163 | LANGUAGE C STRICT IMMUTABLE; 164 | 165 | CREATE TYPE ace_int8 ( 166 | INTERNALLENGTH = 20, 167 | INPUT = ace_int8_in, 168 | OUTPUT = ace_int8_out 169 | ); 170 | 171 | COMMENT ON TYPE ace_int8 IS 'access control list entry (int8-based)'; 172 | 173 | CREATE FUNCTION acl_check_access(ace_int8[], text, int8[], bool) 174 | RETURNS text 175 | AS 'MODULE_PATHNAME', 'acl_int8_check_access_text' 176 | LANGUAGE C IMMUTABLE; 177 | 178 | COMMENT ON FUNCTION acl_check_access(ace_int8[], text, int8[], bool) IS 'determine if an ACL grants a specified set of permissions to the principal identified by a set of int8s'; 179 | 180 | CREATE FUNCTION acl_check_access(ace_int8[], int4, int8[], bool) 181 | RETURNS int4 182 | AS 'MODULE_PATHNAME', 'acl_int8_check_access_int4' 183 | LANGUAGE C IMMUTABLE; 184 | 185 | COMMENT ON FUNCTION acl_check_access(ace_int8[], int4, int8[], bool) IS 'determine if an ACL grants a specified set of permissions to the principal identified by a set of int8s'; 186 | 187 | CREATE FUNCTION acl_merge(ace_int8[], ace_int8[], bool, bool) 188 | RETURNS ace_int8[] 189 | AS 'MODULE_PATHNAME', 'acl_int8_merge' 190 | LANGUAGE C IMMUTABLE; 191 | 192 | COMMENT ON FUNCTION acl_merge(ace_int8[], ace_int8[], bool, bool) IS 'merge two ACLs'; 193 | -------------------------------------------------------------------------------- /acl.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * acl.c 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #include "postgres.h" 10 | #include "fmgr.h" 11 | 12 | #if PG_VERSION_NUM >= 90300 13 | #include "access/htup_details.h" 14 | #endif 15 | #include "access/tupmacs.h" 16 | #include "utils/builtins.h" 17 | 18 | #include "acl.h" 19 | 20 | PG_MODULE_MAGIC; 21 | 22 | static char ace_type_chars[] = 23 | { 24 | 'a', // ACCESS_ALLOWED 25 | 'd' // ACCESS_DENIED 26 | }; 27 | 28 | #define ACE_ALL_TYPES_STR "ad" 29 | 30 | static char ace_flag_chars[] = 31 | { 32 | '0', 33 | '1', 34 | '2', 35 | '3', 36 | '4', 37 | '5', 38 | '6', 39 | '7', 40 | '8', 41 | '9', 42 | 'A', 43 | 'B', 44 | 'C', 45 | 'D', 46 | 'E', 47 | 'F', 48 | 49 | 'G', // RESERVED 50 | 'H', // RESERVED 51 | 'I', // RESERVED 52 | 'J', // RESERVED 53 | 'K', // RESERVED 54 | 'L', // RESERVED 55 | 'M', // RESERVED 56 | 'N', // RESERVED 57 | 'O', // RESERVED 58 | 'P', // RESERVED 59 | 'x', // INVALID 60 | 'h', // INHERITED 61 | 'p', // NO_PROPAGATE_INHERIT 62 | 'c', // CONTAINER_INHERIT 63 | 'o', // OBJECT_INHERIT 64 | 'i' // INHERIT_ONLY 65 | }; 66 | 67 | #define ACE_ALL_FLAGS_STR "hpcoi0123456789ABCDEFGHIJKLMNOP" 68 | 69 | static char ace_mask_chars[] = 70 | { 71 | '0', 72 | '1', 73 | '2', 74 | '3', 75 | '4', 76 | '5', 77 | '6', 78 | '7', 79 | '8', 80 | '9', 81 | 'A', 82 | 'B', 83 | 'C', 84 | 'D', 85 | 'E', 86 | 'F', 87 | 88 | 'G', // RESERVED 89 | 'H', // RESERVED 90 | 'I', // RESERVED 91 | 'J', // RESERVED 92 | 'K', // RESERVED 93 | 'L', // RESERVED 94 | 'M', // RESERVED 95 | 'N', // RESERVED 96 | 'O', // RESERVED 97 | 'P', // RESERVED 98 | 'Q', // RESERVED 99 | 's', // WRITE_ACL 100 | 'c', // READ_ACL 101 | 'd', // DELETE 102 | 'w', // WRITE 103 | 'r' // READ 104 | }; 105 | 106 | #define ACE_ALL_MASKS_STR "scdwr0123456789ABCDEFGHIJKLMNOPQ" 107 | 108 | static int ace_type_inverted[256]; 109 | static int ace_flag_inverted[256]; 110 | static int ace_mask_inverted[256]; 111 | 112 | PGDLLEXPORT void _PG_init(void); 113 | 114 | static void format_mask(StringInfo out, uint32 mask, char mask_chars[]); 115 | static uint32 parse_mask_char(char c); 116 | 117 | static void check_acl(const ArrayType *acl); 118 | 119 | static char * copy_acl_entries(char *src, char *dest, int nitems, int typlen, 120 | char typalign, int *ncopied, 121 | bool (*filter)(AclEntryBase *entry), 122 | void (*modify_entry)(AclEntryBase *src, AclEntryBase *dest), 123 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry)); 124 | 125 | static bool filter_not_inherited(AclEntryBase *entry); 126 | static bool filter_access_denied(AclEntryBase *entry); 127 | static bool filter_access_allowed(AclEntryBase *entry); 128 | static bool filter_inherited_container(AclEntryBase *entry); 129 | static bool filter_inherited_object(AclEntryBase *entry); 130 | static void modify_inherited_container(AclEntryBase *src, AclEntryBase *dest); 131 | static void modify_inherited_object(AclEntryBase *src, AclEntryBase *dest); 132 | 133 | static void 134 | fill_inverted_map(char map[], int inverted_map[], int len, int first_index) 135 | { 136 | int i; 137 | 138 | for (i = 0; i < 256; ++i) 139 | inverted_map[i] = -1; 140 | 141 | for (i = 0; i < len; ++i) 142 | inverted_map[(int) map[i]] = i + first_index; 143 | } 144 | 145 | void 146 | _PG_init(void) 147 | { 148 | fill_inverted_map(ace_type_chars, ace_type_inverted, 2, 1); 149 | fill_inverted_map(ace_flag_chars, ace_flag_inverted, 32, 0); 150 | fill_inverted_map(ace_mask_chars, ace_mask_inverted, 32, 0); 151 | } 152 | 153 | void 154 | parse_acl_entry(const char *s, AclEntryBase *acl_entry_base, 155 | void *opaque, 156 | const char *parse_who(const char *s, void *opaque)) 157 | { 158 | uint32 type; 159 | uint32 flags; 160 | uint32 mask; 161 | 162 | while (isspace((unsigned char) *s)) 163 | ++s; 164 | 165 | if (*s == '\0') 166 | ereport(ERROR, 167 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 168 | errmsg("missing ACE type"))); 169 | 170 | type = ace_type_inverted[(int) *s++]; 171 | if (type == -1) 172 | ereport(ERROR, 173 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 174 | errmsg("invalid ACE type: must be one of \"%s\"", 175 | ACE_ALL_TYPES_STR))); 176 | 177 | while (isspace((unsigned char) *s)) 178 | ++s; 179 | 180 | if (*s++ != '/') 181 | ereport(ERROR, 182 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 183 | errmsg("missing \"/\" sign"))); 184 | 185 | if (*s == '\0') 186 | ereport(ERROR, 187 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 188 | errmsg("missing ACE flags"))); 189 | 190 | flags = 0; 191 | for (; *s != '\0' && *s != '/'; ++s) 192 | { 193 | int flag_bit; 194 | 195 | flag_bit = ace_flag_inverted[(int) *s]; 196 | if (flag_bit == -1) 197 | ereport(ERROR, 198 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 199 | errmsg("invalid ACE flag: must be one of \"%s\"", 200 | ACE_ALL_FLAGS_STR))); 201 | 202 | flags |= 1 << flag_bit; 203 | } 204 | 205 | while (isspace((unsigned char) *s)) 206 | ++s; 207 | 208 | if (*s++ != '/') 209 | ereport(ERROR, 210 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 211 | errmsg("missing \"/\" sign"))); 212 | 213 | while (isspace((unsigned char) *s)) 214 | ++s; 215 | 216 | if (*s == '\0') 217 | ereport(ERROR, 218 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 219 | errmsg("missing ACE who"))); 220 | 221 | s = parse_who(s, opaque); 222 | 223 | if (*s++ != '=') 224 | ereport(ERROR, 225 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 226 | errmsg("missing \"=\" sign"))); 227 | 228 | while (isspace((unsigned char) *s)) 229 | ++s; 230 | 231 | if (*s == '\0') 232 | ereport(ERROR, 233 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 234 | errmsg("missing ACE mask"))); 235 | 236 | mask = 0; 237 | for (; *s != '\0'; ++s) 238 | mask |= parse_mask_char(*s); 239 | 240 | while (isspace((unsigned char) *s)) 241 | ++s; 242 | 243 | if (*s != '\0') 244 | ereport(ERROR, 245 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 246 | errmsg("extra garbage at the end of the ACE specification"))); 247 | 248 | acl_entry_base->type = type; 249 | acl_entry_base->flags |= flags; 250 | acl_entry_base->mask |= mask; 251 | } 252 | 253 | void 254 | format_acl_entry(StringInfo out, intptr_t opaque, 255 | AclEntryBase *acl_entry_base, 256 | void (*format_who)(StringInfo out, intptr_t opaque)) 257 | { 258 | appendStringInfoChar(out, ace_type_chars[acl_entry_base->type - 1]); 259 | 260 | appendStringInfoChar(out, '/'); 261 | format_mask(out, acl_entry_base->flags, ace_flag_chars); 262 | 263 | appendStringInfoChar(out, '/'); 264 | format_who(out, opaque); 265 | 266 | appendStringInfoChar(out, '='); 267 | format_mask(out, acl_entry_base->mask, ace_mask_chars); 268 | } 269 | 270 | uint32 271 | check_access(const ArrayType *acl, int16 typlen, char typalign, 272 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry), 273 | uint32 mask, intptr_t who, 274 | bool (*who_matches)(void *acl_entry, intptr_t who), 275 | bool implicit_allow) 276 | { 277 | uint32 granted = 0; 278 | int i; 279 | char *entry; 280 | int num; 281 | 282 | if (acl == NULL) 283 | return implicit_allow ? mask : 0; 284 | 285 | check_acl(acl); 286 | 287 | num = ArrayGetNItems(ARR_NDIM(acl), ARR_DIMS(acl)); 288 | entry = ARR_DATA_PTR(acl); 289 | 290 | for (i = 0; mask != 0 && i < num; ++i) 291 | { 292 | AclEntryBase *base = extract_acl_entry_base(entry); 293 | 294 | /* There could be more ACE types in the future */ 295 | if (base->type == ACE_ACCESS_ALLOWED || 296 | base->type == ACE_ACCESS_DENIED) 297 | { 298 | if (!(base->flags & (ACE_INHERIT_ONLY | ACE_INVALID)) && 299 | (mask & base->mask) && 300 | who_matches(entry, who)) 301 | { 302 | if (base->type == ACE_ACCESS_ALLOWED) 303 | granted |= mask & base->mask; 304 | 305 | mask &= ~base->mask; 306 | } 307 | } 308 | 309 | entry = att_addlength_pointer(entry, typlen, entry); 310 | entry = (char *) att_align_nominal(entry, typalign); 311 | } 312 | 313 | if (implicit_allow) 314 | granted |= mask; 315 | 316 | return granted; 317 | } 318 | 319 | text * 320 | check_access_text_mask(const ArrayType *acl, int16 typlen, 321 | char typalign, 322 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry), 323 | text *text_mask, intptr_t who, 324 | bool (*who_matches)(void *acl_entry, intptr_t who), 325 | bool implicit_allow) 326 | { 327 | char *mask_str; 328 | int mask_len; 329 | uint32 mask; 330 | int i; 331 | uint32 granted; 332 | StringInfo out; 333 | 334 | mask_str = VARDATA_ANY(text_mask); 335 | mask_len = VARSIZE_ANY_EXHDR(text_mask); 336 | 337 | mask = 0; 338 | for (i = 0; i < mask_len; ++i) 339 | mask |= parse_mask_char(*mask_str++); 340 | 341 | granted = check_access(acl, typlen, typalign, extract_acl_entry_base, 342 | mask, who, who_matches, implicit_allow); 343 | 344 | out = makeStringInfo(); 345 | format_mask(out, granted, ace_mask_chars); 346 | 347 | return cstring_to_text(out->data); 348 | } 349 | 350 | ArrayType * 351 | merge_acls(const ArrayType *parent_acl, const ArrayType *acl, 352 | int16 typlen, char typalign, 353 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry), 354 | bool container, bool deny_first) 355 | { 356 | ArrayType *result; 357 | int maxbytes; 358 | int items; 359 | char *ptr; 360 | char *result_ptr; 361 | int result_items = 0; 362 | 363 | if (parent_acl != NULL) 364 | check_acl(parent_acl); 365 | 366 | check_acl(acl); 367 | 368 | items = ArrayGetNItems(ARR_NDIM(acl), ARR_DIMS(acl)); 369 | ptr = ARR_DATA_PTR(acl); 370 | 371 | maxbytes = ARR_OVERHEAD_NONULLS(1); 372 | maxbytes += ARR_SIZE(acl) - ARR_DATA_OFFSET(acl); 373 | if (parent_acl != NULL) 374 | maxbytes += ARR_SIZE(parent_acl) - ARR_DATA_OFFSET(parent_acl); 375 | 376 | result = (ArrayType *) palloc0(maxbytes); 377 | result->ndim = 1; 378 | result->elemtype = ARR_ELEMTYPE(acl); 379 | ARR_LBOUND(result)[0] = 1; 380 | 381 | result_ptr = ARR_DATA_PTR(result); 382 | 383 | if (!deny_first) 384 | { 385 | result_ptr = copy_acl_entries(ptr, result_ptr, items, 386 | typlen, typalign, &result_items, 387 | filter_not_inherited, NULL, 388 | extract_acl_entry_base); 389 | } 390 | else 391 | { 392 | result_ptr = copy_acl_entries(ptr, result_ptr, items, 393 | typlen, typalign, &result_items, 394 | filter_access_denied, NULL, 395 | extract_acl_entry_base); 396 | result_ptr = copy_acl_entries(ptr, result_ptr, items, 397 | typlen, typalign, &result_items, 398 | filter_access_allowed, NULL, 399 | extract_acl_entry_base); 400 | } 401 | 402 | if (parent_acl != NULL) 403 | result_ptr = copy_acl_entries(ARR_DATA_PTR(parent_acl), result_ptr, 404 | ArrayGetNItems(ARR_NDIM(parent_acl), 405 | ARR_DIMS(parent_acl)), 406 | typlen, typalign, &result_items, 407 | container ? filter_inherited_container 408 | : filter_inherited_object, 409 | container ? modify_inherited_container 410 | : modify_inherited_object, 411 | extract_acl_entry_base); 412 | 413 | ARR_DIMS(result)[0] = result_items; 414 | SET_VARSIZE(result, ARR_OVERHEAD_NONULLS(1) + 415 | (result_ptr - ARR_DATA_PTR(result))); 416 | 417 | return result; 418 | } 419 | 420 | static uint32 421 | parse_mask_char(char c) 422 | { 423 | int mask_bit; 424 | 425 | mask_bit = ace_mask_inverted[(int) c]; 426 | if (mask_bit == -1) 427 | ereport(ERROR, 428 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 429 | errmsg("invalid ACE mask: must be one of \"%s\"", 430 | ACE_ALL_MASKS_STR))); 431 | 432 | return 1 << mask_bit; 433 | } 434 | 435 | static void 436 | format_mask(StringInfo out, uint32 mask, char mask_chars[]) 437 | { 438 | int i; 439 | 440 | for (i = 0; i < 32; ++i) 441 | if (mask & (1 << i)) 442 | appendStringInfoChar(out, mask_chars[i]); 443 | } 444 | 445 | static void 446 | check_acl(const ArrayType *acl) 447 | { 448 | if (ARR_NDIM(acl) > 1) 449 | ereport(ERROR, 450 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 451 | errmsg("ACL arrays must be one-dimensional"))); 452 | 453 | if (ARR_HASNULL(acl)) 454 | ereport(ERROR, 455 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 456 | errmsg("ACL arrays must not contain null values"))); 457 | } 458 | 459 | static char * 460 | copy_acl_entries(char *src, char *dest, int nitems, int typlen, char typalign, 461 | int *ncopied, bool (*filter)(AclEntryBase *entry), 462 | void (*modify_entry)(AclEntryBase *src, AclEntryBase *dest), 463 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry)) 464 | { 465 | int i; 466 | 467 | for (i = 0; i < nitems; ++i) 468 | { 469 | AclEntryBase *entry; 470 | char *ptr; 471 | 472 | ptr = att_addlength_pointer(src, typlen, src); 473 | 474 | entry = extract_acl_entry_base(src); 475 | if (filter(entry)) 476 | { 477 | memcpy(dest, src, ptr - src); 478 | 479 | if (modify_entry != NULL) 480 | { 481 | modify_entry(entry, extract_acl_entry_base(dest)); 482 | } 483 | 484 | dest = att_addlength_pointer(dest, typlen, dest); 485 | dest = (char *) att_align_nominal(dest, typalign); 486 | 487 | ++*ncopied; 488 | } 489 | 490 | src = (char *) att_align_nominal(ptr, typalign); 491 | } 492 | 493 | return dest; 494 | } 495 | 496 | static bool 497 | filter_not_inherited(AclEntryBase *entry) 498 | { 499 | return (entry->flags & ACE_INHERITED) == 0; 500 | } 501 | 502 | static bool 503 | filter_access_denied(AclEntryBase *entry) 504 | { 505 | return (entry->type == ACE_ACCESS_DENIED) && 506 | !(entry->flags & ACE_INHERITED); 507 | } 508 | 509 | static bool 510 | filter_access_allowed(AclEntryBase *entry) 511 | { 512 | return (entry->type == ACE_ACCESS_ALLOWED) && 513 | !(entry->flags & ACE_INHERITED); 514 | } 515 | 516 | static bool 517 | filter_inherited_container(AclEntryBase *entry) 518 | { 519 | uint32 flags; 520 | 521 | flags = entry->flags; 522 | return (flags & ACE_CONTAINER_INHERIT) || 523 | ((flags & ACE_OBJECT_INHERIT) && !(flags & ACE_NO_PROPAGATE_INHERIT)); 524 | } 525 | 526 | static bool 527 | filter_inherited_object(AclEntryBase *entry) 528 | { 529 | return (entry->flags & ACE_OBJECT_INHERIT) != 0; 530 | } 531 | 532 | static void 533 | modify_inherited_container(AclEntryBase *src, AclEntryBase *dest) 534 | { 535 | if (src->flags & ACE_NO_PROPAGATE_INHERIT) 536 | { 537 | if (src->flags & ACE_CONTAINER_INHERIT) 538 | dest->flags &= ACE_FLAGS_APPLICATION_SPECIFIC; 539 | } 540 | else if (src->flags & ACE_CONTAINER_INHERIT) 541 | { 542 | if ((src->flags & ACE_INHERIT_ONLY) && !(src->flags & ACE_INHERITED)) 543 | dest->flags &= ~ACE_INHERIT_ONLY; 544 | } 545 | else if (src->flags & ACE_OBJECT_INHERIT) 546 | { 547 | dest->flags |= ACE_INHERIT_ONLY; 548 | } 549 | 550 | dest->flags |= ACE_INHERITED; 551 | } 552 | 553 | static void 554 | modify_inherited_object(AclEntryBase *src, AclEntryBase *dest) 555 | { 556 | if (src->flags & ACE_OBJECT_INHERIT) 557 | dest->flags &= ACE_FLAGS_APPLICATION_SPECIFIC; 558 | 559 | dest->flags |= ACE_INHERITED; 560 | } 561 | -------------------------------------------------------------------------------- /acl.control: -------------------------------------------------------------------------------- 1 | # ACL extension 2 | comment = 'data type ACL' 3 | default_version = '1.0.4' 4 | module_pathname = '$libdir/acl' 5 | relocatable = true 6 | -------------------------------------------------------------------------------- /acl.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * acl.h 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #ifndef __ACL_H__ 10 | #define __ACL_H__ 11 | 12 | #include "lib/stringinfo.h" 13 | #include "utils/array.h" 14 | 15 | /* ACE types */ 16 | #define ACE_ACCESS_ALLOWED 0x00000001 17 | #define ACE_ACCESS_DENIED 0x00000002 18 | 19 | /* ACE flags 20 | * 0-15 application-specific 21 | * 16-31 reserved */ 22 | #define ACE_INHERIT_ONLY 0x80000000 23 | #define ACE_OBJECT_INHERIT 0x40000000 24 | #define ACE_CONTAINER_INHERIT 0x20000000 25 | #define ACE_NO_PROPAGATE_INHERIT 0x10000000 26 | #define ACE_INHERITED 0x08000000 27 | #define ACE_INVALID 0x04000000 28 | 29 | #define ACE_FLAGS_APPLICATION_SPECIFIC 0x0000FFFF 30 | 31 | /* ACE access rights 32 | * 0-15 application-specific 33 | * 16-31 reserved */ 34 | #define ACE_READ 0x80000000 35 | #define ACE_WRITE 0x40000000 36 | #define ACE_DELETE 0x20000000 37 | #define ACE_READ_ACL 0x10000000 38 | #define ACE_WRITE_ACL 0x08000000 39 | 40 | typedef struct AclEntryBase { 41 | uint32 type; 42 | uint32 flags; 43 | uint32 mask; 44 | } AclEntryBase; 45 | 46 | void parse_acl_entry(const char *s, AclEntryBase *acl_entry_base, 47 | void *opaque, 48 | const char *parse_who(const char *s, void *opaque)); 49 | 50 | void format_acl_entry(StringInfo out, intptr_t opaque, 51 | AclEntryBase *acl_entry_base, 52 | void (*format_who)(StringInfo out, intptr_t opaque)); 53 | 54 | uint32 check_access(const ArrayType *acl, int16 typlen, char typalign, 55 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry), 56 | uint32 mask, intptr_t who, 57 | bool (*who_matches)(void *acl_entry, intptr_t who), 58 | bool implicit_allow); 59 | 60 | text *check_access_text_mask(const ArrayType *acl, int16 typlen, 61 | char typalign, 62 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry), 63 | text *text_mask, intptr_t who, 64 | bool (*who_matches)(void *acl_entry, intptr_t who), 65 | bool implicit_allow); 66 | 67 | ArrayType *merge_acls(const ArrayType *parent_acl, const ArrayType *acl, 68 | int16 typlem, char typalign, 69 | AclEntryBase * (*extract_acl_entry_base)(void *acl_entry), 70 | bool container, bool deny_first); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /acl.md: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /acl_int4.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * acl_int4.c 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #include "postgres.h" 10 | #include "fmgr.h" 11 | 12 | #include "utils/builtins.h" 13 | 14 | #include "acl.h" 15 | #include "util.h" 16 | 17 | PGDLLEXPORT Datum ace_int4_in(PG_FUNCTION_ARGS); 18 | PGDLLEXPORT Datum ace_int4_out(PG_FUNCTION_ARGS); 19 | PGDLLEXPORT Datum acl_int4_check_access_text(PG_FUNCTION_ARGS); 20 | PGDLLEXPORT Datum acl_int4_check_access_int4(PG_FUNCTION_ARGS); 21 | PGDLLEXPORT Datum acl_int4_merge(PG_FUNCTION_ARGS); 22 | 23 | PG_FUNCTION_INFO_V1(ace_int4_in); 24 | PG_FUNCTION_INFO_V1(ace_int4_out); 25 | PG_FUNCTION_INFO_V1(acl_int4_check_access_text); 26 | PG_FUNCTION_INFO_V1(acl_int4_check_access_int4); 27 | PG_FUNCTION_INFO_V1(acl_int4_merge); 28 | 29 | typedef struct AclEntryInt4 30 | { 31 | AclEntryBase base; 32 | int32 who; 33 | } AclEntryInt4; 34 | 35 | #define ACL_TYPE_ALIGNMENT 'i' 36 | #define ACL_TYPE_LENGTH sizeof(AclEntryInt4) 37 | 38 | #define DatumGetInt4AclEntryP(x) ((AclEntryInt4 *) DatumGetPointer(x)) 39 | #define PG_GETARG_BIGINT_ACL_ENTRY_P(x) DatumGetInt4AclEntryP(PG_GETARG_DATUM(x)) 40 | #define PG_RETURN_BIGINT_ACL_ENTRY_P(x) PG_RETURN_POINTER(x) 41 | 42 | static const char *parse_who(const char *s, void *opaque); 43 | static void format_who(StringInfo out, intptr_t acl_entry); 44 | 45 | static AclEntryBase *extract_acl_entry_base(void *entry); 46 | static bool who_matches(void *entry, intptr_t who); 47 | 48 | Datum 49 | ace_int4_in(PG_FUNCTION_ARGS) 50 | { 51 | const char *s = PG_GETARG_CSTRING(0); 52 | AclEntryInt4 *entry; 53 | 54 | entry = palloc0(sizeof(AclEntryInt4)); 55 | 56 | parse_acl_entry(s, &entry->base, &entry->who, parse_who); 57 | 58 | PG_RETURN_BIGINT_ACL_ENTRY_P(entry); 59 | } 60 | 61 | Datum 62 | ace_int4_out(PG_FUNCTION_ARGS) 63 | { 64 | AclEntryInt4 *entry = PG_GETARG_BIGINT_ACL_ENTRY_P(0); 65 | StringInfo out; 66 | 67 | out = makeStringInfo(); 68 | 69 | format_acl_entry(out, entry->who, &entry->base, format_who); 70 | 71 | PG_RETURN_CSTRING(out->data); 72 | } 73 | 74 | Datum 75 | acl_int4_check_access_int4(PG_FUNCTION_ARGS) 76 | { 77 | ArrayType *acl; 78 | uint32 mask; 79 | ArrayType *who; 80 | bool implicit_allow; 81 | uint32 result; 82 | 83 | if (!check_access_extract_args(fcinfo, &acl, &mask, &who, &implicit_allow, 84 | true, true)) 85 | PG_RETURN_NULL(); 86 | 87 | result = check_access(acl, ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 88 | extract_acl_entry_base, mask, 89 | (intptr_t) who, who_matches, 90 | implicit_allow); 91 | 92 | PG_RETURN_UINT32(result); 93 | } 94 | 95 | Datum 96 | acl_int4_check_access_text(PG_FUNCTION_ARGS) 97 | { 98 | ArrayType *acl; 99 | text *mask; 100 | ArrayType *who; 101 | bool implicit_allow; 102 | text *result; 103 | 104 | if (!check_access_text_mask_extract_args(fcinfo, &acl, &mask, &who, 105 | &implicit_allow, true, true)) 106 | PG_RETURN_NULL(); 107 | 108 | result = check_access_text_mask(acl, ACL_TYPE_LENGTH, 109 | ACL_TYPE_ALIGNMENT, 110 | extract_acl_entry_base, mask, 111 | (intptr_t) who, who_matches, 112 | implicit_allow); 113 | 114 | PG_RETURN_TEXT_P(result); 115 | } 116 | 117 | Datum 118 | acl_int4_merge(PG_FUNCTION_ARGS) 119 | { 120 | ArrayType *parent; 121 | ArrayType *child; 122 | bool container; 123 | bool deny_first; 124 | 125 | merge_acls_extract_args(fcinfo, &parent, &child, &container, &deny_first); 126 | 127 | PG_RETURN_ARRAYTYPE_P(merge_acls(parent, child, 128 | ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 129 | extract_acl_entry_base, 130 | container, deny_first)); 131 | } 132 | 133 | static const char * 134 | parse_who(const char *s, void *opaque) 135 | { 136 | char str[12]; 137 | int len = 0; 138 | 139 | for (; *s != '\0' && (*s == '-' || isdigit((unsigned char) *s)); ++s) 140 | { 141 | if (len >= 11) 142 | ereport(ERROR, 143 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 144 | errmsg("int4 too long"))); 145 | 146 | str[len++] = *s; 147 | } 148 | 149 | str[len] = '\0'; 150 | 151 | *((int32 *) opaque) = DatumGetInt32(DirectFunctionCall1( 152 | int4in, CStringGetDatum(str))); 153 | 154 | return s; 155 | } 156 | 157 | static void 158 | format_who(StringInfo out, intptr_t opaque) 159 | { 160 | appendStringInfoString(out, DatumGetCString(DirectFunctionCall1( 161 | int4out, Int32GetDatum(opaque)))); 162 | } 163 | 164 | static AclEntryBase * 165 | extract_acl_entry_base(void *entry) 166 | { 167 | return &((AclEntryInt4 *) entry)->base; 168 | } 169 | 170 | static bool 171 | who_matches(void *entry, intptr_t who) 172 | { 173 | int32 entry_who; 174 | bool result = false; 175 | int i, num; 176 | int32 *ptr; 177 | 178 | entry_who = ((AclEntryInt4 *) entry)->who; 179 | 180 | num = ArrayGetNItems(ARR_NDIM((ArrayType *) who), 181 | ARR_DIMS((ArrayType *) who)); 182 | ptr = (int32 *) ARR_DATA_PTR((ArrayType *) who); 183 | 184 | for (i = 0; i < num; ++i) 185 | { 186 | int32 who_value = *ptr++; 187 | 188 | if (entry_who == who_value) 189 | { 190 | result = true; 191 | break; 192 | } 193 | } 194 | 195 | return result; 196 | } 197 | -------------------------------------------------------------------------------- /acl_int8.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * acl_int8.c 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #include "postgres.h" 10 | #include "fmgr.h" 11 | 12 | #include "utils/builtins.h" 13 | #if PG_VERSION_NUM < 110000 14 | #include "utils/int8.h" 15 | #endif 16 | 17 | #include "acl.h" 18 | #include "util.h" 19 | 20 | PGDLLEXPORT Datum ace_int8_in(PG_FUNCTION_ARGS); 21 | PGDLLEXPORT Datum ace_int8_out(PG_FUNCTION_ARGS); 22 | PGDLLEXPORT Datum acl_int8_check_access_text(PG_FUNCTION_ARGS); 23 | PGDLLEXPORT Datum acl_int8_check_access_int4(PG_FUNCTION_ARGS); 24 | PGDLLEXPORT Datum acl_int8_merge(PG_FUNCTION_ARGS); 25 | 26 | PG_FUNCTION_INFO_V1(ace_int8_in); 27 | PG_FUNCTION_INFO_V1(ace_int8_out); 28 | PG_FUNCTION_INFO_V1(acl_int8_check_access_text); 29 | PG_FUNCTION_INFO_V1(acl_int8_check_access_int4); 30 | PG_FUNCTION_INFO_V1(acl_int8_merge); 31 | 32 | typedef struct AclEntryInt8 33 | { 34 | AclEntryBase base; 35 | char who[8]; 36 | } AclEntryInt8; 37 | 38 | #define ACL_TYPE_ALIGNMENT 'i' 39 | #define ACL_TYPE_LENGTH sizeof(AclEntryInt8) 40 | 41 | #define DatumGetInt8AclEntryP(x) ((AclEntryInt8 *) DatumGetPointer(x)) 42 | #define PG_GETARG_BIGINT_ACL_ENTRY_P(x) DatumGetInt8AclEntryP(PG_GETARG_DATUM(x)) 43 | #define PG_RETURN_BIGINT_ACL_ENTRY_P(x) PG_RETURN_POINTER(x) 44 | 45 | static const char *parse_who(const char *s, void *opaque); 46 | static void format_who(StringInfo out, intptr_t acl_entry); 47 | 48 | static AclEntryBase *extract_acl_entry_base(void *entry); 49 | static bool who_matches(void *entry, intptr_t who); 50 | 51 | Datum 52 | ace_int8_in(PG_FUNCTION_ARGS) 53 | { 54 | const char *s = PG_GETARG_CSTRING(0); 55 | AclEntryInt8 *entry; 56 | 57 | entry = palloc0(sizeof(AclEntryInt8)); 58 | 59 | parse_acl_entry(s, &entry->base, entry->who, parse_who); 60 | 61 | PG_RETURN_BIGINT_ACL_ENTRY_P(entry); 62 | } 63 | 64 | Datum 65 | ace_int8_out(PG_FUNCTION_ARGS) 66 | { 67 | AclEntryInt8 *entry = PG_GETARG_BIGINT_ACL_ENTRY_P(0); 68 | StringInfo out; 69 | 70 | out = makeStringInfo(); 71 | 72 | format_acl_entry(out, (intptr_t) entry->who, &entry->base, format_who); 73 | 74 | PG_RETURN_CSTRING(out->data); 75 | } 76 | 77 | Datum 78 | acl_int8_check_access_int4(PG_FUNCTION_ARGS) 79 | { 80 | ArrayType *acl; 81 | uint32 mask; 82 | ArrayType *who; 83 | bool implicit_allow; 84 | uint32 result; 85 | 86 | if (!check_access_extract_args(fcinfo, &acl, &mask, &who, &implicit_allow, 87 | true, true)) 88 | PG_RETURN_NULL(); 89 | 90 | result = check_access(acl, ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 91 | extract_acl_entry_base, mask, 92 | (intptr_t) who, who_matches, 93 | implicit_allow); 94 | 95 | PG_RETURN_UINT32(result); 96 | } 97 | 98 | Datum 99 | acl_int8_check_access_text(PG_FUNCTION_ARGS) 100 | { 101 | ArrayType *acl; 102 | text *mask; 103 | ArrayType *who; 104 | bool implicit_allow; 105 | text *result; 106 | 107 | if (!check_access_text_mask_extract_args(fcinfo, &acl, &mask, &who, 108 | &implicit_allow, true, true)) 109 | PG_RETURN_NULL(); 110 | 111 | result = check_access_text_mask(acl, ACL_TYPE_LENGTH, 112 | ACL_TYPE_ALIGNMENT, 113 | extract_acl_entry_base, mask, 114 | (intptr_t) who, who_matches, 115 | implicit_allow); 116 | 117 | PG_RETURN_TEXT_P(result); 118 | } 119 | 120 | Datum 121 | acl_int8_merge(PG_FUNCTION_ARGS) 122 | { 123 | ArrayType *parent; 124 | ArrayType *child; 125 | bool container; 126 | bool deny_first; 127 | 128 | merge_acls_extract_args(fcinfo, &parent, &child, &container, &deny_first); 129 | 130 | PG_RETURN_ARRAYTYPE_P(merge_acls(parent, child, 131 | ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 132 | extract_acl_entry_base, 133 | container, deny_first)); 134 | } 135 | 136 | static const char * 137 | parse_who(const char *s, void *opaque) 138 | { 139 | char str[21]; 140 | int len = 0; 141 | int64 who; 142 | 143 | for (; *s != '\0' && (*s == '-' || isdigit((unsigned char) *s)); ++s) 144 | { 145 | if (len >= 20) 146 | ereport(ERROR, 147 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 148 | errmsg("int8 too long"))); 149 | 150 | str[len++] = *s; 151 | } 152 | 153 | str[len] = '\0'; 154 | 155 | who = DatumGetInt64(DirectFunctionCall1(int8in, CStringGetDatum(str))); 156 | memcpy(opaque, &who, 8); 157 | 158 | return s; 159 | } 160 | 161 | static void 162 | format_who(StringInfo out, intptr_t opaque) 163 | { 164 | int64 who; 165 | 166 | memcpy(&who, (void *) opaque, 8); 167 | 168 | appendStringInfoString(out, DatumGetCString(DirectFunctionCall1( 169 | int8out, Int64GetDatum(who)))); 170 | } 171 | 172 | static AclEntryBase * 173 | extract_acl_entry_base(void *entry) 174 | { 175 | return &((AclEntryInt8 *) entry)->base; 176 | } 177 | 178 | static bool 179 | who_matches(void *entry, intptr_t who) 180 | { 181 | int64 entry_who; 182 | bool result = false; 183 | int i, num; 184 | int64 *ptr; 185 | 186 | memcpy(&entry_who, ((AclEntryInt8 *) entry)->who, 8); 187 | 188 | num = ArrayGetNItems(ARR_NDIM((ArrayType *) who), 189 | ARR_DIMS((ArrayType *) who)); 190 | ptr = (int64 *) ARR_DATA_PTR((ArrayType *) who); 191 | 192 | for (i = 0; i < num; ++i) 193 | { 194 | int64 who_value = *ptr++; 195 | 196 | if (entry_who == who_value) 197 | { 198 | result = true; 199 | break; 200 | } 201 | } 202 | 203 | return result; 204 | } 205 | -------------------------------------------------------------------------------- /acl_oid.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * acl_oid.c 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #include "postgres.h" 10 | #include "fmgr.h" 11 | 12 | #include "miscadmin.h" 13 | #if PG_VERSION_NUM >= 90300 14 | #include "access/htup_details.h" 15 | #endif 16 | #include "access/tupmacs.h" 17 | #include "catalog/pg_authid.h" 18 | #include "catalog/pg_type.h" 19 | #include "utils/builtins.h" 20 | #include "utils/syscache.h" 21 | 22 | #include "acl.h" 23 | #include "util.h" 24 | 25 | PGDLLEXPORT Datum ace_in(PG_FUNCTION_ARGS); 26 | PGDLLEXPORT Datum ace_out(PG_FUNCTION_ARGS); 27 | PGDLLEXPORT Datum acl_check_access_text_current_user(PG_FUNCTION_ARGS); 28 | PGDLLEXPORT Datum acl_check_access_int4_current_user(PG_FUNCTION_ARGS); 29 | PGDLLEXPORT Datum acl_check_access_text_oid(PG_FUNCTION_ARGS); 30 | PGDLLEXPORT Datum acl_check_access_int4_oid(PG_FUNCTION_ARGS); 31 | PGDLLEXPORT Datum acl_check_access_text_name(PG_FUNCTION_ARGS); 32 | PGDLLEXPORT Datum acl_check_access_int4_name(PG_FUNCTION_ARGS); 33 | PGDLLEXPORT Datum acl_merge(PG_FUNCTION_ARGS); 34 | 35 | PG_FUNCTION_INFO_V1(ace_in); 36 | PG_FUNCTION_INFO_V1(ace_out); 37 | PG_FUNCTION_INFO_V1(acl_check_access_text_current_user); 38 | PG_FUNCTION_INFO_V1(acl_check_access_int4_current_user); 39 | PG_FUNCTION_INFO_V1(acl_check_access_text_oid); 40 | PG_FUNCTION_INFO_V1(acl_check_access_int4_oid); 41 | PG_FUNCTION_INFO_V1(acl_check_access_text_name); 42 | PG_FUNCTION_INFO_V1(acl_check_access_int4_name); 43 | PG_FUNCTION_INFO_V1(acl_merge); 44 | 45 | typedef struct AclEntryOid 46 | { 47 | AclEntryBase base; 48 | Oid who; 49 | } AclEntryOid; 50 | 51 | #define ACL_TYPE_ALIGNMENT 'i' 52 | #define ACL_TYPE_LENGTH sizeof(AclEntryOid) 53 | 54 | #define PUBLIC_OID 0 55 | 56 | #define DatumGetAclEntryP(x) ((AclEntryOid *) DatumGetPointer(x)) 57 | #define PG_GETARG_ACL_ENTRY_P(x) DatumGetAclEntryP(PG_GETARG_DATUM(x)) 58 | #define PG_RETURN_ACL_ENTRY_P(x) PG_RETURN_POINTER(x) 59 | 60 | static const char *parse_who(const char *s, void *opaque); 61 | static void format_who(StringInfo out, intptr_t opaque); 62 | 63 | static AclEntryBase *extract_acl_entry_base(void *entry); 64 | static bool who_matches(void *entry, intptr_t who); 65 | 66 | static Oid _get_role_oid(const char *name, bool missing_ok); 67 | 68 | Datum 69 | ace_in(PG_FUNCTION_ARGS) 70 | { 71 | const char *s = PG_GETARG_CSTRING(0); 72 | AclEntryOid *entry; 73 | 74 | entry = palloc0(sizeof(AclEntryOid)); 75 | 76 | parse_acl_entry(s, &entry->base, entry, parse_who); 77 | 78 | PG_RETURN_ACL_ENTRY_P(entry); 79 | } 80 | 81 | Datum 82 | ace_out(PG_FUNCTION_ARGS) 83 | { 84 | AclEntryOid *entry = PG_GETARG_ACL_ENTRY_P(0); 85 | StringInfo out; 86 | 87 | out = makeStringInfo(); 88 | 89 | format_acl_entry(out, (intptr_t) entry, &entry->base, format_who); 90 | 91 | PG_RETURN_CSTRING(out->data); 92 | } 93 | 94 | Datum 95 | acl_check_access_int4_current_user(PG_FUNCTION_ARGS) 96 | { 97 | ArrayType *acl; 98 | uint32 mask; 99 | bool implicit_allow; 100 | Oid who; 101 | 102 | if (!check_access_extract_args(fcinfo, &acl, &mask, NULL, &implicit_allow, 103 | false, false)) 104 | PG_RETURN_NULL(); 105 | 106 | who = GetUserId(); 107 | 108 | PG_RETURN_UINT32(check_access(acl, ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 109 | extract_acl_entry_base, mask, 110 | (intptr_t) who, who_matches, 111 | implicit_allow)); 112 | } 113 | 114 | Datum 115 | acl_check_access_text_current_user(PG_FUNCTION_ARGS) 116 | { 117 | ArrayType *acl; 118 | text *mask; 119 | bool implicit_allow; 120 | Oid who; 121 | 122 | if (!check_access_text_mask_extract_args(fcinfo, &acl, &mask, NULL, &implicit_allow, 123 | false, false)) 124 | PG_RETURN_NULL(); 125 | 126 | who = GetUserId(); 127 | 128 | PG_RETURN_TEXT_P(check_access_text_mask(acl, ACL_TYPE_LENGTH, 129 | ACL_TYPE_ALIGNMENT, 130 | extract_acl_entry_base, mask, 131 | (intptr_t) who, who_matches, 132 | implicit_allow)); 133 | } 134 | 135 | Datum 136 | acl_check_access_int4_oid(PG_FUNCTION_ARGS) 137 | { 138 | ArrayType *acl; 139 | uint32 mask; 140 | Oid who; 141 | bool implicit_allow; 142 | 143 | if (!check_access_extract_args(fcinfo, &acl, &mask, NULL, &implicit_allow, 144 | false, true)) 145 | PG_RETURN_NULL(); 146 | 147 | if (PG_ARGISNULL(2)) 148 | PG_RETURN_NULL(); 149 | 150 | who = PG_GETARG_OID(2); 151 | 152 | PG_RETURN_UINT32(check_access(acl, ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 153 | extract_acl_entry_base, mask, 154 | (intptr_t) who, who_matches, 155 | implicit_allow)); 156 | } 157 | 158 | Datum 159 | acl_check_access_text_oid(PG_FUNCTION_ARGS) 160 | { 161 | ArrayType *acl; 162 | text *mask; 163 | Oid who; 164 | bool implicit_allow; 165 | 166 | if (!check_access_text_mask_extract_args(fcinfo, &acl, &mask, NULL, &implicit_allow, 167 | false, true)) 168 | PG_RETURN_NULL(); 169 | 170 | if (PG_ARGISNULL(2)) 171 | PG_RETURN_NULL(); 172 | 173 | who = PG_GETARG_OID(2); 174 | 175 | PG_RETURN_TEXT_P(check_access_text_mask(acl, ACL_TYPE_LENGTH, 176 | ACL_TYPE_ALIGNMENT, 177 | extract_acl_entry_base, mask, 178 | (intptr_t) who, who_matches, 179 | implicit_allow)); 180 | } 181 | 182 | Datum 183 | acl_check_access_int4_name(PG_FUNCTION_ARGS) 184 | { 185 | ArrayType *acl; 186 | uint32 mask; 187 | Name rolename; 188 | bool implicit_allow; 189 | Oid who; 190 | 191 | if (!check_access_extract_args(fcinfo, &acl, &mask, NULL, &implicit_allow, 192 | false, true)) 193 | PG_RETURN_NULL(); 194 | 195 | if (PG_ARGISNULL(2)) 196 | PG_RETURN_NULL(); 197 | 198 | rolename = PG_GETARG_NAME(2); 199 | who = _get_role_oid(NameStr(*rolename), false); 200 | 201 | PG_RETURN_UINT32(check_access(acl, ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 202 | extract_acl_entry_base, mask, 203 | (intptr_t) who, who_matches, 204 | implicit_allow)); 205 | } 206 | 207 | Datum 208 | acl_check_access_text_name(PG_FUNCTION_ARGS) 209 | { 210 | ArrayType *acl; 211 | text *mask; 212 | Name rolename; 213 | bool implicit_allow; 214 | Oid who; 215 | 216 | if (!check_access_text_mask_extract_args(fcinfo, &acl, &mask, NULL, &implicit_allow, 217 | false, true)) 218 | PG_RETURN_NULL(); 219 | 220 | if (PG_ARGISNULL(2)) 221 | PG_RETURN_NULL(); 222 | 223 | rolename = PG_GETARG_NAME(2); 224 | who = _get_role_oid(NameStr(*rolename), false); 225 | 226 | PG_RETURN_TEXT_P(check_access_text_mask(acl, ACL_TYPE_LENGTH, 227 | ACL_TYPE_ALIGNMENT, 228 | extract_acl_entry_base, mask, 229 | (intptr_t) who, who_matches, 230 | implicit_allow)); 231 | } 232 | 233 | Datum 234 | acl_merge(PG_FUNCTION_ARGS) 235 | { 236 | ArrayType *parent; 237 | ArrayType *child; 238 | bool container; 239 | bool deny_first; 240 | 241 | merge_acls_extract_args(fcinfo, &parent, &child, &container, &deny_first); 242 | 243 | PG_RETURN_ARRAYTYPE_P(merge_acls(parent, child, 244 | ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 245 | extract_acl_entry_base, 246 | container, deny_first)); 247 | } 248 | 249 | static const char * 250 | parse_who(const char *s, void *opaque) 251 | { 252 | char name[NAMEDATALEN]; 253 | int len = 0; 254 | Oid oid; 255 | AclEntryOid *acl_entry = (AclEntryOid *) opaque; 256 | 257 | if (*s == '#') 258 | { 259 | for (++s; *s != '\0' && isalnum((unsigned char) *s); ++s) 260 | { 261 | name[len++] = *s; 262 | 263 | if (len >= 9) 264 | ereport(ERROR, 265 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 266 | errmsg("invalid ACE who"))); 267 | } 268 | 269 | name[len] = '\0'; 270 | 271 | oid = DatumGetObjectId(DirectFunctionCall1(oidin, 272 | CStringGetDatum(name))); 273 | 274 | acl_entry->base.flags |= ACE_INVALID; 275 | } 276 | else 277 | { 278 | bool in_quotes = false; 279 | 280 | for (; 281 | *s != '\0' && 282 | (isalnum((unsigned char) *s) || 283 | *s == '_' || 284 | *s == '"' || 285 | in_quotes); 286 | ++s) 287 | { 288 | if (*s == '"') 289 | { 290 | if (*(s + 1) != '"') 291 | { 292 | in_quotes = !in_quotes; 293 | continue; 294 | } 295 | 296 | ++s; 297 | } 298 | 299 | if (len >= NAMEDATALEN - 1) 300 | ereport(ERROR, 301 | (errcode(ERRCODE_NAME_TOO_LONG), 302 | errmsg("identifier too long"), 303 | errdetail("Identifier must be less than %d characters.", 304 | NAMEDATALEN))); 305 | 306 | name[len++] = *s; 307 | } 308 | 309 | if (len == 0) 310 | { 311 | oid = PUBLIC_OID; 312 | } 313 | else 314 | { 315 | name[len] = '\0'; 316 | oid = _get_role_oid(name, true); 317 | 318 | if (!OidIsValid(oid)) 319 | acl_entry->base.flags |= ACE_INVALID; 320 | } 321 | } 322 | 323 | acl_entry->who = oid; 324 | 325 | return s; 326 | } 327 | 328 | static void 329 | format_who(StringInfo out, intptr_t opaque) 330 | { 331 | HeapTuple htup; 332 | AclEntryOid *entry = (AclEntryOid *) opaque; 333 | 334 | if (entry->who == PUBLIC_OID) 335 | return; 336 | 337 | htup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(entry->who)); 338 | if (!HeapTupleIsValid(htup)) 339 | { 340 | appendStringInfo(out, "#%d", entry->who); 341 | } 342 | else 343 | { 344 | char *name = NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname); 345 | char *s; 346 | bool safe = true; 347 | 348 | for (s = name; *s; ++s) 349 | { 350 | if (!isalnum((unsigned char) *s) && *s != '_') 351 | { 352 | safe = false; 353 | break; 354 | } 355 | } 356 | 357 | if (!safe) 358 | appendStringInfoChar(out, '"'); 359 | 360 | for (s = name; *s; ++s) 361 | { 362 | if (*s == '"') 363 | appendStringInfoChar(out, '"'); 364 | 365 | appendStringInfoChar(out, *s); 366 | } 367 | 368 | if (!safe) 369 | appendStringInfoChar(out, '"'); 370 | 371 | ReleaseSysCache(htup); 372 | } 373 | } 374 | 375 | static AclEntryBase * 376 | extract_acl_entry_base(void *entry) 377 | { 378 | return &((AclEntryOid *) entry)->base; 379 | } 380 | 381 | static bool 382 | who_matches(void *entry, intptr_t who) 383 | { 384 | Oid entry_who = ((AclEntryOid *) entry)->who; 385 | 386 | return entry_who == PUBLIC_OID || entry_who == (Oid) who; 387 | } 388 | 389 | static 390 | Oid _get_role_oid(const char *name, bool missing_ok) 391 | { 392 | Oid oid; 393 | 394 | #if PG_VERSION_NUM >= 120000 395 | oid = GetSysCacheOid1(AUTHNAME, Anum_pg_type_oid, CStringGetDatum(name)); 396 | #else 397 | oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(name)); 398 | #endif 399 | if (!missing_ok && !OidIsValid(oid)) 400 | ereport(ERROR, 401 | (errcode(ERRCODE_UNDEFINED_OBJECT), 402 | errmsg("role \"%s\" does not exist", name))); 403 | 404 | return oid; 405 | } 406 | -------------------------------------------------------------------------------- /acl_uuid.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * acl_uuid.c 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #include "postgres.h" 10 | #include "fmgr.h" 11 | 12 | #include "utils/builtins.h" 13 | #include "utils/uuid.h" 14 | 15 | #include "acl.h" 16 | #include "util.h" 17 | 18 | PGDLLEXPORT Datum ace_uuid_in(PG_FUNCTION_ARGS); 19 | PGDLLEXPORT Datum ace_uuid_out(PG_FUNCTION_ARGS); 20 | PGDLLEXPORT Datum acl_uuid_check_access_text(PG_FUNCTION_ARGS); 21 | PGDLLEXPORT Datum acl_uuid_check_access_int4(PG_FUNCTION_ARGS); 22 | PGDLLEXPORT Datum acl_uuid_merge(PG_FUNCTION_ARGS); 23 | 24 | PG_FUNCTION_INFO_V1(ace_uuid_in); 25 | PG_FUNCTION_INFO_V1(ace_uuid_out); 26 | PG_FUNCTION_INFO_V1(acl_uuid_check_access_text); 27 | PG_FUNCTION_INFO_V1(acl_uuid_check_access_int4); 28 | PG_FUNCTION_INFO_V1(acl_uuid_merge); 29 | 30 | typedef struct AclEntryUUID 31 | { 32 | AclEntryBase base; 33 | char who[UUID_LEN]; 34 | } AclEntryUUID; 35 | 36 | #define ACL_TYPE_ALIGNMENT 'i' 37 | #define ACL_TYPE_LENGTH sizeof(AclEntryUUID) 38 | 39 | #define DatumGetUUIDAclEntryP(x) ((AclEntryUUID *) DatumGetPointer(x)) 40 | #define PG_GETARG_UUID_ACL_ENTRY_P(x) DatumGetUUIDAclEntryP(PG_GETARG_DATUM(x)) 41 | #define PG_RETURN_UUID_ACL_ENTRY_P(x) PG_RETURN_POINTER(x) 42 | 43 | static const char *parse_who(const char *s, void *opaque); 44 | static void format_who(StringInfo out, intptr_t opaque); 45 | 46 | static AclEntryBase *extract_acl_entry_base(void *entry); 47 | static bool who_matches(void *entry, intptr_t who); 48 | 49 | Datum 50 | ace_uuid_in(PG_FUNCTION_ARGS) 51 | { 52 | const char *s = PG_GETARG_CSTRING(0); 53 | AclEntryUUID *entry; 54 | 55 | entry = palloc0(sizeof(AclEntryUUID)); 56 | 57 | parse_acl_entry(s, &entry->base, entry->who, parse_who); 58 | 59 | PG_RETURN_UUID_ACL_ENTRY_P(entry); 60 | } 61 | 62 | Datum 63 | ace_uuid_out(PG_FUNCTION_ARGS) 64 | { 65 | AclEntryUUID *entry = PG_GETARG_UUID_ACL_ENTRY_P(0); 66 | StringInfo out; 67 | 68 | out = makeStringInfo(); 69 | 70 | format_acl_entry(out, (intptr_t) entry->who, &entry->base, format_who); 71 | 72 | PG_RETURN_CSTRING(out->data); 73 | } 74 | 75 | Datum 76 | acl_uuid_check_access_int4(PG_FUNCTION_ARGS) 77 | { 78 | ArrayType *acl; 79 | uint32 mask; 80 | ArrayType *who; 81 | bool implicit_allow; 82 | uint32 result; 83 | 84 | if (!check_access_extract_args(fcinfo, &acl, &mask, &who, &implicit_allow, 85 | true, true)) 86 | PG_RETURN_NULL(); 87 | 88 | result = check_access(acl, ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 89 | extract_acl_entry_base, mask, 90 | (intptr_t) who, who_matches, 91 | implicit_allow); 92 | 93 | PG_RETURN_UINT32(result); 94 | } 95 | 96 | Datum 97 | acl_uuid_check_access_text(PG_FUNCTION_ARGS) 98 | { 99 | ArrayType *acl; 100 | text *mask; 101 | ArrayType *who; 102 | bool implicit_allow; 103 | text *result; 104 | 105 | if (!check_access_text_mask_extract_args(fcinfo, &acl, &mask, &who, 106 | &implicit_allow, true, true)) 107 | PG_RETURN_NULL(); 108 | 109 | result = check_access_text_mask(acl, ACL_TYPE_LENGTH, 110 | ACL_TYPE_ALIGNMENT, 111 | extract_acl_entry_base, mask, 112 | (intptr_t) who, who_matches, 113 | implicit_allow); 114 | 115 | PG_RETURN_TEXT_P(result); 116 | } 117 | 118 | Datum 119 | acl_uuid_merge(PG_FUNCTION_ARGS) 120 | { 121 | ArrayType *parent; 122 | ArrayType *child; 123 | bool container; 124 | bool deny_first; 125 | 126 | merge_acls_extract_args(fcinfo, &parent, &child, &container, &deny_first); 127 | 128 | PG_RETURN_ARRAYTYPE_P(merge_acls(parent, child, 129 | ACL_TYPE_LENGTH, ACL_TYPE_ALIGNMENT, 130 | extract_acl_entry_base, 131 | container, deny_first)); 132 | } 133 | 134 | static const char * 135 | parse_who(const char *s, void *opaque) 136 | { 137 | char str[37]; 138 | int len = 0; 139 | pg_uuid_t *uuid; 140 | 141 | for (; *s != '\0' && (*s == '-' || isalnum((unsigned char) *s)); ++s) 142 | { 143 | if (len >= 36) 144 | ereport(ERROR, 145 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 146 | errmsg("UUID too long"), 147 | errdetail("UUID must be exactly 36 characters."))); 148 | 149 | str[len++] = *s; 150 | } 151 | 152 | str[len] = '\0'; 153 | 154 | uuid = DatumGetUUIDP(DirectFunctionCall1(uuid_in, 155 | CStringGetDatum(str))); 156 | 157 | memcpy(opaque, uuid, UUID_LEN); 158 | 159 | return s; 160 | } 161 | 162 | static void 163 | format_who(StringInfo out, intptr_t opaque) 164 | { 165 | appendStringInfoString(out, DatumGetCString(DirectFunctionCall1( 166 | uuid_out, UUIDPGetDatum(opaque)))); 167 | } 168 | 169 | static AclEntryBase * 170 | extract_acl_entry_base(void *entry) 171 | { 172 | return &((AclEntryUUID *) entry)->base; 173 | } 174 | 175 | static bool 176 | who_matches(void *entry, intptr_t who) 177 | { 178 | pg_uuid_t *entry_who; 179 | bool result = false; 180 | int i, num; 181 | pg_uuid_t *ptr; 182 | 183 | entry_who = (pg_uuid_t *) ((AclEntryUUID *) entry)->who; 184 | 185 | num = ArrayGetNItems(ARR_NDIM((ArrayType *) who), 186 | ARR_DIMS((ArrayType *) who)); 187 | ptr = (pg_uuid_t *) ARR_DATA_PTR((ArrayType *) who); 188 | 189 | for (i = 0; i < num; ++i) 190 | { 191 | pg_uuid_t *uuid = ptr; 192 | 193 | if (memcmp(entry_who, uuid, UUID_LEN) == 0) 194 | { 195 | result = true; 196 | break; 197 | } 198 | 199 | ptr = (pg_uuid_t *) ((char *) ptr + UUID_LEN); 200 | } 201 | 202 | return result; 203 | } 204 | -------------------------------------------------------------------------------- /benchmarks/benchmarks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dir=$(cd "$(dirname "$0")" && pwd) 4 | 5 | count="$1" 6 | if [[ -z $count ]]; then 7 | count=2000000 8 | fi 9 | 10 | ace_count="$2" 11 | if [[ -z $ace_count ]]; then 12 | ace_count=40 13 | fi 14 | 15 | unique_aces="$3" 16 | if [[ -z $unique_aces ]]; then 17 | unique_aces=1000 18 | fi 19 | 20 | if [[ -z $PG_HOME ]]; then 21 | PG_HOME=$(dirname $(pg_config --bindir)) 22 | if (( $? != 0 )); then 23 | exit 1 24 | fi 25 | fi 26 | 27 | pg_args= 28 | 29 | if [[ -n $PG_USER ]]; then 30 | pg_args="$pg_args -U $PG_USER" 31 | fi 32 | 33 | if [[ -z $PG_DATABASE ]]; then 34 | PG_DATABASE="acl_benchmarks" 35 | fi 36 | 37 | psql_args="$pg_args -d $PG_DATABASE" 38 | 39 | # Create database 40 | "$PG_HOME"/bin/createdb $pg_args "$PG_DATABASE" 41 | if [[ $? != 0 ]]; then 42 | exit 1 43 | fi 44 | 45 | # Install extensions 46 | "$PG_HOME"/bin/psql $psql_args -f "$dir"/setup.sql 47 | 48 | ################################################################################ 49 | # OID 50 | ################################################################################ 51 | 52 | echo "Testing OID-based ACEs..." 53 | cat "$dir"/test_oid.sql | sed 's/$count/'$count'/' | sed 's/$unique_aces/'$unique_aces'/' | sed 's/$ace_count/'$ace_count'/g' | "$PG_HOME"/bin/psql $psql_args 54 | 55 | ################################################################################ 56 | # UUID 57 | ################################################################################ 58 | 59 | echo "Testing UUID-based ACEs..." 60 | cat "$dir"/test_uuid.sql | sed 's/$count/'$count'/' | sed 's/$unique_aces/'$unique_aces'/' | sed 's/$ace_count/'$ace_count'/g' | "$PG_HOME"/bin/psql $psql_args 61 | 62 | ################################################################################ 63 | # int4 64 | ################################################################################ 65 | 66 | echo "Testing int4-based ACEs..." 67 | cat "$dir"/test_int4.sql | sed 's/$count/'$count'/' | sed 's/$unique_aces/'$unique_aces'/' | sed 's/$ace_count/'$ace_count'/g' | "$PG_HOME"/bin/psql $psql_args 68 | 69 | ################################################################################ 70 | # int8 71 | ################################################################################ 72 | 73 | echo "Testing int8-based ACEs..." 74 | cat "$dir"/test_int8.sql | sed 's/$count/'$count'/' | sed 's/$unique_aces/'$unique_aces'/' | sed 's/$ace_count/'$ace_count'/g' | "$PG_HOME"/bin/psql $psql_args 75 | 76 | # Drop database 77 | "$PG_HOME"/bin/dropdb $pg_args "$PG_DATABASE" 78 | -------------------------------------------------------------------------------- /benchmarks/setup.sql: -------------------------------------------------------------------------------- 1 | create extension acl; 2 | -------------------------------------------------------------------------------- /benchmarks/test_int4.sql: -------------------------------------------------------------------------------- 1 | create temporary table acl_data (n int4 not null primary key, acl ace_int4[]); 2 | 3 | select setseed(0); 4 | 5 | insert into acl_data (n, acl) 6 | select g1, t.acl 7 | from generate_series(0, $unique_aces - 1) g1 8 | cross join lateral ( 9 | select array_agg((t.type || '//' || ((random() * g1 * g2)::int4 % 100) || '=' || a.rights)::ace_int4) as acl 10 | from generate_series(1, (random() * $ace_count * (g1 + 1))::integer % $ace_count) g2 11 | cross join lateral (select t as type from unnest(string_to_array('ad', null)) t order by random() * g1 * g2 limit 1) t 12 | cross join lateral (select string_agg(t, '') as rights from (select t from unnest(string_to_array('scdwr0123456789ABCDEFGHIJKLMNOPQ', null)) t order by random() * g1 * g2 limit (random() * 10 + 1)::integer) t) a 13 | ) t; 14 | 15 | vacuum full analyze acl_data; 16 | 17 | create temporary view acl_test as 18 | select g, (select d.acl from acl_data d where d.n = g % $unique_aces) 19 | from generate_series(1, $count) g; 20 | 21 | do $$ 22 | declare 23 | v_role oid; 24 | v_count int4; 25 | v_time1 timestamptz; 26 | v_time2 timestamptz; 27 | begin 28 | v_time1 = clock_timestamp(); 29 | select count(*) into v_count from acl_test where acl is not null; 30 | v_time2 = clock_timestamp(); 31 | raise notice 'Full scan. Count: %, time: %', v_count, v_time2 - v_time1; 32 | 33 | v_time1 = clock_timestamp(); 34 | select count(*) into v_count from acl_test where acl_check_access(acl, '011010000000000000000000'::bit(32)::int4, (select array_agg(g::int4) from generate_series(1, 20) g), true) = '011010000000000000000000'::bit(32)::int4; 35 | v_time2 = clock_timestamp(); 36 | raise notice 'ACL scan. Count: %, time: %', v_count, v_time2 - v_time1; 37 | end; 38 | $$ language plpgsql; 39 | -------------------------------------------------------------------------------- /benchmarks/test_int8.sql: -------------------------------------------------------------------------------- 1 | create temporary table acl_data (n int8 not null primary key, acl ace_int8[]); 2 | 3 | select setseed(0); 4 | 5 | insert into acl_data (n, acl) 6 | select g1, t.acl 7 | from generate_series(0, $unique_aces - 1) g1 8 | cross join lateral ( 9 | select array_agg((t.type || '//' || ((random() * g1 * g2)::int8 % 100) || '=' || a.rights)::ace_int8) as acl 10 | from generate_series(1, (random() * $ace_count * (g1 + 1))::integer % $ace_count) g2 11 | cross join lateral (select t as type from unnest(string_to_array('ad', null)) t order by random() * g1 * g2 limit 1) t 12 | cross join lateral (select string_agg(t, '') as rights from (select t from unnest(string_to_array('scdwr0123456789ABCDEFGHIJKLMNOPQ', null)) t order by random() * g1 * g2 limit (random() * 10 + 1)::integer) t) a 13 | ) t; 14 | 15 | vacuum full analyze acl_data; 16 | 17 | create temporary view acl_test as 18 | select g, (select d.acl from acl_data d where d.n = g % $unique_aces) 19 | from generate_series(1, $count) g; 20 | 21 | do $$ 22 | declare 23 | v_role oid; 24 | v_count int8; 25 | v_time1 timestamptz; 26 | v_time2 timestamptz; 27 | begin 28 | v_time1 = clock_timestamp(); 29 | select count(*) into v_count from acl_test where acl is not null; 30 | v_time2 = clock_timestamp(); 31 | raise notice 'Full scan. Count: %, time: %', v_count, v_time2 - v_time1; 32 | 33 | v_time1 = clock_timestamp(); 34 | select count(*) into v_count from acl_test where acl_check_access(acl, '011010000000000000000000'::bit(32)::int4, (select array_agg(g::int8) from generate_series(1, 20) g), true) = '011010000000000000000000'::bit(32)::int4; 35 | v_time2 = clock_timestamp(); 36 | raise notice 'ACL scan. Count: %, time: %', v_count, v_time2 - v_time1; 37 | end; 38 | $$ language plpgsql; 39 | -------------------------------------------------------------------------------- /benchmarks/test_oid.sql: -------------------------------------------------------------------------------- 1 | create temporary table acl_data (n bigint not null primary key, acl ace[]); 2 | 3 | select setseed(0); 4 | 5 | do $$ 6 | declare 7 | v_n integer; 8 | v_user name; 9 | v_role name; 10 | begin 11 | set client_min_messages to warning; 12 | 13 | for v_n in 0..100 loop 14 | execute 'create role acl_test_' || v_n; 15 | end loop; 16 | 17 | for v_n in 1..10000 loop 18 | v_user = 'acl_test_' || (random() * 100)::bigint; 19 | v_role = 'acl_test_' || (random() * 100)::bigint; 20 | 21 | if not pg_has_role(v_role, v_user, 'MEMBER') then 22 | execute 'grant ' || quote_ident(v_role) || ' to ' || quote_ident(v_user); 23 | end if; 24 | end loop; 25 | 26 | set client_min_messages to notice; 27 | end; 28 | $$ language plpgsql; 29 | 30 | insert into acl_data (n, acl) 31 | select g1, t.acl 32 | from generate_series(0, $unique_aces - 1) g1 33 | cross join lateral ( 34 | select array_agg((t.type || '//' || r.rolname || '=' || a.rights)::ace) as acl 35 | from generate_series(1, (random() * $ace_count * (g1 + 1))::integer % $ace_count) g2 36 | cross join lateral (select * from pg_roles order by random() * g1 * g2 limit 1) r 37 | cross join lateral (select t as type from unnest(string_to_array('ad', null)) t order by random() * g1 * g2 limit 1) t 38 | cross join lateral (select string_agg(t, '') as rights from (select t from unnest(string_to_array('scdwr0123456789ABCDEFGHIJKLMNOPQ', null)) t order by random() * g1 * g2 limit (random() * 10 + 1)::integer) t) a 39 | ) t; 40 | 41 | vacuum full analyze acl_data; 42 | 43 | create temporary view acl_test as 44 | select g, (select d.acl from acl_data d where d.n = g % $unique_aces) 45 | from generate_series(1, $count) g; 46 | 47 | do $$ 48 | declare 49 | v_role oid; 50 | v_count bigint; 51 | v_time1 timestamptz; 52 | v_time2 timestamptz; 53 | begin 54 | v_time1 = clock_timestamp(); 55 | select count(*) into v_count from acl_test where acl is not null; 56 | v_time2 = clock_timestamp(); 57 | raise notice 'Full scan. Count: %, time: %', v_count, v_time2 - v_time1; 58 | 59 | v_role = (select oid from pg_roles where rolname = 'acl_test_42'); 60 | 61 | v_time1 = clock_timestamp(); 62 | select count(*) into v_count from acl_test where acl_check_access(acl, '011010000000000000000000'::bit(32)::int4, v_role, true) = '011010000000000000000000'::bit(32)::int4; 63 | v_time2 = clock_timestamp(); 64 | raise notice 'ACL scan. Count: %, time: %', v_count, v_time2 - v_time1; 65 | end; 66 | $$ language plpgsql; 67 | 68 | do $$ 69 | declare 70 | v_n integer; 71 | begin 72 | for v_n in 0..100 loop 73 | execute 'drop role acl_test_' || v_n; 74 | end loop; 75 | end; 76 | $$ language plpgsql; 77 | -------------------------------------------------------------------------------- /benchmarks/test_uuid.sql: -------------------------------------------------------------------------------- 1 | create temporary table uuids (n bigint not null primary key, uuid uuid); 2 | create temporary table acl_data (n bigint not null primary key, acl ace_uuid[]); 3 | 4 | select setseed(0); 5 | 6 | insert into uuids (n, uuid) 7 | select g1, ('00000000-0000-0000-0000-0000000000' || lpad(g1::text, 2, '0'))::uuid 8 | from generate_series(0, 99) g1; 9 | 10 | insert into acl_data (n, acl) 11 | select g1, t.acl 12 | from generate_series(0, $unique_aces - 1) g1 13 | cross join lateral ( 14 | select array_agg((t.type || '//' || u.uuid || '=' || a.rights)::ace_uuid) as acl 15 | from generate_series(1, (random() * $ace_count * (g1 + 1))::integer % $ace_count) g2 16 | cross join lateral (select * from uuids where n = (random() * g1 * g2)::bigint % 100) u 17 | cross join lateral (select t as type from unnest(string_to_array('ad', null)) t order by random() * g1 * g2 limit 1) t 18 | cross join lateral (select string_agg(t, '') as rights from (select t from unnest(string_to_array('scdwr0123456789ABCDEFGHIJKLMNOPQ', null)) t order by random() * g1 * g2 limit (random() * 10 + 1)::integer) t) a 19 | ) t; 20 | 21 | vacuum full analyze acl_data; 22 | 23 | create temporary view acl_test as 24 | select g, (select d.acl from acl_data d where d.n = g % $unique_aces) 25 | from generate_series(1, $count) g; 26 | 27 | do $$ 28 | declare 29 | v_role oid; 30 | v_count bigint; 31 | v_time1 timestamptz; 32 | v_time2 timestamptz; 33 | begin 34 | v_time1 = clock_timestamp(); 35 | select count(*) into v_count from acl_test where acl is not null; 36 | v_time2 = clock_timestamp(); 37 | raise notice 'Full scan. Count: %, time: %', v_count, v_time2 - v_time1; 38 | 39 | v_time1 = clock_timestamp(); 40 | select count(*) into v_count from acl_test where acl_check_access(acl, '011010000000000000000000'::bit(32)::int4, (select array_agg(uuid) from uuids where n < 20), true) = '011010000000000000000000'::bit(32)::int4; 41 | v_time2 = clock_timestamp(); 42 | raise notice 'ACL scan. Count: %, time: %', v_count, v_time2 - v_time1; 43 | end; 44 | $$ language plpgsql; 45 | -------------------------------------------------------------------------------- /expected/acl_int4.out: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int4; 3 | ERROR: missing ACE type 4 | LINE 1: select ''::ace_int4; 5 | ^ 6 | select 'a'::ace_int4; 7 | ERROR: missing "/" sign 8 | LINE 1: select 'a'::ace_int4; 9 | ^ 10 | select 'q'::ace_int4; 11 | ERROR: invalid ACE type: must be one of "ad" 12 | LINE 1: select 'q'::ace_int4; 13 | ^ 14 | select 'a*'::ace_int4; 15 | ERROR: missing "/" sign 16 | LINE 1: select 'a*'::ace_int4; 17 | ^ 18 | select 'a/'::ace_int4; 19 | ERROR: missing ACE flags 20 | LINE 1: select 'a/'::ace_int4; 21 | ^ 22 | select 'a/hq'::ace_int4; 23 | ERROR: invalid ACE flag: must be one of "hpcoi0123456789ABCDEFGHIJKLMNOP" 24 | LINE 1: select 'a/hq'::ace_int4; 25 | ^ 26 | select 'a/h'::ace_int4; 27 | ERROR: missing "/" sign 28 | LINE 1: select 'a/h'::ace_int4; 29 | ^ 30 | select 'a/h/'::ace_int4; 31 | ERROR: missing ACE who 32 | LINE 1: select 'a/h/'::ace_int4; 33 | ^ 34 | select 'a/h/='::ace_int4; 35 | ERROR: invalid input syntax for integer: "" 36 | LINE 1: select 'a/h/='::ace_int4; 37 | ^ 38 | select 'a/h/1='::ace_int4; 39 | ERROR: missing ACE mask 40 | LINE 1: select 'a/h/1='::ace_int4; 41 | ^ 42 | select 'a/h/1=d,'::ace_int4; 43 | ERROR: invalid ACE mask: must be one of "scdwr0123456789ABCDEFGHIJKLMNOPQ" 44 | LINE 1: select 'a/h/1=d,'::ace_int4; 45 | ^ 46 | select 'a/h/1=dw'::ace_int4; 47 | ace_int4 48 | ---------- 49 | a/h/1=dw 50 | (1 row) 51 | 52 | select 'a/ihpc/1=wdddw'::ace_int4; 53 | ace_int4 54 | ------------- 55 | a/hpci/1=dw 56 | (1 row) 57 | 58 | select 'd/ihpc/1=wdddw'::ace_int4; 59 | ace_int4 60 | ------------- 61 | d/hpci/1=dw 62 | (1 row) 63 | 64 | select 'd/ihpc/-2147483648=wdddw'::ace_int4; 65 | ace_int4 66 | ----------------------- 67 | d/hpci/-2147483648=dw 68 | (1 row) 69 | 70 | select 'd/ihpc/2147483647=wdddw'::ace_int4; 71 | ace_int4 72 | ---------------------- 73 | d/hpci/2147483647=dw 74 | (1 row) 75 | 76 | select 'a/ihpc/blah"=dw0'::ace_int4; 77 | ERROR: invalid input syntax for integer: "" 78 | LINE 1: select 'a/ihpc/blah"=dw0'::ace_int4; 79 | ^ 80 | select 'd/ihpc/21474836480=wdddw'::ace_int4; 81 | ERROR: value "21474836480" is out of range for type integer 82 | LINE 1: select 'd/ihpc/21474836480=wdddw'::ace_int4; 83 | ^ 84 | select 'd/ihpc/214748364800=wdddw'::ace_int4; 85 | ERROR: int4 too long 86 | LINE 1: select 'd/ihpc/214748364800=wdddw'::ace_int4; 87 | ^ 88 | -- check access 89 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 90 | coalesce 91 | ---------- 92 | 93 | (1 row) 94 | 95 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 96 | coalesce 97 | ---------- 98 | 0sd 99 | (1 row) 100 | 101 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 102 | coalesce 103 | ---------- 104 | 105 | (1 row) 106 | 107 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 108 | coalesce 109 | ---------- 110 | 0sd 111 | (1 row) 112 | 113 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], false), 'NULL'); 114 | coalesce 115 | ---------- 116 | 117 | (1 row) 118 | 119 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], true), 'NULL'); 120 | coalesce 121 | ---------- 122 | 0sd 123 | (1 row) 124 | 125 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], false), 'NULL'); 126 | coalesce 127 | ---------- 128 | NULL 129 | (1 row) 130 | 131 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], true), 'NULL'); 132 | coalesce 133 | ---------- 134 | NULL 135 | (1 row) 136 | 137 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 138 | acl_check_access 139 | ---------------------------------- 140 | 00000000000000000000000000000000 141 | (1 row) 142 | 143 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 144 | acl_check_access 145 | ---------------------------------- 146 | 00101000000000000000000000000001 147 | (1 row) 148 | 149 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 150 | acl_check_access 151 | ---------------------------------- 152 | 00000000000000000000000000000000 153 | (1 row) 154 | 155 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 156 | acl_check_access 157 | ---------------------------------- 158 | 00101000000000000000000000000001 159 | (1 row) 160 | 161 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], false)::bit(32); 162 | acl_check_access 163 | ---------------------------------- 164 | 00000000000000000000000000000000 165 | (1 row) 166 | 167 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], true)::bit(32); 168 | acl_check_access 169 | ---------------------------------- 170 | 00101000000000000000000000000001 171 | (1 row) 172 | 173 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], false)::bit(32); 174 | acl_check_access 175 | ------------------ 176 | 177 | (1 row) 178 | 179 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], true)::bit(32); 180 | acl_check_access 181 | ------------------ 182 | 183 | (1 row) 184 | 185 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], false), 'NULL'); 186 | coalesce 187 | ---------- 188 | 0d 189 | (1 row) 190 | 191 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], true), 'NULL'); 192 | coalesce 193 | ---------- 194 | 0cd 195 | (1 row) 196 | 197 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 198 | acl_check_access 199 | ---------------------------------- 200 | 00100000000000000000000000000001 201 | (1 row) 202 | 203 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 204 | acl_check_access 205 | ---------------------------------- 206 | 00100000000000000000000000000001 207 | (1 row) 208 | 209 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], null), 'NULL'); 210 | ERROR: allow_implicit argument must be not null 211 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], null)::bit(32); 212 | ERROR: allow_implicit argument must be not null 213 | -- inherit only 214 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false); 215 | acl_check_access 216 | ------------------ 217 | 0sd 218 | (1 row) 219 | 220 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 221 | acl_check_access 222 | ---------------------------------- 223 | 00101000000000000000000000000001 224 | (1 row) 225 | 226 | -- merge 227 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 228 | acl_merge 229 | -------------------------------- 230 | {a//0=0,d//0=1,a//0=23,d//0=4} 231 | (1 row) 232 | 233 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, true); 234 | acl_merge 235 | -------------------------------- 236 | {d//0=1,d//0=4,a//0=0,a//0=23} 237 | (1 row) 238 | 239 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 240 | acl_merge 241 | -------------------------------- 242 | {a//0=0,d//0=1,a//0=23,d//0=4} 243 | (1 row) 244 | 245 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, true); 246 | acl_merge 247 | -------------------------------- 248 | {d//0=1,d//0=4,a//0=0,a//0=23} 249 | (1 row) 250 | 251 | -- inheritance 252 | -- container 253 | -- no flags -> not inherited 254 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 255 | acl_merge 256 | -------------------------------- 257 | {a//0=0,d//0=1,a//0=23,d//0=4} 258 | (1 row) 259 | 260 | -- inherit only -> not inherited 261 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 262 | acl_merge 263 | -------------------------------- 264 | {a//0=0,d//0=1,a//0=23,d//0=4} 265 | (1 row) 266 | 267 | -- object inherit -> inherit only + object inherit 268 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 269 | acl_merge 270 | ------------------------------------------ 271 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 272 | (1 row) 273 | 274 | -- inherit only + object inherit -> inherit only + object inherit 275 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 276 | acl_merge 277 | ------------------------------------------ 278 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 279 | (1 row) 280 | 281 | -- object inherit + no propagate inherit -> no inheritance 282 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 283 | acl_merge 284 | -------------------------------- 285 | {a//0=0,d//0=1,a//0=23,d//0=4} 286 | (1 row) 287 | 288 | -- inherit only + object inherit + no propagate inherit -> no inheritance 289 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 290 | acl_merge 291 | -------------------------------- 292 | {a//0=0,d//0=1,a//0=23,d//0=4} 293 | (1 row) 294 | 295 | -- container inherit -> container inherit 296 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 297 | acl_merge 298 | ----------------------------------------- 299 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 300 | (1 row) 301 | 302 | -- inherit only + container inherit -> container inherit 303 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 304 | acl_merge 305 | ----------------------------------------- 306 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 307 | (1 row) 308 | 309 | -- container inherit + no propagate inherit -> no flags 310 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 311 | acl_merge 312 | ---------------------------------------- 313 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 314 | (1 row) 315 | 316 | -- inherit only + container inherit + no propagate inherit -> no flags 317 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 318 | acl_merge 319 | ---------------------------------------- 320 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 321 | (1 row) 322 | 323 | -- container inherit + object inherit -> container inherit + object inherit 324 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 325 | acl_merge 326 | ------------------------------------------ 327 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 328 | (1 row) 329 | 330 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 331 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 332 | acl_merge 333 | ------------------------------------------ 334 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 335 | (1 row) 336 | 337 | -- container inherit + object inherit + no propagate inherit -> no flags 338 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 339 | acl_merge 340 | ---------------------------------------- 341 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 342 | (1 row) 343 | 344 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 345 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 346 | acl_merge 347 | ---------------------------------------- 348 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 349 | (1 row) 350 | 351 | -- skip inherited 352 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 353 | acl_merge 354 | -------------------------------- 355 | {a//0=0,d//0=1,a//0=23,d//0=4} 356 | (1 row) 357 | 358 | -- object 359 | -- no flags -> not inherited 360 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 361 | acl_merge 362 | -------------------------------- 363 | {a//0=0,d//0=1,a//0=23,d//0=4} 364 | (1 row) 365 | 366 | -- inherit only -> not inherited 367 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 368 | acl_merge 369 | -------------------------------- 370 | {a//0=0,d//0=1,a//0=23,d//0=4} 371 | (1 row) 372 | 373 | -- object inherit -> no flags 374 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 375 | acl_merge 376 | ---------------------------------------- 377 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 378 | (1 row) 379 | 380 | -- inherit only + object inherit -> no flags 381 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 382 | acl_merge 383 | ---------------------------------------- 384 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 385 | (1 row) 386 | 387 | -- object inherit + no propagate inherit -> no flags 388 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 389 | acl_merge 390 | ---------------------------------------- 391 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 392 | (1 row) 393 | 394 | -- inherit only + object inherit + no propagate inherit -> no flags 395 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 396 | acl_merge 397 | ---------------------------------------- 398 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 399 | (1 row) 400 | 401 | -- container inherit -> not inherited 402 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 403 | acl_merge 404 | -------------------------------- 405 | {a//0=0,d//0=1,a//0=23,d//0=4} 406 | (1 row) 407 | 408 | -- inherit only + container inherit -> not inherited 409 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 410 | acl_merge 411 | -------------------------------- 412 | {a//0=0,d//0=1,a//0=23,d//0=4} 413 | (1 row) 414 | 415 | -- container inherit + no propagate inherit -> not inherited 416 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 417 | acl_merge 418 | -------------------------------- 419 | {a//0=0,d//0=1,a//0=23,d//0=4} 420 | (1 row) 421 | 422 | -- inherit only + container inherit + no propagate inherit -> not inherited 423 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 424 | acl_merge 425 | -------------------------------- 426 | {a//0=0,d//0=1,a//0=23,d//0=4} 427 | (1 row) 428 | 429 | -- container inherit + object inherit -> no flags 430 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 431 | acl_merge 432 | ---------------------------------------- 433 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 434 | (1 row) 435 | 436 | -- inherit only + container inherit + object inherit -> no flags 437 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 438 | acl_merge 439 | ---------------------------------------- 440 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 441 | (1 row) 442 | 443 | -- container inherit + object inherit + no propagate inherit -> no flags 444 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 445 | acl_merge 446 | ---------------------------------------- 447 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 448 | (1 row) 449 | 450 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 451 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 452 | acl_merge 453 | ---------------------------------------- 454 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 455 | (1 row) 456 | 457 | -- skip inherited 458 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 459 | acl_merge 460 | -------------------------------- 461 | {a//0=0,d//0=1,a//0=23,d//0=4} 462 | (1 row) 463 | 464 | -------------------------------------------------------------------------------- /expected/acl_int4_pg12.out: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int4; 3 | ERROR: missing ACE type 4 | LINE 1: select ''::ace_int4; 5 | ^ 6 | select 'a'::ace_int4; 7 | ERROR: missing "/" sign 8 | LINE 1: select 'a'::ace_int4; 9 | ^ 10 | select 'q'::ace_int4; 11 | ERROR: invalid ACE type: must be one of "ad" 12 | LINE 1: select 'q'::ace_int4; 13 | ^ 14 | select 'a*'::ace_int4; 15 | ERROR: missing "/" sign 16 | LINE 1: select 'a*'::ace_int4; 17 | ^ 18 | select 'a/'::ace_int4; 19 | ERROR: missing ACE flags 20 | LINE 1: select 'a/'::ace_int4; 21 | ^ 22 | select 'a/hq'::ace_int4; 23 | ERROR: invalid ACE flag: must be one of "hpcoi0123456789ABCDEFGHIJKLMNOP" 24 | LINE 1: select 'a/hq'::ace_int4; 25 | ^ 26 | select 'a/h'::ace_int4; 27 | ERROR: missing "/" sign 28 | LINE 1: select 'a/h'::ace_int4; 29 | ^ 30 | select 'a/h/'::ace_int4; 31 | ERROR: missing ACE who 32 | LINE 1: select 'a/h/'::ace_int4; 33 | ^ 34 | select 'a/h/='::ace_int4; 35 | ERROR: invalid input syntax for type integer: "" 36 | LINE 1: select 'a/h/='::ace_int4; 37 | ^ 38 | select 'a/h/1='::ace_int4; 39 | ERROR: missing ACE mask 40 | LINE 1: select 'a/h/1='::ace_int4; 41 | ^ 42 | select 'a/h/1=d,'::ace_int4; 43 | ERROR: invalid ACE mask: must be one of "scdwr0123456789ABCDEFGHIJKLMNOPQ" 44 | LINE 1: select 'a/h/1=d,'::ace_int4; 45 | ^ 46 | select 'a/h/1=dw'::ace_int4; 47 | ace_int4 48 | ---------- 49 | a/h/1=dw 50 | (1 row) 51 | 52 | select 'a/ihpc/1=wdddw'::ace_int4; 53 | ace_int4 54 | ------------- 55 | a/hpci/1=dw 56 | (1 row) 57 | 58 | select 'd/ihpc/1=wdddw'::ace_int4; 59 | ace_int4 60 | ------------- 61 | d/hpci/1=dw 62 | (1 row) 63 | 64 | select 'd/ihpc/-2147483648=wdddw'::ace_int4; 65 | ace_int4 66 | ----------------------- 67 | d/hpci/-2147483648=dw 68 | (1 row) 69 | 70 | select 'd/ihpc/2147483647=wdddw'::ace_int4; 71 | ace_int4 72 | ---------------------- 73 | d/hpci/2147483647=dw 74 | (1 row) 75 | 76 | select 'a/ihpc/blah"=dw0'::ace_int4; 77 | ERROR: invalid input syntax for type integer: "" 78 | LINE 1: select 'a/ihpc/blah"=dw0'::ace_int4; 79 | ^ 80 | select 'd/ihpc/21474836480=wdddw'::ace_int4; 81 | ERROR: value "21474836480" is out of range for type integer 82 | LINE 1: select 'd/ihpc/21474836480=wdddw'::ace_int4; 83 | ^ 84 | select 'd/ihpc/214748364800=wdddw'::ace_int4; 85 | ERROR: int4 too long 86 | LINE 1: select 'd/ihpc/214748364800=wdddw'::ace_int4; 87 | ^ 88 | -- check access 89 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 90 | coalesce 91 | ---------- 92 | 93 | (1 row) 94 | 95 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 96 | coalesce 97 | ---------- 98 | 0sd 99 | (1 row) 100 | 101 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 102 | coalesce 103 | ---------- 104 | 105 | (1 row) 106 | 107 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 108 | coalesce 109 | ---------- 110 | 0sd 111 | (1 row) 112 | 113 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], false), 'NULL'); 114 | coalesce 115 | ---------- 116 | 117 | (1 row) 118 | 119 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], true), 'NULL'); 120 | coalesce 121 | ---------- 122 | 0sd 123 | (1 row) 124 | 125 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], false), 'NULL'); 126 | coalesce 127 | ---------- 128 | NULL 129 | (1 row) 130 | 131 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], true), 'NULL'); 132 | coalesce 133 | ---------- 134 | NULL 135 | (1 row) 136 | 137 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 138 | acl_check_access 139 | ---------------------------------- 140 | 00000000000000000000000000000000 141 | (1 row) 142 | 143 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 144 | acl_check_access 145 | ---------------------------------- 146 | 00101000000000000000000000000001 147 | (1 row) 148 | 149 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 150 | acl_check_access 151 | ---------------------------------- 152 | 00000000000000000000000000000000 153 | (1 row) 154 | 155 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 156 | acl_check_access 157 | ---------------------------------- 158 | 00101000000000000000000000000001 159 | (1 row) 160 | 161 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], false)::bit(32); 162 | acl_check_access 163 | ---------------------------------- 164 | 00000000000000000000000000000000 165 | (1 row) 166 | 167 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], true)::bit(32); 168 | acl_check_access 169 | ---------------------------------- 170 | 00101000000000000000000000000001 171 | (1 row) 172 | 173 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], false)::bit(32); 174 | acl_check_access 175 | ------------------ 176 | 177 | (1 row) 178 | 179 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], true)::bit(32); 180 | acl_check_access 181 | ------------------ 182 | 183 | (1 row) 184 | 185 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], false), 'NULL'); 186 | coalesce 187 | ---------- 188 | 0d 189 | (1 row) 190 | 191 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], true), 'NULL'); 192 | coalesce 193 | ---------- 194 | 0cd 195 | (1 row) 196 | 197 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 198 | acl_check_access 199 | ---------------------------------- 200 | 00100000000000000000000000000001 201 | (1 row) 202 | 203 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 204 | acl_check_access 205 | ---------------------------------- 206 | 00100000000000000000000000000001 207 | (1 row) 208 | 209 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], null), 'NULL'); 210 | ERROR: allow_implicit argument must be not null 211 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], null)::bit(32); 212 | ERROR: allow_implicit argument must be not null 213 | -- inherit only 214 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false); 215 | acl_check_access 216 | ------------------ 217 | 0sd 218 | (1 row) 219 | 220 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 221 | acl_check_access 222 | ---------------------------------- 223 | 00101000000000000000000000000001 224 | (1 row) 225 | 226 | -- merge 227 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 228 | acl_merge 229 | -------------------------------- 230 | {a//0=0,d//0=1,a//0=23,d//0=4} 231 | (1 row) 232 | 233 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, true); 234 | acl_merge 235 | -------------------------------- 236 | {d//0=1,d//0=4,a//0=0,a//0=23} 237 | (1 row) 238 | 239 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 240 | acl_merge 241 | -------------------------------- 242 | {a//0=0,d//0=1,a//0=23,d//0=4} 243 | (1 row) 244 | 245 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, true); 246 | acl_merge 247 | -------------------------------- 248 | {d//0=1,d//0=4,a//0=0,a//0=23} 249 | (1 row) 250 | 251 | -- inheritance 252 | -- container 253 | -- no flags -> not inherited 254 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 255 | acl_merge 256 | -------------------------------- 257 | {a//0=0,d//0=1,a//0=23,d//0=4} 258 | (1 row) 259 | 260 | -- inherit only -> not inherited 261 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 262 | acl_merge 263 | -------------------------------- 264 | {a//0=0,d//0=1,a//0=23,d//0=4} 265 | (1 row) 266 | 267 | -- object inherit -> inherit only + object inherit 268 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 269 | acl_merge 270 | ------------------------------------------ 271 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 272 | (1 row) 273 | 274 | -- inherit only + object inherit -> inherit only + object inherit 275 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 276 | acl_merge 277 | ------------------------------------------ 278 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 279 | (1 row) 280 | 281 | -- object inherit + no propagate inherit -> no inheritance 282 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 283 | acl_merge 284 | -------------------------------- 285 | {a//0=0,d//0=1,a//0=23,d//0=4} 286 | (1 row) 287 | 288 | -- inherit only + object inherit + no propagate inherit -> no inheritance 289 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 290 | acl_merge 291 | -------------------------------- 292 | {a//0=0,d//0=1,a//0=23,d//0=4} 293 | (1 row) 294 | 295 | -- container inherit -> container inherit 296 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 297 | acl_merge 298 | ----------------------------------------- 299 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 300 | (1 row) 301 | 302 | -- inherit only + container inherit -> container inherit 303 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 304 | acl_merge 305 | ----------------------------------------- 306 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 307 | (1 row) 308 | 309 | -- container inherit + no propagate inherit -> no flags 310 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 311 | acl_merge 312 | ---------------------------------------- 313 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 314 | (1 row) 315 | 316 | -- inherit only + container inherit + no propagate inherit -> no flags 317 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 318 | acl_merge 319 | ---------------------------------------- 320 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 321 | (1 row) 322 | 323 | -- container inherit + object inherit -> container inherit + object inherit 324 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 325 | acl_merge 326 | ------------------------------------------ 327 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 328 | (1 row) 329 | 330 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 331 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 332 | acl_merge 333 | ------------------------------------------ 334 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 335 | (1 row) 336 | 337 | -- container inherit + object inherit + no propagate inherit -> no flags 338 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 339 | acl_merge 340 | ---------------------------------------- 341 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 342 | (1 row) 343 | 344 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 345 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 346 | acl_merge 347 | ---------------------------------------- 348 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 349 | (1 row) 350 | 351 | -- skip inherited 352 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 353 | acl_merge 354 | -------------------------------- 355 | {a//0=0,d//0=1,a//0=23,d//0=4} 356 | (1 row) 357 | 358 | -- object 359 | -- no flags -> not inherited 360 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 361 | acl_merge 362 | -------------------------------- 363 | {a//0=0,d//0=1,a//0=23,d//0=4} 364 | (1 row) 365 | 366 | -- inherit only -> not inherited 367 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 368 | acl_merge 369 | -------------------------------- 370 | {a//0=0,d//0=1,a//0=23,d//0=4} 371 | (1 row) 372 | 373 | -- object inherit -> no flags 374 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 375 | acl_merge 376 | ---------------------------------------- 377 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 378 | (1 row) 379 | 380 | -- inherit only + object inherit -> no flags 381 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 382 | acl_merge 383 | ---------------------------------------- 384 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 385 | (1 row) 386 | 387 | -- object inherit + no propagate inherit -> no flags 388 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 389 | acl_merge 390 | ---------------------------------------- 391 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 392 | (1 row) 393 | 394 | -- inherit only + object inherit + no propagate inherit -> no flags 395 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 396 | acl_merge 397 | ---------------------------------------- 398 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 399 | (1 row) 400 | 401 | -- container inherit -> not inherited 402 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 403 | acl_merge 404 | -------------------------------- 405 | {a//0=0,d//0=1,a//0=23,d//0=4} 406 | (1 row) 407 | 408 | -- inherit only + container inherit -> not inherited 409 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 410 | acl_merge 411 | -------------------------------- 412 | {a//0=0,d//0=1,a//0=23,d//0=4} 413 | (1 row) 414 | 415 | -- container inherit + no propagate inherit -> not inherited 416 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 417 | acl_merge 418 | -------------------------------- 419 | {a//0=0,d//0=1,a//0=23,d//0=4} 420 | (1 row) 421 | 422 | -- inherit only + container inherit + no propagate inherit -> not inherited 423 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 424 | acl_merge 425 | -------------------------------- 426 | {a//0=0,d//0=1,a//0=23,d//0=4} 427 | (1 row) 428 | 429 | -- container inherit + object inherit -> no flags 430 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 431 | acl_merge 432 | ---------------------------------------- 433 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 434 | (1 row) 435 | 436 | -- inherit only + container inherit + object inherit -> no flags 437 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 438 | acl_merge 439 | ---------------------------------------- 440 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 441 | (1 row) 442 | 443 | -- container inherit + object inherit + no propagate inherit -> no flags 444 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 445 | acl_merge 446 | ---------------------------------------- 447 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 448 | (1 row) 449 | 450 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 451 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 452 | acl_merge 453 | ---------------------------------------- 454 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 455 | (1 row) 456 | 457 | -- skip inherited 458 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 459 | acl_merge 460 | -------------------------------- 461 | {a//0=0,d//0=1,a//0=23,d//0=4} 462 | (1 row) 463 | 464 | -------------------------------------------------------------------------------- /expected/acl_int8.out: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int8; 3 | ERROR: missing ACE type 4 | LINE 1: select ''::ace_int8; 5 | ^ 6 | select 'a'::ace_int8; 7 | ERROR: missing "/" sign 8 | LINE 1: select 'a'::ace_int8; 9 | ^ 10 | select 'q'::ace_int8; 11 | ERROR: invalid ACE type: must be one of "ad" 12 | LINE 1: select 'q'::ace_int8; 13 | ^ 14 | select 'a*'::ace_int8; 15 | ERROR: missing "/" sign 16 | LINE 1: select 'a*'::ace_int8; 17 | ^ 18 | select 'a/'::ace_int8; 19 | ERROR: missing ACE flags 20 | LINE 1: select 'a/'::ace_int8; 21 | ^ 22 | select 'a/hq'::ace_int8; 23 | ERROR: invalid ACE flag: must be one of "hpcoi0123456789ABCDEFGHIJKLMNOP" 24 | LINE 1: select 'a/hq'::ace_int8; 25 | ^ 26 | select 'a/h'::ace_int8; 27 | ERROR: missing "/" sign 28 | LINE 1: select 'a/h'::ace_int8; 29 | ^ 30 | select 'a/h/'::ace_int8; 31 | ERROR: missing ACE who 32 | LINE 1: select 'a/h/'::ace_int8; 33 | ^ 34 | select 'a/h/='::ace_int8; 35 | ERROR: invalid input syntax for integer: "" 36 | LINE 1: select 'a/h/='::ace_int8; 37 | ^ 38 | select 'a/h/1='::ace_int8; 39 | ERROR: missing ACE mask 40 | LINE 1: select 'a/h/1='::ace_int8; 41 | ^ 42 | select 'a/h/1=d,'::ace_int8; 43 | ERROR: invalid ACE mask: must be one of "scdwr0123456789ABCDEFGHIJKLMNOPQ" 44 | LINE 1: select 'a/h/1=d,'::ace_int8; 45 | ^ 46 | select 'a/h/1=dw'::ace_int8; 47 | ace_int8 48 | ---------- 49 | a/h/1=dw 50 | (1 row) 51 | 52 | select 'a/ihpc/1=wdddw'::ace_int8; 53 | ace_int8 54 | ------------- 55 | a/hpci/1=dw 56 | (1 row) 57 | 58 | select 'd/ihpc/1=wdddw'::ace_int8; 59 | ace_int8 60 | ------------- 61 | d/hpci/1=dw 62 | (1 row) 63 | 64 | select 'd/ihpc/-9223372036854775808=wdddw'::ace_int8; 65 | ace_int8 66 | -------------------------------- 67 | d/hpci/-9223372036854775808=dw 68 | (1 row) 69 | 70 | select 'd/ihpc/9223372036854775807=wdddw'::ace_int8; 71 | ace_int8 72 | ------------------------------- 73 | d/hpci/9223372036854775807=dw 74 | (1 row) 75 | 76 | select 'a/ihpc/blah"=dw0'::ace_int8; 77 | ERROR: invalid input syntax for integer: "" 78 | LINE 1: select 'a/ihpc/blah"=dw0'::ace_int8; 79 | ^ 80 | select 'd/ihpc/9223372036854775808=wdddw'::ace_int8; 81 | ERROR: value "9223372036854775808" is out of range for type bigint 82 | LINE 1: select 'd/ihpc/9223372036854775808=wdddw'::ace_int8; 83 | ^ 84 | select 'd/ihpc/922337203685477580800=wdddw'::ace_int8; 85 | ERROR: int8 too long 86 | LINE 1: select 'd/ihpc/922337203685477580800=wdddw'::ace_int8; 87 | ^ 88 | -- check access 89 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 90 | coalesce 91 | ---------- 92 | 93 | (1 row) 94 | 95 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 96 | coalesce 97 | ---------- 98 | 0sd 99 | (1 row) 100 | 101 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 102 | coalesce 103 | ---------- 104 | 105 | (1 row) 106 | 107 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 108 | coalesce 109 | ---------- 110 | 0sd 111 | (1 row) 112 | 113 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], false), 'NULL'); 114 | coalesce 115 | ---------- 116 | 117 | (1 row) 118 | 119 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], true), 'NULL'); 120 | coalesce 121 | ---------- 122 | 0sd 123 | (1 row) 124 | 125 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], false), 'NULL'); 126 | coalesce 127 | ---------- 128 | NULL 129 | (1 row) 130 | 131 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], true), 'NULL'); 132 | coalesce 133 | ---------- 134 | NULL 135 | (1 row) 136 | 137 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 138 | acl_check_access 139 | ---------------------------------- 140 | 00000000000000000000000000000000 141 | (1 row) 142 | 143 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 144 | acl_check_access 145 | ---------------------------------- 146 | 00101000000000000000000000000001 147 | (1 row) 148 | 149 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 150 | acl_check_access 151 | ---------------------------------- 152 | 00000000000000000000000000000000 153 | (1 row) 154 | 155 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 156 | acl_check_access 157 | ---------------------------------- 158 | 00101000000000000000000000000001 159 | (1 row) 160 | 161 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], false)::bit(32); 162 | acl_check_access 163 | ---------------------------------- 164 | 00000000000000000000000000000000 165 | (1 row) 166 | 167 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], true)::bit(32); 168 | acl_check_access 169 | ---------------------------------- 170 | 00101000000000000000000000000001 171 | (1 row) 172 | 173 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], false)::bit(32); 174 | acl_check_access 175 | ------------------ 176 | 177 | (1 row) 178 | 179 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], true)::bit(32); 180 | acl_check_access 181 | ------------------ 182 | 183 | (1 row) 184 | 185 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], false), 'NULL'); 186 | coalesce 187 | ---------- 188 | 0d 189 | (1 row) 190 | 191 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], true), 'NULL'); 192 | coalesce 193 | ---------- 194 | 0cd 195 | (1 row) 196 | 197 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 198 | acl_check_access 199 | ---------------------------------- 200 | 00100000000000000000000000000001 201 | (1 row) 202 | 203 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 204 | acl_check_access 205 | ---------------------------------- 206 | 00100000000000000000000000000001 207 | (1 row) 208 | 209 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], null), 'NULL'); 210 | ERROR: allow_implicit argument must be not null 211 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], null)::bit(32); 212 | ERROR: allow_implicit argument must be not null 213 | -- inherit only 214 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false); 215 | acl_check_access 216 | ------------------ 217 | 0sd 218 | (1 row) 219 | 220 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 221 | acl_check_access 222 | ---------------------------------- 223 | 00101000000000000000000000000001 224 | (1 row) 225 | 226 | -- merge 227 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 228 | acl_merge 229 | -------------------------------- 230 | {a//0=0,d//0=1,a//0=23,d//0=4} 231 | (1 row) 232 | 233 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, true); 234 | acl_merge 235 | -------------------------------- 236 | {d//0=1,d//0=4,a//0=0,a//0=23} 237 | (1 row) 238 | 239 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 240 | acl_merge 241 | -------------------------------- 242 | {a//0=0,d//0=1,a//0=23,d//0=4} 243 | (1 row) 244 | 245 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, true); 246 | acl_merge 247 | -------------------------------- 248 | {d//0=1,d//0=4,a//0=0,a//0=23} 249 | (1 row) 250 | 251 | -- inheritance 252 | -- container 253 | -- no flags -> not inherited 254 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 255 | acl_merge 256 | -------------------------------- 257 | {a//0=0,d//0=1,a//0=23,d//0=4} 258 | (1 row) 259 | 260 | -- inherit only -> not inherited 261 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 262 | acl_merge 263 | -------------------------------- 264 | {a//0=0,d//0=1,a//0=23,d//0=4} 265 | (1 row) 266 | 267 | -- object inherit -> inherit only + object inherit 268 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 269 | acl_merge 270 | ------------------------------------------ 271 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 272 | (1 row) 273 | 274 | -- inherit only + object inherit -> inherit only + object inherit 275 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 276 | acl_merge 277 | ------------------------------------------ 278 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 279 | (1 row) 280 | 281 | -- object inherit + no propagate inherit -> no inheritance 282 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 283 | acl_merge 284 | -------------------------------- 285 | {a//0=0,d//0=1,a//0=23,d//0=4} 286 | (1 row) 287 | 288 | -- inherit only + object inherit + no propagate inherit -> no inheritance 289 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 290 | acl_merge 291 | -------------------------------- 292 | {a//0=0,d//0=1,a//0=23,d//0=4} 293 | (1 row) 294 | 295 | -- container inherit -> container inherit 296 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 297 | acl_merge 298 | ----------------------------------------- 299 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 300 | (1 row) 301 | 302 | -- inherit only + container inherit -> container inherit 303 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 304 | acl_merge 305 | ----------------------------------------- 306 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 307 | (1 row) 308 | 309 | -- container inherit + no propagate inherit -> no flags 310 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 311 | acl_merge 312 | ---------------------------------------- 313 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 314 | (1 row) 315 | 316 | -- inherit only + container inherit + no propagate inherit -> no flags 317 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 318 | acl_merge 319 | ---------------------------------------- 320 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 321 | (1 row) 322 | 323 | -- container inherit + object inherit -> container inherit + object inherit 324 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 325 | acl_merge 326 | ------------------------------------------ 327 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 328 | (1 row) 329 | 330 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 331 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 332 | acl_merge 333 | ------------------------------------------ 334 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 335 | (1 row) 336 | 337 | -- container inherit + object inherit + no propagate inherit -> no flags 338 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 339 | acl_merge 340 | ---------------------------------------- 341 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 342 | (1 row) 343 | 344 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 345 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 346 | acl_merge 347 | ---------------------------------------- 348 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 349 | (1 row) 350 | 351 | -- skip inherited 352 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 353 | acl_merge 354 | -------------------------------- 355 | {a//0=0,d//0=1,a//0=23,d//0=4} 356 | (1 row) 357 | 358 | -- object 359 | -- no flags -> not inherited 360 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 361 | acl_merge 362 | -------------------------------- 363 | {a//0=0,d//0=1,a//0=23,d//0=4} 364 | (1 row) 365 | 366 | -- inherit only -> not inherited 367 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 368 | acl_merge 369 | -------------------------------- 370 | {a//0=0,d//0=1,a//0=23,d//0=4} 371 | (1 row) 372 | 373 | -- object inherit -> no flags 374 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 375 | acl_merge 376 | ---------------------------------------- 377 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 378 | (1 row) 379 | 380 | -- inherit only + object inherit -> no flags 381 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 382 | acl_merge 383 | ---------------------------------------- 384 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 385 | (1 row) 386 | 387 | -- object inherit + no propagate inherit -> no flags 388 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 389 | acl_merge 390 | ---------------------------------------- 391 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 392 | (1 row) 393 | 394 | -- inherit only + object inherit + no propagate inherit -> no flags 395 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 396 | acl_merge 397 | ---------------------------------------- 398 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 399 | (1 row) 400 | 401 | -- container inherit -> not inherited 402 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 403 | acl_merge 404 | -------------------------------- 405 | {a//0=0,d//0=1,a//0=23,d//0=4} 406 | (1 row) 407 | 408 | -- inherit only + container inherit -> not inherited 409 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 410 | acl_merge 411 | -------------------------------- 412 | {a//0=0,d//0=1,a//0=23,d//0=4} 413 | (1 row) 414 | 415 | -- container inherit + no propagate inherit -> not inherited 416 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 417 | acl_merge 418 | -------------------------------- 419 | {a//0=0,d//0=1,a//0=23,d//0=4} 420 | (1 row) 421 | 422 | -- inherit only + container inherit + no propagate inherit -> not inherited 423 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 424 | acl_merge 425 | -------------------------------- 426 | {a//0=0,d//0=1,a//0=23,d//0=4} 427 | (1 row) 428 | 429 | -- container inherit + object inherit -> no flags 430 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 431 | acl_merge 432 | ---------------------------------------- 433 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 434 | (1 row) 435 | 436 | -- inherit only + container inherit + object inherit -> no flags 437 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 438 | acl_merge 439 | ---------------------------------------- 440 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 441 | (1 row) 442 | 443 | -- container inherit + object inherit + no propagate inherit -> no flags 444 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 445 | acl_merge 446 | ---------------------------------------- 447 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 448 | (1 row) 449 | 450 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 451 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 452 | acl_merge 453 | ---------------------------------------- 454 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 455 | (1 row) 456 | 457 | -- skip inherited 458 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 459 | acl_merge 460 | -------------------------------- 461 | {a//0=0,d//0=1,a//0=23,d//0=4} 462 | (1 row) 463 | 464 | -------------------------------------------------------------------------------- /expected/acl_int8_pg12.out: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int8; 3 | ERROR: missing ACE type 4 | LINE 1: select ''::ace_int8; 5 | ^ 6 | select 'a'::ace_int8; 7 | ERROR: missing "/" sign 8 | LINE 1: select 'a'::ace_int8; 9 | ^ 10 | select 'q'::ace_int8; 11 | ERROR: invalid ACE type: must be one of "ad" 12 | LINE 1: select 'q'::ace_int8; 13 | ^ 14 | select 'a*'::ace_int8; 15 | ERROR: missing "/" sign 16 | LINE 1: select 'a*'::ace_int8; 17 | ^ 18 | select 'a/'::ace_int8; 19 | ERROR: missing ACE flags 20 | LINE 1: select 'a/'::ace_int8; 21 | ^ 22 | select 'a/hq'::ace_int8; 23 | ERROR: invalid ACE flag: must be one of "hpcoi0123456789ABCDEFGHIJKLMNOP" 24 | LINE 1: select 'a/hq'::ace_int8; 25 | ^ 26 | select 'a/h'::ace_int8; 27 | ERROR: missing "/" sign 28 | LINE 1: select 'a/h'::ace_int8; 29 | ^ 30 | select 'a/h/'::ace_int8; 31 | ERROR: missing ACE who 32 | LINE 1: select 'a/h/'::ace_int8; 33 | ^ 34 | select 'a/h/='::ace_int8; 35 | ERROR: invalid input syntax for type bigint: "" 36 | LINE 1: select 'a/h/='::ace_int8; 37 | ^ 38 | select 'a/h/1='::ace_int8; 39 | ERROR: missing ACE mask 40 | LINE 1: select 'a/h/1='::ace_int8; 41 | ^ 42 | select 'a/h/1=d,'::ace_int8; 43 | ERROR: invalid ACE mask: must be one of "scdwr0123456789ABCDEFGHIJKLMNOPQ" 44 | LINE 1: select 'a/h/1=d,'::ace_int8; 45 | ^ 46 | select 'a/h/1=dw'::ace_int8; 47 | ace_int8 48 | ---------- 49 | a/h/1=dw 50 | (1 row) 51 | 52 | select 'a/ihpc/1=wdddw'::ace_int8; 53 | ace_int8 54 | ------------- 55 | a/hpci/1=dw 56 | (1 row) 57 | 58 | select 'd/ihpc/1=wdddw'::ace_int8; 59 | ace_int8 60 | ------------- 61 | d/hpci/1=dw 62 | (1 row) 63 | 64 | select 'd/ihpc/-9223372036854775808=wdddw'::ace_int8; 65 | ace_int8 66 | -------------------------------- 67 | d/hpci/-9223372036854775808=dw 68 | (1 row) 69 | 70 | select 'd/ihpc/9223372036854775807=wdddw'::ace_int8; 71 | ace_int8 72 | ------------------------------- 73 | d/hpci/9223372036854775807=dw 74 | (1 row) 75 | 76 | select 'a/ihpc/blah"=dw0'::ace_int8; 77 | ERROR: invalid input syntax for type bigint: "" 78 | LINE 1: select 'a/ihpc/blah"=dw0'::ace_int8; 79 | ^ 80 | select 'd/ihpc/9223372036854775808=wdddw'::ace_int8; 81 | ERROR: value "9223372036854775808" is out of range for type bigint 82 | LINE 1: select 'd/ihpc/9223372036854775808=wdddw'::ace_int8; 83 | ^ 84 | select 'd/ihpc/922337203685477580800=wdddw'::ace_int8; 85 | ERROR: int8 too long 86 | LINE 1: select 'd/ihpc/922337203685477580800=wdddw'::ace_int8; 87 | ^ 88 | -- check access 89 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 90 | coalesce 91 | ---------- 92 | 93 | (1 row) 94 | 95 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 96 | coalesce 97 | ---------- 98 | 0sd 99 | (1 row) 100 | 101 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 102 | coalesce 103 | ---------- 104 | 105 | (1 row) 106 | 107 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 108 | coalesce 109 | ---------- 110 | 0sd 111 | (1 row) 112 | 113 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], false), 'NULL'); 114 | coalesce 115 | ---------- 116 | 117 | (1 row) 118 | 119 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], true), 'NULL'); 120 | coalesce 121 | ---------- 122 | 0sd 123 | (1 row) 124 | 125 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], false), 'NULL'); 126 | coalesce 127 | ---------- 128 | NULL 129 | (1 row) 130 | 131 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], true), 'NULL'); 132 | coalesce 133 | ---------- 134 | NULL 135 | (1 row) 136 | 137 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 138 | acl_check_access 139 | ---------------------------------- 140 | 00000000000000000000000000000000 141 | (1 row) 142 | 143 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 144 | acl_check_access 145 | ---------------------------------- 146 | 00101000000000000000000000000001 147 | (1 row) 148 | 149 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 150 | acl_check_access 151 | ---------------------------------- 152 | 00000000000000000000000000000000 153 | (1 row) 154 | 155 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 156 | acl_check_access 157 | ---------------------------------- 158 | 00101000000000000000000000000001 159 | (1 row) 160 | 161 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], false)::bit(32); 162 | acl_check_access 163 | ---------------------------------- 164 | 00000000000000000000000000000000 165 | (1 row) 166 | 167 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], true)::bit(32); 168 | acl_check_access 169 | ---------------------------------- 170 | 00101000000000000000000000000001 171 | (1 row) 172 | 173 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], false)::bit(32); 174 | acl_check_access 175 | ------------------ 176 | 177 | (1 row) 178 | 179 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], true)::bit(32); 180 | acl_check_access 181 | ------------------ 182 | 183 | (1 row) 184 | 185 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], false), 'NULL'); 186 | coalesce 187 | ---------- 188 | 0d 189 | (1 row) 190 | 191 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], true), 'NULL'); 192 | coalesce 193 | ---------- 194 | 0cd 195 | (1 row) 196 | 197 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 198 | acl_check_access 199 | ---------------------------------- 200 | 00100000000000000000000000000001 201 | (1 row) 202 | 203 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 204 | acl_check_access 205 | ---------------------------------- 206 | 00100000000000000000000000000001 207 | (1 row) 208 | 209 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], null), 'NULL'); 210 | ERROR: allow_implicit argument must be not null 211 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], null)::bit(32); 212 | ERROR: allow_implicit argument must be not null 213 | -- inherit only 214 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false); 215 | acl_check_access 216 | ------------------ 217 | 0sd 218 | (1 row) 219 | 220 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 221 | acl_check_access 222 | ---------------------------------- 223 | 00101000000000000000000000000001 224 | (1 row) 225 | 226 | -- merge 227 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 228 | acl_merge 229 | -------------------------------- 230 | {a//0=0,d//0=1,a//0=23,d//0=4} 231 | (1 row) 232 | 233 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, true); 234 | acl_merge 235 | -------------------------------- 236 | {d//0=1,d//0=4,a//0=0,a//0=23} 237 | (1 row) 238 | 239 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 240 | acl_merge 241 | -------------------------------- 242 | {a//0=0,d//0=1,a//0=23,d//0=4} 243 | (1 row) 244 | 245 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, true); 246 | acl_merge 247 | -------------------------------- 248 | {d//0=1,d//0=4,a//0=0,a//0=23} 249 | (1 row) 250 | 251 | -- inheritance 252 | -- container 253 | -- no flags -> not inherited 254 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 255 | acl_merge 256 | -------------------------------- 257 | {a//0=0,d//0=1,a//0=23,d//0=4} 258 | (1 row) 259 | 260 | -- inherit only -> not inherited 261 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 262 | acl_merge 263 | -------------------------------- 264 | {a//0=0,d//0=1,a//0=23,d//0=4} 265 | (1 row) 266 | 267 | -- object inherit -> inherit only + object inherit 268 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 269 | acl_merge 270 | ------------------------------------------ 271 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 272 | (1 row) 273 | 274 | -- inherit only + object inherit -> inherit only + object inherit 275 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 276 | acl_merge 277 | ------------------------------------------ 278 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hoi/1=d} 279 | (1 row) 280 | 281 | -- object inherit + no propagate inherit -> no inheritance 282 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 283 | acl_merge 284 | -------------------------------- 285 | {a//0=0,d//0=1,a//0=23,d//0=4} 286 | (1 row) 287 | 288 | -- inherit only + object inherit + no propagate inherit -> no inheritance 289 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 290 | acl_merge 291 | -------------------------------- 292 | {a//0=0,d//0=1,a//0=23,d//0=4} 293 | (1 row) 294 | 295 | -- container inherit -> container inherit 296 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 297 | acl_merge 298 | ----------------------------------------- 299 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 300 | (1 row) 301 | 302 | -- inherit only + container inherit -> container inherit 303 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 304 | acl_merge 305 | ----------------------------------------- 306 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hc/1=d} 307 | (1 row) 308 | 309 | -- container inherit + no propagate inherit -> no flags 310 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 311 | acl_merge 312 | ---------------------------------------- 313 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 314 | (1 row) 315 | 316 | -- inherit only + container inherit + no propagate inherit -> no flags 317 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 318 | acl_merge 319 | ---------------------------------------- 320 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 321 | (1 row) 322 | 323 | -- container inherit + object inherit -> container inherit + object inherit 324 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 325 | acl_merge 326 | ------------------------------------------ 327 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 328 | (1 row) 329 | 330 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 331 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 332 | acl_merge 333 | ------------------------------------------ 334 | {a//0=0,d//0=1,a//0=23,d//0=4,a/hco/1=d} 335 | (1 row) 336 | 337 | -- container inherit + object inherit + no propagate inherit -> no flags 338 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 339 | acl_merge 340 | ---------------------------------------- 341 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 342 | (1 row) 343 | 344 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 345 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 346 | acl_merge 347 | ---------------------------------------- 348 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 349 | (1 row) 350 | 351 | -- skip inherited 352 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 353 | acl_merge 354 | -------------------------------- 355 | {a//0=0,d//0=1,a//0=23,d//0=4} 356 | (1 row) 357 | 358 | -- object 359 | -- no flags -> not inherited 360 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 361 | acl_merge 362 | -------------------------------- 363 | {a//0=0,d//0=1,a//0=23,d//0=4} 364 | (1 row) 365 | 366 | -- inherit only -> not inherited 367 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 368 | acl_merge 369 | -------------------------------- 370 | {a//0=0,d//0=1,a//0=23,d//0=4} 371 | (1 row) 372 | 373 | -- object inherit -> no flags 374 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 375 | acl_merge 376 | ---------------------------------------- 377 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 378 | (1 row) 379 | 380 | -- inherit only + object inherit -> no flags 381 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 382 | acl_merge 383 | ---------------------------------------- 384 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 385 | (1 row) 386 | 387 | -- object inherit + no propagate inherit -> no flags 388 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 389 | acl_merge 390 | ---------------------------------------- 391 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 392 | (1 row) 393 | 394 | -- inherit only + object inherit + no propagate inherit -> no flags 395 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 396 | acl_merge 397 | ---------------------------------------- 398 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 399 | (1 row) 400 | 401 | -- container inherit -> not inherited 402 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 403 | acl_merge 404 | -------------------------------- 405 | {a//0=0,d//0=1,a//0=23,d//0=4} 406 | (1 row) 407 | 408 | -- inherit only + container inherit -> not inherited 409 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 410 | acl_merge 411 | -------------------------------- 412 | {a//0=0,d//0=1,a//0=23,d//0=4} 413 | (1 row) 414 | 415 | -- container inherit + no propagate inherit -> not inherited 416 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 417 | acl_merge 418 | -------------------------------- 419 | {a//0=0,d//0=1,a//0=23,d//0=4} 420 | (1 row) 421 | 422 | -- inherit only + container inherit + no propagate inherit -> not inherited 423 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 424 | acl_merge 425 | -------------------------------- 426 | {a//0=0,d//0=1,a//0=23,d//0=4} 427 | (1 row) 428 | 429 | -- container inherit + object inherit -> no flags 430 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 431 | acl_merge 432 | ---------------------------------------- 433 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 434 | (1 row) 435 | 436 | -- inherit only + container inherit + object inherit -> no flags 437 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 438 | acl_merge 439 | ---------------------------------------- 440 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 441 | (1 row) 442 | 443 | -- container inherit + object inherit + no propagate inherit -> no flags 444 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 445 | acl_merge 446 | ---------------------------------------- 447 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 448 | (1 row) 449 | 450 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 451 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 452 | acl_merge 453 | ---------------------------------------- 454 | {a//0=0,d//0=1,a//0=23,d//0=4,a/h/1=d} 455 | (1 row) 456 | 457 | -- skip inherited 458 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 459 | acl_merge 460 | -------------------------------- 461 | {a//0=0,d//0=1,a//0=23,d//0=4} 462 | (1 row) 463 | 464 | -------------------------------------------------------------------------------- /expected/install.out: -------------------------------------------------------------------------------- 1 | create extension acl; 2 | -------------------------------------------------------------------------------- /sql/acl_int4.sql: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int4; 3 | select 'a'::ace_int4; 4 | select 'q'::ace_int4; 5 | select 'a*'::ace_int4; 6 | 7 | select 'a/'::ace_int4; 8 | select 'a/hq'::ace_int4; 9 | select 'a/h'::ace_int4; 10 | 11 | select 'a/h/'::ace_int4; 12 | 13 | select 'a/h/='::ace_int4; 14 | select 'a/h/1='::ace_int4; 15 | select 'a/h/1=d,'::ace_int4; 16 | select 'a/h/1=dw'::ace_int4; 17 | select 'a/ihpc/1=wdddw'::ace_int4; 18 | select 'd/ihpc/1=wdddw'::ace_int4; 19 | select 'd/ihpc/-2147483648=wdddw'::ace_int4; 20 | select 'd/ihpc/2147483647=wdddw'::ace_int4; 21 | select 'a/ihpc/blah"=dw0'::ace_int4; 22 | select 'd/ihpc/21474836480=wdddw'::ace_int4; 23 | select 'd/ihpc/214748364800=wdddw'::ace_int4; 24 | 25 | -- check access 26 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 27 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 28 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 29 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 30 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], false), 'NULL'); 31 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], true), 'NULL'); 32 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], false), 'NULL'); 33 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], true), 'NULL'); 34 | 35 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 36 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 37 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 38 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 39 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], false)::bit(32); 40 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], true)::bit(32); 41 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], false)::bit(32); 42 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], true)::bit(32); 43 | 44 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], false), 'NULL'); 45 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], true), 'NULL'); 46 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 47 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 48 | 49 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], null), 'NULL'); 50 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], null)::bit(32); 51 | 52 | -- inherit only 53 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false); 54 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 55 | 56 | -- merge 57 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 58 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, true); 59 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 60 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, true); 61 | 62 | -- inheritance 63 | 64 | -- container 65 | 66 | -- no flags -> not inherited 67 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 68 | 69 | -- inherit only -> not inherited 70 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 71 | 72 | -- object inherit -> inherit only + object inherit 73 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 74 | 75 | -- inherit only + object inherit -> inherit only + object inherit 76 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 77 | 78 | -- object inherit + no propagate inherit -> no inheritance 79 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 80 | 81 | -- inherit only + object inherit + no propagate inherit -> no inheritance 82 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 83 | 84 | -- container inherit -> container inherit 85 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 86 | 87 | -- inherit only + container inherit -> container inherit 88 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 89 | 90 | -- container inherit + no propagate inherit -> no flags 91 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 92 | 93 | -- inherit only + container inherit + no propagate inherit -> no flags 94 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 95 | 96 | -- container inherit + object inherit -> container inherit + object inherit 97 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 98 | 99 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 100 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 101 | 102 | -- container inherit + object inherit + no propagate inherit -> no flags 103 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 104 | 105 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 106 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 107 | 108 | -- skip inherited 109 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 110 | 111 | -- object 112 | 113 | -- no flags -> not inherited 114 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 115 | 116 | -- inherit only -> not inherited 117 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 118 | 119 | -- object inherit -> no flags 120 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 121 | 122 | -- inherit only + object inherit -> no flags 123 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 124 | 125 | -- object inherit + no propagate inherit -> no flags 126 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 127 | 128 | -- inherit only + object inherit + no propagate inherit -> no flags 129 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 130 | 131 | -- container inherit -> not inherited 132 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 133 | 134 | -- inherit only + container inherit -> not inherited 135 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 136 | 137 | -- container inherit + no propagate inherit -> not inherited 138 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 139 | 140 | -- inherit only + container inherit + no propagate inherit -> not inherited 141 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 142 | 143 | -- container inherit + object inherit -> no flags 144 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 145 | 146 | -- inherit only + container inherit + object inherit -> no flags 147 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 148 | 149 | -- container inherit + object inherit + no propagate inherit -> no flags 150 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 151 | 152 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 153 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 154 | 155 | -- skip inherited 156 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 157 | -------------------------------------------------------------------------------- /sql/acl_int4_pg12.sql: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int4; 3 | select 'a'::ace_int4; 4 | select 'q'::ace_int4; 5 | select 'a*'::ace_int4; 6 | 7 | select 'a/'::ace_int4; 8 | select 'a/hq'::ace_int4; 9 | select 'a/h'::ace_int4; 10 | 11 | select 'a/h/'::ace_int4; 12 | 13 | select 'a/h/='::ace_int4; 14 | select 'a/h/1='::ace_int4; 15 | select 'a/h/1=d,'::ace_int4; 16 | select 'a/h/1=dw'::ace_int4; 17 | select 'a/ihpc/1=wdddw'::ace_int4; 18 | select 'd/ihpc/1=wdddw'::ace_int4; 19 | select 'd/ihpc/-2147483648=wdddw'::ace_int4; 20 | select 'd/ihpc/2147483647=wdddw'::ace_int4; 21 | select 'a/ihpc/blah"=dw0'::ace_int4; 22 | select 'd/ihpc/21474836480=wdddw'::ace_int4; 23 | select 'd/ihpc/214748364800=wdddw'::ace_int4; 24 | 25 | -- check access 26 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 27 | select coalesce(acl_check_access('{}'::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 28 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], false), 'NULL'); 29 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{3, 2}'::int4[], true), 'NULL'); 30 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], false), 'NULL'); 31 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], true), 'NULL'); 32 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], false), 'NULL'); 33 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', null::int4[], true), 'NULL'); 34 | 35 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 36 | select acl_check_access('{}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 37 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 38 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 39 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], false)::bit(32); 40 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], true)::bit(32); 41 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], false)::bit(32); 42 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), null::int4[], true)::bit(32); 43 | 44 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], false), 'NULL'); 45 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sdc0', '{3, 2}'::int4[], true), 'NULL'); 46 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 47 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], true)::bit(32); 48 | 49 | select coalesce(acl_check_access(null::ace_int4[], 'sd0', '{}'::int4[], null), 'NULL'); 50 | select acl_check_access(null::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int4[], null)::bit(32); 51 | 52 | -- inherit only 53 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], 'sd0', '{3, 2}'::int4[], false); 54 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int4[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int4[], false)::bit(32); 55 | 56 | -- merge 57 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 58 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, true); 59 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 60 | select acl_merge(null::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, true); 61 | 62 | -- inheritance 63 | 64 | -- container 65 | 66 | -- no flags -> not inherited 67 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 68 | 69 | -- inherit only -> not inherited 70 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 71 | 72 | -- object inherit -> inherit only + object inherit 73 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 74 | 75 | -- inherit only + object inherit -> inherit only + object inherit 76 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 77 | 78 | -- object inherit + no propagate inherit -> no inheritance 79 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 80 | 81 | -- inherit only + object inherit + no propagate inherit -> no inheritance 82 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 83 | 84 | -- container inherit -> container inherit 85 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 86 | 87 | -- inherit only + container inherit -> container inherit 88 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 89 | 90 | -- container inherit + no propagate inherit -> no flags 91 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 92 | 93 | -- inherit only + container inherit + no propagate inherit -> no flags 94 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 95 | 96 | -- container inherit + object inherit -> container inherit + object inherit 97 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 98 | 99 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 100 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 101 | 102 | -- container inherit + object inherit + no propagate inherit -> no flags 103 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 104 | 105 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 106 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 107 | 108 | -- skip inherited 109 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], true, false); 110 | 111 | -- object 112 | 113 | -- no flags -> not inherited 114 | select acl_merge('{a//1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 115 | 116 | -- inherit only -> not inherited 117 | select acl_merge('{a/i/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 118 | 119 | -- object inherit -> no flags 120 | select acl_merge('{a/o/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 121 | 122 | -- inherit only + object inherit -> no flags 123 | select acl_merge('{a/io/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 124 | 125 | -- object inherit + no propagate inherit -> no flags 126 | select acl_merge('{a/op/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 127 | 128 | -- inherit only + object inherit + no propagate inherit -> no flags 129 | select acl_merge('{a/iop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 130 | 131 | -- container inherit -> not inherited 132 | select acl_merge('{a/c/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 133 | 134 | -- inherit only + container inherit -> not inherited 135 | select acl_merge('{a/ic/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 136 | 137 | -- container inherit + no propagate inherit -> not inherited 138 | select acl_merge('{a/cp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 139 | 140 | -- inherit only + container inherit + no propagate inherit -> not inherited 141 | select acl_merge('{a/icp/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 142 | 143 | -- container inherit + object inherit -> no flags 144 | select acl_merge('{a/co/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 145 | 146 | -- inherit only + container inherit + object inherit -> no flags 147 | select acl_merge('{a/ico/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 148 | 149 | -- container inherit + object inherit + no propagate inherit -> no flags 150 | select acl_merge('{a/cop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 151 | 152 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 153 | select acl_merge('{a/icop/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 154 | 155 | -- skip inherited 156 | select acl_merge('{a/h/1=d}'::ace_int4[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int4[], false, false); 157 | -------------------------------------------------------------------------------- /sql/acl_int8.sql: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int8; 3 | select 'a'::ace_int8; 4 | select 'q'::ace_int8; 5 | select 'a*'::ace_int8; 6 | 7 | select 'a/'::ace_int8; 8 | select 'a/hq'::ace_int8; 9 | select 'a/h'::ace_int8; 10 | 11 | select 'a/h/'::ace_int8; 12 | 13 | select 'a/h/='::ace_int8; 14 | select 'a/h/1='::ace_int8; 15 | select 'a/h/1=d,'::ace_int8; 16 | select 'a/h/1=dw'::ace_int8; 17 | select 'a/ihpc/1=wdddw'::ace_int8; 18 | select 'd/ihpc/1=wdddw'::ace_int8; 19 | select 'd/ihpc/-9223372036854775808=wdddw'::ace_int8; 20 | select 'd/ihpc/9223372036854775807=wdddw'::ace_int8; 21 | select 'a/ihpc/blah"=dw0'::ace_int8; 22 | select 'd/ihpc/9223372036854775808=wdddw'::ace_int8; 23 | select 'd/ihpc/922337203685477580800=wdddw'::ace_int8; 24 | 25 | -- check access 26 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 27 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 28 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 29 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 30 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], false), 'NULL'); 31 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], true), 'NULL'); 32 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], false), 'NULL'); 33 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], true), 'NULL'); 34 | 35 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 36 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 37 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 38 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 39 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], false)::bit(32); 40 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], true)::bit(32); 41 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], false)::bit(32); 42 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], true)::bit(32); 43 | 44 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], false), 'NULL'); 45 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], true), 'NULL'); 46 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 47 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 48 | 49 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], null), 'NULL'); 50 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], null)::bit(32); 51 | 52 | -- inherit only 53 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false); 54 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 55 | 56 | -- merge 57 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 58 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, true); 59 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 60 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, true); 61 | 62 | -- inheritance 63 | 64 | -- container 65 | 66 | -- no flags -> not inherited 67 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 68 | 69 | -- inherit only -> not inherited 70 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 71 | 72 | -- object inherit -> inherit only + object inherit 73 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 74 | 75 | -- inherit only + object inherit -> inherit only + object inherit 76 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 77 | 78 | -- object inherit + no propagate inherit -> no inheritance 79 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 80 | 81 | -- inherit only + object inherit + no propagate inherit -> no inheritance 82 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 83 | 84 | -- container inherit -> container inherit 85 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 86 | 87 | -- inherit only + container inherit -> container inherit 88 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 89 | 90 | -- container inherit + no propagate inherit -> no flags 91 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 92 | 93 | -- inherit only + container inherit + no propagate inherit -> no flags 94 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 95 | 96 | -- container inherit + object inherit -> container inherit + object inherit 97 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 98 | 99 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 100 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 101 | 102 | -- container inherit + object inherit + no propagate inherit -> no flags 103 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 104 | 105 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 106 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 107 | 108 | -- skip inherited 109 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 110 | 111 | -- object 112 | 113 | -- no flags -> not inherited 114 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 115 | 116 | -- inherit only -> not inherited 117 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 118 | 119 | -- object inherit -> no flags 120 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 121 | 122 | -- inherit only + object inherit -> no flags 123 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 124 | 125 | -- object inherit + no propagate inherit -> no flags 126 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 127 | 128 | -- inherit only + object inherit + no propagate inherit -> no flags 129 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 130 | 131 | -- container inherit -> not inherited 132 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 133 | 134 | -- inherit only + container inherit -> not inherited 135 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 136 | 137 | -- container inherit + no propagate inherit -> not inherited 138 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 139 | 140 | -- inherit only + container inherit + no propagate inherit -> not inherited 141 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 142 | 143 | -- container inherit + object inherit -> no flags 144 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 145 | 146 | -- inherit only + container inherit + object inherit -> no flags 147 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 148 | 149 | -- container inherit + object inherit + no propagate inherit -> no flags 150 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 151 | 152 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 153 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 154 | 155 | -- skip inherited 156 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 157 | -------------------------------------------------------------------------------- /sql/acl_int8_pg12.sql: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_int8; 3 | select 'a'::ace_int8; 4 | select 'q'::ace_int8; 5 | select 'a*'::ace_int8; 6 | 7 | select 'a/'::ace_int8; 8 | select 'a/hq'::ace_int8; 9 | select 'a/h'::ace_int8; 10 | 11 | select 'a/h/'::ace_int8; 12 | 13 | select 'a/h/='::ace_int8; 14 | select 'a/h/1='::ace_int8; 15 | select 'a/h/1=d,'::ace_int8; 16 | select 'a/h/1=dw'::ace_int8; 17 | select 'a/ihpc/1=wdddw'::ace_int8; 18 | select 'd/ihpc/1=wdddw'::ace_int8; 19 | select 'd/ihpc/-9223372036854775808=wdddw'::ace_int8; 20 | select 'd/ihpc/9223372036854775807=wdddw'::ace_int8; 21 | select 'a/ihpc/blah"=dw0'::ace_int8; 22 | select 'd/ihpc/9223372036854775808=wdddw'::ace_int8; 23 | select 'd/ihpc/922337203685477580800=wdddw'::ace_int8; 24 | 25 | -- check access 26 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 27 | select coalesce(acl_check_access('{}'::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 28 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], false), 'NULL'); 29 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{3, 2}'::int8[], true), 'NULL'); 30 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], false), 'NULL'); 31 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], true), 'NULL'); 32 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], false), 'NULL'); 33 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', null::int8[], true), 'NULL'); 34 | 35 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 36 | select acl_check_access('{}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 37 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 38 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 39 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], false)::bit(32); 40 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], true)::bit(32); 41 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], false)::bit(32); 42 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), null::int8[], true)::bit(32); 43 | 44 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], false), 'NULL'); 45 | select coalesce(acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sdc0', '{3, 2}'::int8[], true), 'NULL'); 46 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 47 | select acl_check_access('{d//1=w,d//2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], true)::bit(32); 48 | 49 | select coalesce(acl_check_access(null::ace_int8[], 'sd0', '{}'::int8[], null), 'NULL'); 50 | select acl_check_access(null::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::int8[], null)::bit(32); 51 | 52 | -- inherit only 53 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], 'sd0', '{3, 2}'::int8[], false); 54 | select acl_check_access('{d//1=w,d/i/2=s,a//2=sdw,a//3=0}'::ace_int8[], (1 << 0) | (1 << 27) | (1 << 29), '{3, 2}'::int8[], false)::bit(32); 55 | 56 | -- merge 57 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 58 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, true); 59 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 60 | select acl_merge(null::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, true); 61 | 62 | -- inheritance 63 | 64 | -- container 65 | 66 | -- no flags -> not inherited 67 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 68 | 69 | -- inherit only -> not inherited 70 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 71 | 72 | -- object inherit -> inherit only + object inherit 73 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 74 | 75 | -- inherit only + object inherit -> inherit only + object inherit 76 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 77 | 78 | -- object inherit + no propagate inherit -> no inheritance 79 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 80 | 81 | -- inherit only + object inherit + no propagate inherit -> no inheritance 82 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 83 | 84 | -- container inherit -> container inherit 85 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 86 | 87 | -- inherit only + container inherit -> container inherit 88 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 89 | 90 | -- container inherit + no propagate inherit -> no flags 91 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 92 | 93 | -- inherit only + container inherit + no propagate inherit -> no flags 94 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 95 | 96 | -- container inherit + object inherit -> container inherit + object inherit 97 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 98 | 99 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 100 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 101 | 102 | -- container inherit + object inherit + no propagate inherit -> no flags 103 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 104 | 105 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 106 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 107 | 108 | -- skip inherited 109 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], true, false); 110 | 111 | -- object 112 | 113 | -- no flags -> not inherited 114 | select acl_merge('{a//1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 115 | 116 | -- inherit only -> not inherited 117 | select acl_merge('{a/i/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 118 | 119 | -- object inherit -> no flags 120 | select acl_merge('{a/o/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 121 | 122 | -- inherit only + object inherit -> no flags 123 | select acl_merge('{a/io/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 124 | 125 | -- object inherit + no propagate inherit -> no flags 126 | select acl_merge('{a/op/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 127 | 128 | -- inherit only + object inherit + no propagate inherit -> no flags 129 | select acl_merge('{a/iop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 130 | 131 | -- container inherit -> not inherited 132 | select acl_merge('{a/c/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 133 | 134 | -- inherit only + container inherit -> not inherited 135 | select acl_merge('{a/ic/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 136 | 137 | -- container inherit + no propagate inherit -> not inherited 138 | select acl_merge('{a/cp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 139 | 140 | -- inherit only + container inherit + no propagate inherit -> not inherited 141 | select acl_merge('{a/icp/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 142 | 143 | -- container inherit + object inherit -> no flags 144 | select acl_merge('{a/co/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 145 | 146 | -- inherit only + container inherit + object inherit -> no flags 147 | select acl_merge('{a/ico/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 148 | 149 | -- container inherit + object inherit + no propagate inherit -> no flags 150 | select acl_merge('{a/cop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 151 | 152 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 153 | select acl_merge('{a/icop/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 154 | 155 | -- skip inherited 156 | select acl_merge('{a/h/1=d}'::ace_int8[], '{a//0=0,d//0=1,a//0=23,d//0=4}'::ace_int8[], false, false); 157 | -------------------------------------------------------------------------------- /sql/acl_oid.sql: -------------------------------------------------------------------------------- 1 | -- set up users 2 | create user acl_test1; 3 | create user "acl test2"; 4 | create user """acl=""s,/a//acl_test1"; 5 | create user acl_temporary_user; 6 | 7 | -- ACL format checks 8 | select ''::ace; 9 | select 'a'::ace; 10 | select 'q'::ace; 11 | select 'a*'::ace; 12 | 13 | select 'a/'::ace; 14 | select 'a/hq'::ace; 15 | select 'a/h'::ace; 16 | 17 | select 'a/h/'::ace; 18 | 19 | select 'a/h/='::ace; 20 | select 'a/h/acl_test1='::ace; 21 | select 'a/h/acl_test1=d,'::ace; 22 | select 'a/h/acl_test1=dw'::ace; 23 | select 'a/ihpc/acl_test1=wdddw'::ace; 24 | select 'd/ihpc/acl_test1=wdddw'::ace; 25 | select 'a/ihpc/"acl test2"=dw0'::ace; 26 | 27 | -- invalid role 28 | select 'a//blah=d'::ace; 29 | 30 | -- deleted role 31 | create table acl_test (ace ace); 32 | insert into acl_test (ace) values ('a//acl_temporary_user=s'); 33 | drop user acl_temporary_user; 34 | select ace::text ~ '#' from acl_test; 35 | 36 | -- invalid acl 37 | select (ace::text::ace::text) ~ '#' from acl_test; 38 | 39 | -- current user 40 | set role 'acl_test1'; 41 | select coalesce(acl_check_access('{}'::ace[], 'sd0', false), 'NULL'); 42 | select acl_check_access('{}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), false)::bit(32); 43 | select coalesce(acl_check_access(null::ace[], 'sd0', false), 'NULL'); 44 | select acl_check_access(null::ace[], (1 << 0) | (1 << 27) | (1 << 29), false)::bit(32); 45 | 46 | select acl_check_access('{d//=s,a//acl_test1=sdw}'::ace[], 'sd0', false); 47 | select acl_check_access('{d//=s,a//acl_test1=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), false)::bit(32); 48 | select acl_check_access('{a//acl_test1=s0,d//=sdw}'::ace[], 'sd0', false); 49 | select acl_check_access('{a//acl_test1=s0,d//=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), false)::bit(32); 50 | reset role; 51 | 52 | set role """acl=""s,/a//acl_test1"; 53 | select acl_check_access('{d/hpc/acl_test1=dw0,a//\"\"\"acl=\"\"s\,/a//acl_test1\"=c}'::ace[], 'c', false); 54 | select acl_check_access('{d/hpc/acl_test1=dw0,a//\"\"\"acl=\"\"s\,/a//acl_test1\"=c}'::ace[], (1 << 28), false)::bit(32); 55 | reset role; 56 | 57 | -- name 58 | select coalesce(acl_check_access('{}'::ace[], 'sd0', 'acl_test1', false), 'NULL'); 59 | select acl_check_access('{}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), 'acl_test1', false)::bit(32); 60 | select coalesce(acl_check_access(null::ace[], 'sd0', 'acl_test1', false), 'NULL'); 61 | select acl_check_access(null::ace[], (1 << 0) | (1 << 27) | (1 << 29), 'acl_test1', false)::bit(32); 62 | select coalesce(acl_check_access('{}'::ace[], 'sd0', null, false), 'NULL'); 63 | select acl_check_access('{}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), null, false)::bit(32); 64 | 65 | select acl_check_access('{d//=s,a//acl_test1=sdw}'::ace[], 'sd0', 'acl_test1', false); 66 | select acl_check_access('{d//=s,a//acl_test1=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), 'acl_test1', false)::bit(32); 67 | select acl_check_access('{a//acl_test1=s0,d//=sdw}'::ace[], 'sd0', 'acl_test1', false); 68 | select acl_check_access('{a//acl_test1=s0,d//=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), 'acl_test1', false)::bit(32); 69 | select acl_check_access('{d/hpc/acl_test1=dw0,a//\"\"\"acl=\"\"s\,/a//acl_test1\"=c}'::ace[], 'c', '"acl="s,/a//acl_test1', false); 70 | select acl_check_access('{d/hpc/acl_test1=dw0,a//\"\"\"acl=\"\"s\,/a//acl_test1\"=c}'::ace[], (1 << 28), '"acl="s,/a//acl_test1', false)::bit(32); 71 | 72 | -- oid 73 | select coalesce(acl_check_access('{}'::ace[], 'sd0', (select oid from pg_roles where rolname = 'acl_test1'), false), 'NULL'); 74 | select acl_check_access('{}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), (select oid from pg_roles where rolname = 'acl_test1'), false)::bit(32); 75 | select coalesce(acl_check_access(null::ace[], 'sd0', (select oid from pg_roles where rolname = 'acl_test1'), false), 'NULL'); 76 | select acl_check_access(null::ace[], (1 << 0) | (1 << 27) | (1 << 29), (select oid from pg_roles where rolname = 'acl_test1'), false)::bit(32); 77 | select coalesce(acl_check_access('{}'::ace[], 'sd0', null, false), 'NULL'); 78 | select acl_check_access('{}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), null, false)::bit(32); 79 | 80 | select acl_check_access('{d//=s,a//acl_test1=sdw}'::ace[], 'sd0', (select oid from pg_roles where rolname = 'acl_test1'), false); 81 | select acl_check_access('{d//=s,a//acl_test1=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), (select oid from pg_roles where rolname = 'acl_test1'), false)::bit(32); 82 | select acl_check_access('{a//acl_test1=s0,d//=sdw}'::ace[], 'sd0', (select oid from pg_roles where rolname = 'acl_test1'), false); 83 | select acl_check_access('{a//acl_test1=s0,d//=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), (select oid from pg_roles where rolname = 'acl_test1'), false)::bit(32); 84 | select acl_check_access('{d/hpc/acl_test1=dw0,a//\"\"\"acl=\"\"s\,/a//acl_test1\"=c}'::ace[], 'c', (select oid from pg_roles where rolname = '"acl="s,/a//acl_test1'), false); 85 | select acl_check_access('{d/hpc/acl_test1=dw0,a//\"\"\"acl=\"\"s\,/a//acl_test1\"=c}'::ace[], (1 << 28), (select oid from pg_roles where rolname = '"acl="s,/a//acl_test1'), false)::bit(32); 86 | 87 | -- inherit only 88 | select acl_check_access('{d/i/=s,a//acl_test1=sdw}'::ace[], 'sd0', 'acl_test1', false); 89 | select acl_check_access('{d/i/=s,a//acl_test1=sdw}'::ace[], (1 << 0) | (1 << 27) | (1 << 29), 'acl_test1', false)::bit(32); 90 | 91 | -- merge 92 | select acl_merge(null::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 93 | select acl_merge(null::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, true); 94 | select acl_merge(null::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 95 | select acl_merge(null::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, true); 96 | 97 | -- inheritance 98 | 99 | -- container 100 | 101 | -- no flags -> not inherited 102 | select acl_merge('{a//acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 103 | 104 | -- inherit only -> not inherited 105 | select acl_merge('{a/i/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 106 | 107 | -- object inherit -> inherit only + object inherit 108 | select acl_merge('{a/o/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 109 | 110 | -- inherit only + object inherit -> inherit only + object inherit 111 | select acl_merge('{a/io/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 112 | 113 | -- object inherit + no propagate inherit -> no inheritance 114 | select acl_merge('{a/op/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 115 | 116 | -- inherit only + object inherit + no propagate inherit -> no inheritance 117 | select acl_merge('{a/iop/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 118 | 119 | -- container inherit -> container inherit 120 | select acl_merge('{a/c/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 121 | 122 | -- inherit only + container inherit -> container inherit 123 | select acl_merge('{a/ic/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 124 | 125 | -- container inherit + no propagate inherit -> no flags 126 | select acl_merge('{a/cp/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 127 | 128 | -- inherit only + container inherit + no propagate inherit -> no flags 129 | select acl_merge('{a/icp/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 130 | 131 | -- container inherit + object inherit -> container inherit + object inherit 132 | select acl_merge('{a/co/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 133 | 134 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 135 | select acl_merge('{a/ico/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 136 | 137 | -- container inherit + object inherit + no propagate inherit -> no flags 138 | select acl_merge('{a/cop/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 139 | 140 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 141 | select acl_merge('{a/icop/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 142 | 143 | -- skip inherited 144 | select acl_merge('{a/h/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], true, false); 145 | 146 | -- object 147 | 148 | -- no flags -> not inherited 149 | select acl_merge('{a//acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 150 | 151 | -- inherit only -> not inherited 152 | select acl_merge('{a/i/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 153 | 154 | -- object inherit -> no flags 155 | select acl_merge('{a/o/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 156 | 157 | -- inherit only + object inherit -> no flags 158 | select acl_merge('{a/io/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 159 | 160 | -- object inherit + no propagate inherit -> no flags 161 | select acl_merge('{a/op/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 162 | 163 | -- inherit only + object inherit + no propagate inherit -> no flags 164 | select acl_merge('{a/iop/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 165 | 166 | -- container inherit -> not inherited 167 | select acl_merge('{a/c/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 168 | 169 | -- inherit only + container inherit -> not inherited 170 | select acl_merge('{a/ic/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 171 | 172 | -- container inherit + no propagate inherit -> not inherited 173 | select acl_merge('{a/cp/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 174 | 175 | -- inherit only + container inherit + no propagate inherit -> not inherited 176 | select acl_merge('{a/icp/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 177 | 178 | -- container inherit + object inherit -> no flags 179 | select acl_merge('{a/co/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 180 | 181 | -- inherit only + container inherit + object inherit -> no flags 182 | select acl_merge('{a/ico/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 183 | 184 | -- container inherit + object inherit + no propagate inherit -> no flags 185 | select acl_merge('{a/cop/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 186 | 187 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 188 | select acl_merge('{a/icop/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 189 | 190 | -- skip inherited 191 | select acl_merge('{a/h/acl_test1=d}'::ace[], '{a//=0,d//=1,a//=23,d//=4}'::ace[], false, false); 192 | 193 | -- clean up 194 | drop user acl_test1; 195 | drop user "acl test2"; 196 | drop user """acl=""s,/a//acl_test1"; 197 | -------------------------------------------------------------------------------- /sql/acl_uuid.sql: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_uuid; 3 | select 'a'::ace_uuid; 4 | select 'q'::ace_uuid; 5 | select 'a*'::ace_uuid; 6 | 7 | select 'a/'::ace_uuid; 8 | select 'a/hq'::ace_uuid; 9 | select 'a/h'::ace_uuid; 10 | 11 | select 'a/h/'::ace_uuid; 12 | 13 | select 'a/h/='::ace_uuid; 14 | select 'a/h/00000000-0000-0000-0000-000000000001='::ace_uuid; 15 | select 'a/h/00000000-0000-0000-0000-000000000001=d,'::ace_uuid; 16 | select 'a/h/00000000-0000-0000-0000-000000000001=dw'::ace_uuid; 17 | select 'a/ihpc/00000000-0000-0000-0000-000000000001=wdddw'::ace_uuid; 18 | select 'd/ihpc/00000000-0000-0000-0000-000000000001=wdddw'::ace_uuid; 19 | select 'd/ihpc/a0000000-ffff-b000-c000-d00000000001=wdddw'::ace_uuid; 20 | select 'a/ihpc/blah"=dw0'::ace_uuid; 21 | select 'd/ihpc/a0000000-ffff-b000-c000-d000000000010000=wdddw'::ace_uuid; 22 | 23 | -- check access 24 | select coalesce(acl_check_access('{}'::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 25 | select coalesce(acl_check_access('{}'::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true), 'NULL'); 26 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 27 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true), 'NULL'); 28 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{}'::uuid[], false), 'NULL'); 29 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{}'::uuid[], true), 'NULL'); 30 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', null::uuid[], false), 'NULL'); 31 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', null::uuid[], true), 'NULL'); 32 | 33 | select acl_check_access('{}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 34 | select acl_check_access('{}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true)::bit(32); 35 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 36 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true)::bit(32); 37 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::uuid[], false)::bit(32); 38 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::uuid[], true)::bit(32); 39 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), null::uuid[], false)::bit(32); 40 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), null::uuid[], true)::bit(32); 41 | 42 | select coalesce(acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], 'sdc0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 43 | select coalesce(acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], 'sdc0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true), 'NULL'); 44 | select acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 45 | select acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true)::bit(32); 46 | 47 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{}'::uuid[], null), 'NULL'); 48 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::uuid[], null)::bit(32); 49 | 50 | -- inherit only 51 | select coalesce(acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d/i/00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 52 | select acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d/i/00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 53 | 54 | -- merge 55 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 56 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, true); 57 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 58 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, true); 59 | 60 | -- inheritance 61 | 62 | -- container 63 | 64 | -- no flags -> not inherited 65 | select acl_merge('{a//00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 66 | 67 | -- inherit only -> not inherited 68 | select acl_merge('{a/i/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 69 | 70 | -- object inherit -> inherit only + object inherit 71 | select acl_merge('{a/o/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 72 | 73 | -- inherit only + object inherit -> inherit only + object inherit 74 | select acl_merge('{a/io/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 75 | 76 | -- object inherit + no propagate inherit -> no inheritance 77 | select acl_merge('{a/op/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 78 | 79 | -- inherit only + object inherit + no propagate inherit -> no inheritance 80 | select acl_merge('{a/iop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 81 | 82 | -- container inherit -> container inherit 83 | select acl_merge('{a/c/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 84 | 85 | -- inherit only + container inherit -> container inherit 86 | select acl_merge('{a/ic/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 87 | 88 | -- container inherit + no propagate inherit -> no flags 89 | select acl_merge('{a/cp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 90 | 91 | -- inherit only + container inherit + no propagate inherit -> no flags 92 | select acl_merge('{a/icp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 93 | 94 | -- container inherit + object inherit -> container inherit + object inherit 95 | select acl_merge('{a/co/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 96 | 97 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 98 | select acl_merge('{a/ico/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 99 | 100 | -- container inherit + object inherit + no propagate inherit -> no flags 101 | select acl_merge('{a/cop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 102 | 103 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 104 | select acl_merge('{a/icop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 105 | 106 | -- skip inherited 107 | select acl_merge('{a/h/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 108 | 109 | -- object 110 | 111 | -- no flags -> not inherited 112 | select acl_merge('{a//00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 113 | 114 | -- inherit only -> not inherited 115 | select acl_merge('{a/i/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 116 | 117 | -- object inherit -> no flags 118 | select acl_merge('{a/o/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 119 | 120 | -- inherit only + object inherit -> no flags 121 | select acl_merge('{a/io/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 122 | 123 | -- object inherit + no propagate inherit -> no flags 124 | select acl_merge('{a/op/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 125 | 126 | -- inherit only + object inherit + no propagate inherit -> no flags 127 | select acl_merge('{a/iop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 128 | 129 | -- container inherit -> not inherited 130 | select acl_merge('{a/c/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 131 | 132 | -- inherit only + container inherit -> not inherited 133 | select acl_merge('{a/ic/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 134 | 135 | -- container inherit + no propagate inherit -> not inherited 136 | select acl_merge('{a/cp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 137 | 138 | -- inherit only + container inherit + no propagate inherit -> not inherited 139 | select acl_merge('{a/icp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 140 | 141 | -- container inherit + object inherit -> no flags 142 | select acl_merge('{a/co/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 143 | 144 | -- inherit only + container inherit + object inherit -> no flags 145 | select acl_merge('{a/ico/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 146 | 147 | -- container inherit + object inherit + no propagate inherit -> no flags 148 | select acl_merge('{a/cop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 149 | 150 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 151 | select acl_merge('{a/icop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 152 | 153 | -- skip inherited 154 | select acl_merge('{a/h/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 155 | -------------------------------------------------------------------------------- /sql/acl_uuid_pg10.sql: -------------------------------------------------------------------------------- 1 | -- ACL format checks 2 | select ''::ace_uuid; 3 | select 'a'::ace_uuid; 4 | select 'q'::ace_uuid; 5 | select 'a*'::ace_uuid; 6 | 7 | select 'a/'::ace_uuid; 8 | select 'a/hq'::ace_uuid; 9 | select 'a/h'::ace_uuid; 10 | 11 | select 'a/h/'::ace_uuid; 12 | 13 | select 'a/h/='::ace_uuid; 14 | select 'a/h/00000000-0000-0000-0000-000000000001='::ace_uuid; 15 | select 'a/h/00000000-0000-0000-0000-000000000001=d,'::ace_uuid; 16 | select 'a/h/00000000-0000-0000-0000-000000000001=dw'::ace_uuid; 17 | select 'a/ihpc/00000000-0000-0000-0000-000000000001=wdddw'::ace_uuid; 18 | select 'd/ihpc/00000000-0000-0000-0000-000000000001=wdddw'::ace_uuid; 19 | select 'd/ihpc/a0000000-ffff-b000-c000-d00000000001=wdddw'::ace_uuid; 20 | select 'a/ihpc/blah"=dw0'::ace_uuid; 21 | select 'd/ihpc/a0000000-ffff-b000-c000-d000000000010000=wdddw'::ace_uuid; 22 | 23 | -- check access 24 | select coalesce(acl_check_access('{}'::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 25 | select coalesce(acl_check_access('{}'::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true), 'NULL'); 26 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 27 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true), 'NULL'); 28 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{}'::uuid[], false), 'NULL'); 29 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{}'::uuid[], true), 'NULL'); 30 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', null::uuid[], false), 'NULL'); 31 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', null::uuid[], true), 'NULL'); 32 | 33 | select acl_check_access('{}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 34 | select acl_check_access('{}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true)::bit(32); 35 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 36 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true)::bit(32); 37 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::uuid[], false)::bit(32); 38 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::uuid[], true)::bit(32); 39 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), null::uuid[], false)::bit(32); 40 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), null::uuid[], true)::bit(32); 41 | 42 | select coalesce(acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], 'sdc0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 43 | select coalesce(acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], 'sdc0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true), 'NULL'); 44 | select acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 45 | select acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d//00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], true)::bit(32); 46 | 47 | select coalesce(acl_check_access(null::ace_uuid[], 'sd0', '{}'::uuid[], null), 'NULL'); 48 | select acl_check_access(null::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{}'::uuid[], null)::bit(32); 49 | 50 | -- inherit only 51 | select coalesce(acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d/i/00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], 'sd0', '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false), 'NULL'); 52 | select acl_check_access('{d//00000000-0000-0000-0000-000000000001=w,d/i/00000000-0000-0000-0000-000000000002=s,a//00000000-0000-0000-0000-000000000002=sdw,a//00000000-0000-0000-0000-000000000003=0}'::ace_uuid[], (1 << 0) | (1 << 27) | (1 << 29), '{00000000-0000-0000-0000-000000000003, 00000000-0000-0000-0000-000000000002}'::uuid[], false)::bit(32); 53 | 54 | -- merge 55 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 56 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, true); 57 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 58 | select acl_merge(null::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, true); 59 | 60 | -- inheritance 61 | 62 | -- container 63 | 64 | -- no flags -> not inherited 65 | select acl_merge('{a//00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 66 | 67 | -- inherit only -> not inherited 68 | select acl_merge('{a/i/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 69 | 70 | -- object inherit -> inherit only + object inherit 71 | select acl_merge('{a/o/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 72 | 73 | -- inherit only + object inherit -> inherit only + object inherit 74 | select acl_merge('{a/io/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 75 | 76 | -- object inherit + no propagate inherit -> no inheritance 77 | select acl_merge('{a/op/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 78 | 79 | -- inherit only + object inherit + no propagate inherit -> no inheritance 80 | select acl_merge('{a/iop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 81 | 82 | -- container inherit -> container inherit 83 | select acl_merge('{a/c/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 84 | 85 | -- inherit only + container inherit -> container inherit 86 | select acl_merge('{a/ic/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 87 | 88 | -- container inherit + no propagate inherit -> no flags 89 | select acl_merge('{a/cp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 90 | 91 | -- inherit only + container inherit + no propagate inherit -> no flags 92 | select acl_merge('{a/icp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 93 | 94 | -- container inherit + object inherit -> container inherit + object inherit 95 | select acl_merge('{a/co/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 96 | 97 | -- inherit only + container inherit + object inherit -> container inherit + object inherit 98 | select acl_merge('{a/ico/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 99 | 100 | -- container inherit + object inherit + no propagate inherit -> no flags 101 | select acl_merge('{a/cop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 102 | 103 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 104 | select acl_merge('{a/icop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 105 | 106 | -- skip inherited 107 | select acl_merge('{a/h/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], true, false); 108 | 109 | -- object 110 | 111 | -- no flags -> not inherited 112 | select acl_merge('{a//00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 113 | 114 | -- inherit only -> not inherited 115 | select acl_merge('{a/i/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 116 | 117 | -- object inherit -> no flags 118 | select acl_merge('{a/o/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 119 | 120 | -- inherit only + object inherit -> no flags 121 | select acl_merge('{a/io/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 122 | 123 | -- object inherit + no propagate inherit -> no flags 124 | select acl_merge('{a/op/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 125 | 126 | -- inherit only + object inherit + no propagate inherit -> no flags 127 | select acl_merge('{a/iop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 128 | 129 | -- container inherit -> not inherited 130 | select acl_merge('{a/c/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 131 | 132 | -- inherit only + container inherit -> not inherited 133 | select acl_merge('{a/ic/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 134 | 135 | -- container inherit + no propagate inherit -> not inherited 136 | select acl_merge('{a/cp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 137 | 138 | -- inherit only + container inherit + no propagate inherit -> not inherited 139 | select acl_merge('{a/icp/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 140 | 141 | -- container inherit + object inherit -> no flags 142 | select acl_merge('{a/co/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 143 | 144 | -- inherit only + container inherit + object inherit -> no flags 145 | select acl_merge('{a/ico/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 146 | 147 | -- container inherit + object inherit + no propagate inherit -> no flags 148 | select acl_merge('{a/cop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 149 | 150 | -- inherit only + container inherit + object inherit + no propagate inherit -> no flags 151 | select acl_merge('{a/icop/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 152 | 153 | -- skip inherited 154 | select acl_merge('{a/h/00000000-0000-0000-0000-000000000001=d}'::ace_uuid[], '{a//00000000-0000-0000-0000-000000000000=0,d//00000000-0000-0000-0000-000000000000=1,a//00000000-0000-0000-0000-000000000000=23,d//00000000-0000-0000-0000-000000000000=4}'::ace_uuid[], false, false); 155 | -------------------------------------------------------------------------------- /sql/install.sql: -------------------------------------------------------------------------------- 1 | create extension acl; 2 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * util.c 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #include "util.h" 10 | 11 | static void check_who_array(ArrayType *who_array); 12 | 13 | bool 14 | check_access_extract_args(FunctionCallInfo fcinfo, ArrayType **acl, 15 | uint32 *mask, ArrayType **who, bool *implicit_allow, 16 | bool extract_who, bool has_who_argument) 17 | { 18 | if (PG_ARGISNULL(0)) 19 | *acl = NULL; 20 | else 21 | *acl = PG_GETARG_ARRAYTYPE_P(0); 22 | 23 | if (PG_ARGISNULL(1)) 24 | return false; 25 | 26 | *mask = PG_GETARG_UINT32(1); 27 | 28 | if (has_who_argument && PG_ARGISNULL(2)) 29 | return false; 30 | 31 | if (extract_who) 32 | { 33 | *who = PG_GETARG_ARRAYTYPE_P(2); 34 | check_who_array(*who); 35 | } 36 | 37 | if (PG_ARGISNULL(has_who_argument ? 3 : 2)) 38 | ereport(ERROR, 39 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 40 | errmsg("allow_implicit argument must be not null"))); 41 | 42 | *implicit_allow = PG_GETARG_BOOL(has_who_argument ? 3 : 2); 43 | 44 | return true; 45 | } 46 | 47 | bool 48 | check_access_text_mask_extract_args(FunctionCallInfo fcinfo, ArrayType **acl, 49 | text **mask, ArrayType **who, 50 | bool *implicit_allow, bool extract_who, 51 | bool has_who_argument) 52 | { 53 | if (PG_ARGISNULL(0)) 54 | *acl = NULL; 55 | else 56 | *acl = PG_GETARG_ARRAYTYPE_P(0); 57 | 58 | if (PG_ARGISNULL(1)) 59 | return false; 60 | 61 | *mask = PG_GETARG_TEXT_P(1); 62 | 63 | if (has_who_argument && PG_ARGISNULL(2)) 64 | return false; 65 | 66 | if (extract_who) 67 | { 68 | *who = PG_GETARG_ARRAYTYPE_P(2); 69 | check_who_array(*who); 70 | } 71 | 72 | if (PG_ARGISNULL(has_who_argument ? 3 : 2)) 73 | ereport(ERROR, 74 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 75 | errmsg("allow_implicit argument must be not null"))); 76 | 77 | *implicit_allow = PG_GETARG_BOOL(has_who_argument ? 3 : 2); 78 | 79 | return true; 80 | } 81 | 82 | void 83 | merge_acls_extract_args(FunctionCallInfo fcinfo, ArrayType **parent, 84 | ArrayType **child, bool *container, bool *deny_first) 85 | { 86 | if (PG_ARGISNULL(0)) 87 | *parent = NULL; 88 | else 89 | *parent = PG_GETARG_ARRAYTYPE_P(0); 90 | 91 | if (PG_ARGISNULL(1)) 92 | ereport(ERROR, 93 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 94 | errmsg("ACL must be not null"))); 95 | 96 | *child = PG_GETARG_ARRAYTYPE_P(1); 97 | 98 | if (PG_ARGISNULL(2)) 99 | ereport(ERROR, 100 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 101 | errmsg("container argument must be not null"))); 102 | 103 | *container = PG_GETARG_BOOL(2); 104 | 105 | if (PG_ARGISNULL(3)) 106 | ereport(ERROR, 107 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 108 | errmsg("deny_first argument must be not null"))); 109 | 110 | *deny_first = PG_GETARG_BOOL(3); 111 | } 112 | 113 | static void 114 | check_who_array(ArrayType *who_array) 115 | { 116 | if (ARR_HASNULL(who_array)) 117 | ereport(ERROR, 118 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 119 | errmsg("Who array must not contain null values"))); 120 | 121 | if (ARR_NDIM(who_array) > 1) 122 | ereport(ERROR, 123 | (errcode(ERRCODE_INTERNAL_ERROR), 124 | errmsg("wrong number of dimensions of who array"), 125 | errdetail("Who array must be one dimensional."))); 126 | 127 | if (ARR_NDIM(who_array) > 0 && ARR_LBOUND(who_array)[0] != 1) 128 | ereport(ERROR, 129 | (errcode(ERRCODE_INTERNAL_ERROR), 130 | errmsg("wrong range of who array"), 131 | errdetail("Lower bound of who array must be one."))); 132 | } 133 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------- 2 | * 3 | * util.h 4 | * 5 | * Copyright (c) 2015-2023 Vladislav Arkhipov 6 | * 7 | * ------------------------------------------------------------------------- 8 | */ 9 | #ifndef __UTIL_H__ 10 | #define __UTIL_H__ 11 | 12 | #include "postgres.h" 13 | #include "fmgr.h" 14 | 15 | #include "utils/array.h" 16 | 17 | bool check_access_extract_args(FunctionCallInfo fcinfo, ArrayType **acl, 18 | uint32 *mask, ArrayType **who, 19 | bool *implicit_allow, bool extract_who, 20 | bool has_who_argument); 21 | bool check_access_text_mask_extract_args(FunctionCallInfo fcinfo, 22 | ArrayType **acl, text **mask, 23 | ArrayType **who, bool *implicit_allow, 24 | bool extract_who, 25 | bool has_who_argument); 26 | 27 | void merge_acls_extract_args(FunctionCallInfo fcinfo, ArrayType **parent, 28 | ArrayType **child, bool *container, 29 | bool *deny_first); 30 | 31 | #endif 32 | --------------------------------------------------------------------------------