/src/tdengine/source/common/src/tpriv.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com> |
3 | | * |
4 | | * This program is free software: you can use, redistribute, and/or modify |
5 | | * it under the terms of the GNU Affero General Public License, version 3 |
6 | | * or later ("AGPL"), as published by the Free Software Foundation. |
7 | | * |
8 | | * This program is distributed in the hope that it will be useful, but WITHOUT |
9 | | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
10 | | * FITNESS FOR A PARTICULAR PURPOSE. |
11 | | * |
12 | | * You should have received a copy of the GNU Affero General Public License |
13 | | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
14 | | */ |
15 | | |
16 | | #define _DEFAULT_SOURCE |
17 | | #include "systable.h" |
18 | | #include "tpriv.h" |
19 | | #include "tmsg.h" |
20 | | #include "tutil.h" |
21 | | |
22 | | static TdThreadOnce privInit = PTHREAD_ONCE_INIT; |
23 | | |
24 | | typedef struct { |
25 | | const char* name; |
26 | | int32_t level; |
27 | | } SPrivObjInfo; |
28 | | |
29 | | static const SPrivObjInfo __privObjInfo[] = { |
30 | | {"CLUSTER", 0}, {"NODE", 0}, {"DATABASE", 0}, {"TABLE", 1}, {"FUNCTION", 0}, {"INDEX", 1}, |
31 | | {"VIEW", 1}, {"USER", 0}, {"ROLE", 0}, {"RSMA", 1}, {"TSMA", 1}, {"TOPIC", 1}, |
32 | | {"STREAM", 1}, {"MOUNT", 0}, {"AUDIT", 0}, {"TOKEN", 0}, {"NONE", 1}, {"XTASK", 0}, |
33 | | }; |
34 | | |
35 | | /** |
36 | | * N.B. increase the macro PRIV_INFO_TABLE_VERSION for any update of privInfoTable |
37 | | */ |
38 | | |
39 | | #define SYS_ADMIN_BASIC_ROLES (T_ROLE_SYSDBA | T_ROLE_SYSSEC | T_ROLE_SYSAUDIT) |
40 | | #define SYS_ADMIN_CORE_ROLES (T_ROLE_SYSDBA | T_ROLE_SYSSEC) |
41 | | #define SYS_ADMIN_INFO1_ROLES (SYS_ADMIN_BASIC_ROLES | T_ROLE_SYSINFO_1) |
42 | | #define SYS_ADMIN_INFO_ROLES (SYS_ADMIN_BASIC_ROLES | T_ROLE_SYSINFO_0 | T_ROLE_SYSINFO_1) |
43 | | #define SYS_ADMIN_EXT_ROLES (T_ROLE_SYSINFO_0 | T_ROLE_SYSINFO_1 | T_ROLE_SYSAUDIT_LOG) |
44 | | #define SYS_ADMIN_ALL_ROLES (SYS_ADMIN_BASIC_ROLES | T_ROLE_SYSAUDIT_LOG | T_ROLE_SYSINFO_0 | T_ROLE_SYSINFO_1) |
45 | | |
46 | | static SPrivInfo privInfoTable[] = { |
47 | | // ==================== common privileges ==================== |
48 | | {PRIV_CM_ALL, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "ALL"}, |
49 | | {PRIV_CM_ALTER, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "ALTER"}, |
50 | | {PRIV_CM_DROP, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "DROP"}, |
51 | | {PRIV_CM_SHOW, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "SHOW"}, |
52 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "SHOW CREATE"}, |
53 | | {PRIV_CM_START, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "START"}, |
54 | | {PRIV_CM_STOP, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "STOP"}, |
55 | | {PRIV_CM_RECALC, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "RECALCULATE"}, |
56 | | {PRIV_CM_KILL, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "KILL"}, |
57 | | {PRIV_CM_SUBSCRIBE, PRIV_CATEGORY_COMMON, 0, 0, 0, 0, "", "SUBSCRIBE"}, |
58 | | |
59 | | // ==================== system privileges ==================== |
60 | | // Database Management |
61 | | {PRIV_DB_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE DATABASE"}, |
62 | | {PRIV_VG_BALANCE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "BALANCE VGROUP"}, |
63 | | {PRIV_VG_BALANCE_LEADER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "BALANCE VGROUP LEADER"}, |
64 | | {PRIV_VG_MERGE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "MERGE VGROUP"}, |
65 | | {PRIV_VG_REDISTRIBUTE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "REDISTRIBUTE VGROUP"}, |
66 | | {PRIV_VG_SPLIT, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "SPLIT VGROUP"}, |
67 | | |
68 | | // Function Privileges |
69 | | {PRIV_FUNC_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE FUNCTION"}, |
70 | | {PRIV_FUNC_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "DROP FUNCTION"}, |
71 | | {PRIV_FUNC_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW FUNCTIONS"}, |
72 | | |
73 | | // Mount Privileges |
74 | | {PRIV_MOUNT_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE MOUNT"}, |
75 | | {PRIV_MOUNT_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "DROP MOUNT"}, |
76 | | {PRIV_MOUNT_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW MOUNTS"}, |
77 | | |
78 | | // User Management |
79 | | {PRIV_USER_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE USER"}, |
80 | | {PRIV_USER_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "DROP USER"}, |
81 | | {PRIV_USER_SET_SECURITY, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA | T_ROLE_SYSSEC, 0, "", |
82 | | "SET USER SECURITY INFORMATION"}, |
83 | | {PRIV_USER_SET_AUDIT, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA | T_ROLE_SYSAUDIT, 0, "", |
84 | | "SET USER AUDIT INFORMATION"}, |
85 | | {PRIV_USER_SET_BASIC, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "SET USER BASIC INFORMATION"}, |
86 | | {PRIV_USER_UNLOCK, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_CORE_ROLES, 0, "", "UNLOCK USER"}, |
87 | | {PRIV_USER_LOCK, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_CORE_ROLES, 0, "", "LOCK USER"}, |
88 | | {PRIV_USER_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW USERS"}, |
89 | | {PRIV_USER_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "ALTER USER"}, |
90 | | {PRIV_USER_SHOW_SECURITY, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_BASIC_ROLES, 0, "", |
91 | | "SHOW USERS SECURITY INFORMATION"}, |
92 | | |
93 | | // Role Management |
94 | | {PRIV_ROLE_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE ROLE"}, |
95 | | {PRIV_ROLE_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "DROP ROLE"}, |
96 | | {PRIV_ROLE_UNLOCK, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_CORE_ROLES, 0, "", "UNLOCK ROLE"}, |
97 | | {PRIV_ROLE_LOCK, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_CORE_ROLES, 0, "", "LOCK ROLE"}, |
98 | | {PRIV_ROLE_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW ROLES"}, |
99 | | |
100 | | // Token Privileges |
101 | | {PRIV_TOKEN_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "CREATE TOKEN"}, |
102 | | {PRIV_TOKEN_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "DROP TOKEN"}, |
103 | | {PRIV_TOKEN_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "ALTER TOKEN"}, |
104 | | {PRIV_TOKEN_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_BASIC_ROLES, 0, "", "SHOW TOKENS"}, |
105 | | |
106 | | // Node Management |
107 | | {PRIV_NODE_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE NODE"}, |
108 | | {PRIV_NODE_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "ALTER NODE"}, |
109 | | {PRIV_NODE_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "DROP NODE"}, |
110 | | {PRIV_NODES_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW NODES"}, |
111 | | |
112 | | // System Variables |
113 | | {PRIV_VAR_SECURITY_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "ALTER SECURITY VARIABLE"}, |
114 | | {PRIV_VAR_AUDIT_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT, 0, "", "ALTER AUDIT VARIABLE"}, |
115 | | {PRIV_VAR_SYSTEM_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "ALTER SYSTEM VARIABLE"}, |
116 | | {PRIV_VAR_DEBUG_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "ALTER DEBUG VARIABLE"}, |
117 | | {PRIV_VAR_SECURITY_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW SECURITY VARIABLE"}, |
118 | | {PRIV_VAR_AUDIT_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW AUDIT VARIABLE"}, |
119 | | {PRIV_VAR_SYSTEM_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW SYSTEM VARIABLE"}, |
120 | | {PRIV_VAR_DEBUG_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW DEBUG VARIABLE"}, |
121 | | |
122 | | // Key/Password Management |
123 | | {PRIV_KEY_UPDATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "UPDATE KEY"}, |
124 | | {PRIV_TOTP_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "CREATE TOTP_SECRET"}, |
125 | | {PRIV_TOTP_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "DROP TOTP_SECRET"}, |
126 | | {PRIV_PASS_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "ALTER PASS"}, |
127 | | {PRIV_PASS_ALTER_SELF, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "ALTER SELF PASS"}, |
128 | | |
129 | | // Grant/Revoke Privileges |
130 | | {PRIV_GRANT_PRIVILEGE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "GRANT PRIVILEGE"}, |
131 | | {PRIV_REVOKE_PRIVILEGE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "REVOKE PRIVILEGE"}, |
132 | | {PRIV_SHOW_PRIVILEGES, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW PRIVILEGES"}, |
133 | | {PRIV_GRANT_SYSDBA, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "GRANT SYSDBA PRIVILEGE"}, |
134 | | {PRIV_REVOKE_SYSDBA, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "REVOKE SYSDBA PRIVILEGE"}, |
135 | | {PRIV_GRANT_SYSSEC, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "GRANT SYSSEC PRIVILEGE"}, |
136 | | {PRIV_REVOKE_SYSSEC, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "REVOKE SYSSEC PRIVILEGE"}, |
137 | | {PRIV_GRANT_SYSAUDIT, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT, 0, "", "GRANT SYSAUDIT PRIVILEGE"}, |
138 | | {PRIV_REVOKE_SYSAUDIT, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT, 0, "", "REVOKE SYSAUDIT PRIVILEGE"}, |
139 | | |
140 | | // Audit Management |
141 | | {PRIV_AUDIT_DB_DROP, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT, 0, "", "DROP AUDIT DATABASE"}, |
142 | | {PRIV_AUDIT_DB_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT, 0, "", "ALTER AUDIT DATABASE"}, |
143 | | {PRIV_AUDIT_DB_USE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT | T_ROLE_SYSAUDIT_LOG, 0, "", "USE AUDIT DATABASE"}, |
144 | | {PRIV_AUDIT_TBL_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT_LOG, 0, "", "CREATE AUDIT TABLE"}, |
145 | | {PRIV_AUDIT_TBL_SELECT, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT, 0, "", "SELECT AUDIT TABLE"}, |
146 | | {PRIV_AUDIT_TBL_INSERT, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSAUDIT_LOG, 0, "", "INSERT AUDIT TABLE"}, |
147 | | |
148 | | // System Administration |
149 | | {PRIV_TRANS_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW TRANS"}, |
150 | | {PRIV_TRANS_KILL, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "KILL TRANS"}, |
151 | | {PRIV_CONN_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW CONNECTIONS"}, |
152 | | {PRIV_CONN_KILL, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "KILL CONNECTION"}, |
153 | | {PRIV_QUERY_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW QUERIES"}, |
154 | | {PRIV_QUERY_KILL, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "KILL QUERY"}, |
155 | | {PRIV_INFO_SCHEMA_READ_BASIC, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", |
156 | | "READ INFORMATION SCHEMA BASIC"}, |
157 | | {PRIV_INFO_SCHEMA_READ_SEC, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", |
158 | | "READ INFORMATION SCHEMA SECURITY"}, |
159 | | {PRIV_INFO_SCHEMA_READ_AUDIT, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", |
160 | | "READ INFORMATION SCHEMA AUDIT"}, |
161 | | {PRIV_INFO_SCHEMA_READ_PRIVILEGED, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", |
162 | | "READ INFORMATION SCHEMA PRIVILEGED"}, |
163 | | {PRIV_PERF_SCHEMA_READ_BASIC, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", |
164 | | "READ PERFORMANCE SCHEMA BASIC"}, |
165 | | {PRIV_PERF_SCHEMA_READ_PRIVILEGED, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", |
166 | | "READ PERFORMANCE SCHEMA PRIVILEGED"}, |
167 | | {PRIV_GRANTS_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW GRANTS"}, |
168 | | {PRIV_CLUSTER_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW CLUSTER"}, |
169 | | {PRIV_APPS_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO_ROLES, 0, "", "SHOW APPS"}, |
170 | | // Xnode Task Management |
171 | | {PRIV_XNODE_TASK_CREATE, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSDBA, 0, "", "CREATE XNODE TASK"}, |
172 | | |
173 | | // Security Policy Management |
174 | | {PRIV_SECURITY_POLICY_ALTER, PRIV_CATEGORY_SYSTEM, 0, 0, T_ROLE_SYSSEC, 0, "", "ALTER SECURITY POLICY"}, |
175 | | {PRIV_SECURITY_POLICIES_SHOW, PRIV_CATEGORY_SYSTEM, 0, 0, SYS_ADMIN_INFO1_ROLES, 0, "", "SHOW SECURITY POLICIES"}, |
176 | | |
177 | | // ==================== object privileges ==================== |
178 | | // Cluster Privileges |
179 | | {PRIV_CM_ALTER, PRIV_CATEGORY_OBJECT, PRIV_OBJ_CLUSTER, 0, SYS_ADMIN_INFO1_ROLES, 2, "", "ALTER CLUSTER"}, |
180 | | |
181 | | // Database Privileges |
182 | | {PRIV_CM_ALTER, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "ALTER DATABASE"}, |
183 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "DROP DATABASE"}, |
184 | | {PRIV_DB_USE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_BASIC_ROLES, 3, "", "USE DATABASE"}, |
185 | | {PRIV_DB_USE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_EXT_ROLES, 3, TSDB_INFORMATION_SCHEMA_DB, |
186 | | "USE DATABASE"}, |
187 | | {PRIV_DB_USE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_EXT_ROLES, 3, TSDB_PERFORMANCE_SCHEMA_DB, |
188 | | "USE DATABASE"}, |
189 | | {PRIV_DB_FLUSH, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "FLUSH DATABASE"}, |
190 | | {PRIV_DB_COMPACT, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "COMPACT DATABASE"}, |
191 | | {PRIV_DB_TRIM, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "TRIM DATABASE"}, |
192 | | {PRIV_DB_ROLLUP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "ROLLUP DATABASE"}, |
193 | | {PRIV_DB_SCAN, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 1, "", "SCAN DATABASE"}, |
194 | | {PRIV_DB_SSMIGRATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "SSMIGRATE DATABASE"}, |
195 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW DATABASES"}, |
196 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE DATABASE"}, |
197 | | {PRIV_SHOW_VNODES, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO1_ROLES, 1, "", "SHOW VNODES"}, |
198 | | {PRIV_SHOW_VGROUPS, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO1_ROLES, 1, "", "SHOW VGROUPS"}, |
199 | | {PRIV_SHOW_COMPACTS, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO1_ROLES, 1, "", "SHOW COMPACTS"}, |
200 | | {PRIV_SHOW_RETENTIONS, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO1_ROLES, 1, "", "SHOW RETENTIONS"}, |
201 | | {PRIV_SHOW_SCANS, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO1_ROLES, 1, "", "SHOW SCANS"}, |
202 | | {PRIV_SHOW_SSMIGRATES, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, SYS_ADMIN_INFO1_ROLES, 1, "", "SHOW SSMIGRATES"}, |
203 | | |
204 | | // Table Privileges |
205 | | {PRIV_TBL_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "CREATE TABLE"}, |
206 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, T_ROLE_SYSDBA, 2, "", "DROP TABLE"}, |
207 | | {PRIV_CM_ALTER, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, T_ROLE_SYSDBA, 2, "", "ALTER TABLE"}, |
208 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW TABLES"}, |
209 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE TABLE"}, |
210 | | {PRIV_TBL_SELECT, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, 0, 1, "", "SELECT"}, |
211 | | {PRIV_TBL_INSERT, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, 0, 2, "", "INSERT"}, |
212 | | {PRIV_TBL_UPDATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, 0, 2, "", "UPDATE"}, |
213 | | {PRIV_TBL_DELETE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, 0, 2, "", "DELETE"}, |
214 | | |
215 | | // Index Privileges |
216 | | {PRIV_IDX_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, T_ROLE_SYSDBA, 2, "", "CREATE INDEX"}, |
217 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_IDX, 1, T_ROLE_SYSDBA, 2, "", "DROP INDEX"}, |
218 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_IDX, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW INDEXES"}, |
219 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_IDX, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE INDEX"}, |
220 | | |
221 | | // RSMA Privileges |
222 | | {PRIV_RSMA_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, T_ROLE_SYSDBA, 2, "", "CREATE RSMA"}, |
223 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_RSMA, 1, T_ROLE_SYSDBA, 2, "", "DROP RSMA"}, |
224 | | {PRIV_CM_ALTER, PRIV_CATEGORY_OBJECT, PRIV_OBJ_RSMA, 1, T_ROLE_SYSDBA, 2, "", "ALTER RSMA"}, |
225 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_RSMA, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW RSMAS"}, |
226 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_RSMA, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE RSMA"}, |
227 | | |
228 | | // TSMA Privileges |
229 | | {PRIV_TSMA_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TBL, 1, T_ROLE_SYSDBA, 2, "", "CREATE TSMA"}, |
230 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TSMA, 1, T_ROLE_SYSDBA, 2, "", "DROP TSMA"}, |
231 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TSMA, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW TSMAS"}, |
232 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TSMA, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE TSMA"}, |
233 | | |
234 | | // View Privileges |
235 | | {PRIV_VIEW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "CREATE VIEW"}, |
236 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_VIEW, 1, T_ROLE_SYSDBA, 2, "", "DROP VIEW"}, |
237 | | {PRIV_CM_ALTER, PRIV_CATEGORY_OBJECT, PRIV_OBJ_VIEW, 1, T_ROLE_SYSDBA, 2, "", "ALTER VIEW"}, |
238 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_VIEW, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW VIEWS"}, |
239 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_VIEW, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE VIEW"}, |
240 | | {PRIV_VIEW_SELECT, PRIV_CATEGORY_OBJECT, PRIV_OBJ_VIEW, 1, 0, 1, "", "SELECT VIEW"}, |
241 | | |
242 | | // Topic Privileges |
243 | | {PRIV_TOPIC_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "CREATE TOPIC"}, |
244 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TOPIC, 1, T_ROLE_SYSDBA, 2, "", "DROP TOPIC"}, |
245 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TOPIC, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW TOPICS"}, |
246 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TOPIC, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE TOPIC"}, |
247 | | {PRIV_CM_SUBSCRIBE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TOPIC, 1, 0, 1, "", "SUBSCRIBE TOPIC"}, |
248 | | {PRIV_CONSUMER_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TOPIC, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CONSUMERS"}, |
249 | | {PRIV_SUBSCRIPTION_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_TOPIC, 1, SYS_ADMIN_INFO_ROLES, 1, "", |
250 | | "SHOW SUBSCRIPTIONS"}, |
251 | | // Stream Privileges |
252 | | {PRIV_STREAM_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_DB, 0, T_ROLE_SYSDBA, 2, "", "CREATE STREAM"}, |
253 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_STREAM, 1, T_ROLE_SYSDBA, 2, "", "DROP STREAM"}, |
254 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_STREAM, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW STREAMS"}, |
255 | | {PRIV_CM_SHOW_CREATE, PRIV_CATEGORY_OBJECT, PRIV_OBJ_STREAM, 1, SYS_ADMIN_INFO_ROLES, 1, "", "SHOW CREATE STREAM"}, |
256 | | {PRIV_CM_START, PRIV_CATEGORY_OBJECT, PRIV_OBJ_STREAM, 1, T_ROLE_SYSDBA, 2, "", "START STREAM"}, |
257 | | {PRIV_CM_STOP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_STREAM, 1, T_ROLE_SYSDBA, 2, "", "STOP STREAM"}, |
258 | | {PRIV_CM_RECALC, PRIV_CATEGORY_OBJECT, PRIV_OBJ_STREAM, 1, T_ROLE_SYSDBA, 2, "", "RECALCULATE STREAM"}, |
259 | | // Xnode/Xnode Task Privileges |
260 | | {PRIV_CM_SHOW, PRIV_CATEGORY_OBJECT, PRIV_OBJ_XTASK, 0, T_ROLE_SYSDBA, 1, "", "SHOW XNODE TASKS"}, |
261 | | {PRIV_CM_ALTER, PRIV_CATEGORY_OBJECT, PRIV_OBJ_XTASK, 0, T_ROLE_SYSDBA, 2, "", "ALTER XNODE TASK"}, |
262 | | {PRIV_CM_DROP, PRIV_CATEGORY_OBJECT, PRIV_OBJ_XTASK, 0, T_ROLE_SYSDBA, 2, "", "DROP XNODE TASK"}, |
263 | | }; |
264 | | |
265 | | static SPrivInfo* privLookup[MAX_PRIV_TYPE + 1] = {0}; |
266 | | |
267 | 0 | static void initPrivLookup(void) { |
268 | 0 | for (size_t i = 0; i < sizeof(privInfoTable) / sizeof(privInfoTable[0]); ++i) { |
269 | 0 | EPrivType privType = privInfoTable[i].privType; |
270 | 0 | if (privType <= MAX_PRIV_TYPE && |
271 | 0 | !privLookup[privType]) { // duplicated items for other purpose, e.g. createDefaultRoles. |
272 | 0 | privLookup[privType] = &privInfoTable[i]; |
273 | 0 | } |
274 | 0 | } |
275 | 0 | } |
276 | | |
277 | 0 | int32_t privExpandAll(SPrivSet* privSet, EPrivObjType pObjType, uint8_t pObjLevel) { |
278 | 0 | if (!privSet) return TSDB_CODE_APP_ERROR; |
279 | 0 | if (!PRIV_HAS(privSet, PRIV_CM_ALL)) return TSDB_CODE_SUCCESS; |
280 | | |
281 | 0 | SPrivInfoIter iter = {0}; |
282 | 0 | privInfoIterInit(&iter); |
283 | |
|
284 | 0 | SPrivInfo* pPrivInfo = NULL; |
285 | 0 | while (privInfoIterNext(&iter, &pPrivInfo)) { |
286 | 0 | if (pPrivInfo->objType != pObjType) continue; |
287 | 0 | if (pPrivInfo->objLevel != pObjLevel) { |
288 | 0 | uWarn("privExpandAll: skip privType %d due to level mismatch, expected %d vs %d", pPrivInfo->privType, pObjLevel, |
289 | 0 | pPrivInfo->objLevel); |
290 | 0 | continue; |
291 | 0 | } |
292 | 0 | if (pPrivInfo->category != PRIV_CATEGORY_OBJECT) { |
293 | 0 | uWarn("privExpandAll: skip privType %d due to category mismatch, expected OBJECT vs %d", pPrivInfo->privType, |
294 | 0 | pPrivInfo->category); |
295 | 0 | continue; |
296 | 0 | } |
297 | 0 | privAddType(privSet, pPrivInfo->privType); |
298 | 0 | } |
299 | |
|
300 | 0 | return TSDB_CODE_SUCCESS; |
301 | 0 | } |
302 | | |
303 | 0 | int32_t privExpandRw(SPrivSet* privSet, EPrivObjType pObjType, uint8_t pObjLevel) { |
304 | 0 | if (!privSet) return TSDB_CODE_APP_ERROR; |
305 | | |
306 | 0 | bool hasRead = PRIV_HAS(privSet, PRIV_CM_READ); |
307 | 0 | bool hasWrite = PRIV_HAS(privSet, PRIV_CM_WRITE); |
308 | |
|
309 | 0 | if (!hasRead && !hasWrite) return TSDB_CODE_SUCCESS; |
310 | | |
311 | | // Remove the legacy types |
312 | 0 | if (hasRead) privRemoveType(privSet, PRIV_CM_READ); |
313 | 0 | if (hasWrite) privRemoveType(privSet, PRIV_CM_WRITE); |
314 | |
|
315 | 0 | SPrivInfoIter iter = {0}; |
316 | 0 | privInfoIterInit(&iter); |
317 | |
|
318 | 0 | SPrivInfo* pPrivInfo = NULL; |
319 | 0 | while (privInfoIterNext(&iter, &pPrivInfo)) { |
320 | 0 | if (pPrivInfo->objType != pObjType) continue; |
321 | 0 | if (pPrivInfo->objLevel != pObjLevel) continue; |
322 | 0 | if (pPrivInfo->category != PRIV_CATEGORY_OBJECT) continue; |
323 | | |
324 | | // Check rwAttr and add corresponding privileges |
325 | | // rwAttr: 1 = read, 2 = write, 3 = read/write |
326 | 0 | if (hasRead && (pPrivInfo->rwAttr & PRIV_RW_ATTR_READ)) { |
327 | 0 | privAddType(privSet, pPrivInfo->privType); |
328 | 0 | } |
329 | 0 | if (hasWrite && (pPrivInfo->rwAttr & PRIV_RW_ATTR_WRITE)) { |
330 | 0 | privAddType(privSet, pPrivInfo->privType); |
331 | 0 | } |
332 | 0 | } |
333 | |
|
334 | 0 | return TSDB_CODE_SUCCESS; |
335 | 0 | } |
336 | | |
337 | 0 | int32_t privUpgradeRwDb(SHashObj* objPrivs, const char* dbFName, const char* tbName, uint8_t rwAttr) { |
338 | 0 | if (!objPrivs) return TSDB_CODE_APP_ERROR; |
339 | | |
340 | 0 | int32_t code = 0, lino = 0; |
341 | 0 | char key[TSDB_PRIV_MAX_KEY_LEN] = {0}; |
342 | 0 | SPrivInfoIter iter = {0}; |
343 | 0 | privInfoIterInit(&iter); |
344 | |
|
345 | 0 | SPrivInfo* pPrivInfo = NULL; |
346 | 0 | while (privInfoIterNext(&iter, &pPrivInfo)) { |
347 | 0 | if ((pPrivInfo->rwAttr & rwAttr) == 0) continue; |
348 | 0 | SPrivInfo privInfo = {.objType = pPrivInfo->objType, .objLevel = pPrivInfo->objLevel}; |
349 | 0 | int32_t keyLen = privObjKeyF(&privInfo, dbFName, tbName, key, sizeof(key)); |
350 | |
|
351 | 0 | SPrivObjPolicies* policies = taosHashGet(objPrivs, key, keyLen + 1); |
352 | 0 | if (policies == NULL) { |
353 | 0 | SPrivObjPolicies policy = {0}; |
354 | 0 | privAddType(&policy.policy, pPrivInfo->privType); |
355 | 0 | TAOS_CHECK_EXIT(taosHashPut(objPrivs, key, keyLen + 1, &policy, sizeof(SPrivObjPolicies))); |
356 | 0 | } else { |
357 | 0 | privAddType(&policies->policy, pPrivInfo->privType); |
358 | 0 | } |
359 | 0 | } |
360 | 0 | _exit: |
361 | 0 | return code; |
362 | 0 | } |
363 | | |
364 | | int32_t privCheckConflicts(const SPrivSet* privSet, EPrivCategory* pCategory, EPrivObjType* pObjType, |
365 | 0 | uint8_t* pObjLevel, EPrivType* conflict0, EPrivType* conflict1) { |
366 | 0 | (void)taosThreadOnce(&privInit, initPrivLookup); |
367 | |
|
368 | 0 | if (!privSet) return TSDB_CODE_APP_ERROR; |
369 | | |
370 | 0 | int32_t code = 0; |
371 | 0 | const SPrivInfo* privInfo = NULL; |
372 | |
|
373 | 0 | bool hasSystemPriv = false; |
374 | 0 | bool hasObjectPriv = false; |
375 | 0 | bool hasCommonPriv = false; |
376 | |
|
377 | 0 | EPrivType lastPriv = PRIV_TYPE_UNKNOWN; |
378 | |
|
379 | 0 | for (int32_t i = 0; i < PRIV_GROUP_CNT; ++i) { |
380 | 0 | uint64_t chunk = privSet->set[i]; |
381 | 0 | if (chunk == 0) continue; |
382 | | |
383 | 0 | while (chunk != 0) { |
384 | 0 | int32_t bitPos = BUILDIN_CTZL(chunk); |
385 | 0 | EPrivType privType = (i << 6) + bitPos; |
386 | 0 | chunk &= ~(1ULL << bitPos); |
387 | |
|
388 | 0 | privInfo = privLookup[privType]; |
389 | 0 | if (privInfo == NULL) continue; |
390 | | |
391 | 0 | switch (privInfo->category) { |
392 | 0 | case PRIV_CATEGORY_SYSTEM: { |
393 | 0 | if (hasObjectPriv || hasCommonPriv) { |
394 | 0 | code = 1; |
395 | 0 | goto _exit; |
396 | 0 | } |
397 | 0 | hasSystemPriv = true; |
398 | 0 | lastPriv = privInfo->privType; |
399 | 0 | break; |
400 | 0 | } |
401 | 0 | case PRIV_CATEGORY_OBJECT: { |
402 | 0 | if (hasSystemPriv) { |
403 | 0 | code = 1; |
404 | 0 | goto _exit; |
405 | 0 | } |
406 | 0 | if ((*pObjType != privInfo->objType) && (*pObjType != PRIV_OBJ_NONE)) { |
407 | 0 | code = 2; |
408 | 0 | goto _exit; |
409 | 0 | } |
410 | 0 | if (*pObjLevel != privInfo->objLevel) { |
411 | 0 | code = 3; |
412 | 0 | goto _exit; |
413 | 0 | } |
414 | 0 | hasObjectPriv = true; |
415 | 0 | lastPriv = privInfo->privType; |
416 | 0 | break; |
417 | 0 | } |
418 | 0 | case PRIV_CATEGORY_COMMON: { |
419 | 0 | if (hasSystemPriv) { |
420 | 0 | code = 1; |
421 | 0 | goto _exit; |
422 | 0 | } |
423 | 0 | hasCommonPriv = true; |
424 | 0 | lastPriv = privInfo->privType; |
425 | 0 | break; |
426 | 0 | } |
427 | 0 | default: |
428 | 0 | break; |
429 | 0 | } |
430 | 0 | } |
431 | 0 | } |
432 | | |
433 | 0 | _exit: |
434 | 0 | if (code != 0) { |
435 | 0 | if (conflict0) *conflict0 = lastPriv; |
436 | 0 | if (conflict1 && privInfo) *conflict1 = privInfo->privType; |
437 | 0 | return code; |
438 | 0 | } |
439 | | |
440 | 0 | if (pCategory) { |
441 | 0 | *pCategory = hasSystemPriv ? PRIV_CATEGORY_SYSTEM |
442 | 0 | : hasObjectPriv ? PRIV_CATEGORY_OBJECT |
443 | 0 | : hasCommonPriv ? PRIV_CATEGORY_COMMON |
444 | 0 | : PRIV_CATEGORY_UNKNOWN; |
445 | 0 | } |
446 | |
|
447 | 0 | return 0; |
448 | 0 | } |
449 | | |
450 | 0 | void privIterInit(SPrivIter* pIter, SPrivSet* privSet) { |
451 | 0 | (void)taosThreadOnce(&privInit, initPrivLookup); |
452 | 0 | pIter->privSet = privSet; |
453 | 0 | pIter->groupIndex = 0; |
454 | 0 | pIter->curPriv = privSet->set[0]; |
455 | 0 | } |
456 | | |
457 | 0 | bool privIterNext(SPrivIter* iter, SPrivInfo** ppPrivInfo) { |
458 | 0 | _loop: |
459 | 0 | while (iter->curPriv == 0) { |
460 | 0 | if (++iter->groupIndex >= PRIV_GROUP_CNT) { |
461 | 0 | return false; |
462 | 0 | } |
463 | 0 | iter->curPriv = iter->privSet->set[iter->groupIndex]; |
464 | 0 | } |
465 | 0 | int32_t bitPos = BUILDIN_CTZL(iter->curPriv); |
466 | 0 | EPrivType privType = (iter->groupIndex << 6) + bitPos; |
467 | 0 | iter->curPriv &= (iter->curPriv -1); |
468 | 0 | if (ppPrivInfo) { |
469 | 0 | *ppPrivInfo = privLookup[privType]; |
470 | 0 | if (!(*ppPrivInfo)) goto _loop; |
471 | 0 | } |
472 | 0 | return true; |
473 | 0 | } |
474 | | |
475 | 0 | void privInfoIterInit(SPrivInfoIter* pIter) { |
476 | 0 | (void)taosThreadOnce(&privInit, initPrivLookup); |
477 | 0 | pIter->privInfo = privInfoTable; |
478 | 0 | pIter->privInfoCnt = sizeof(privInfoTable) / sizeof(privInfoTable[0]); |
479 | 0 | pIter->index = 0; |
480 | 0 | } |
481 | | |
482 | 0 | bool privInfoIterNext(SPrivInfoIter* iter, SPrivInfo** ppPrivInfo) { |
483 | 0 | if (iter->index < iter->privInfoCnt) { |
484 | 0 | if (ppPrivInfo) { |
485 | 0 | *ppPrivInfo = &iter->privInfo[iter->index++]; |
486 | 0 | } else { |
487 | 0 | iter->index++; |
488 | 0 | } |
489 | 0 | return true; |
490 | 0 | } |
491 | | |
492 | 0 | return false; |
493 | 0 | } |
494 | | // objType.1.db.tb or objType.1.db |
495 | 0 | int32_t privObjKeyF(const SPrivInfo* pPrivInfo, const char* fname, const char* tb, char* buf, int32_t bufLen) { |
496 | 0 | return (pPrivInfo->objLevel == 0) |
497 | 0 | ? snprintf(buf, bufLen, "%d.%s", pPrivInfo->objType, fname ? fname : "") |
498 | 0 | : snprintf(buf, bufLen, "%d.%s.%s", pPrivInfo->objType, fname ? fname : "", tb ? tb : ""); |
499 | 0 | } |
500 | | |
501 | | int32_t privObjKey(const SPrivInfo* pPrivInfo, int32_t acctId, const char* name, const char* tb, char* buf, |
502 | 0 | int32_t bufLen) { |
503 | 0 | return (pPrivInfo->objLevel == 0) |
504 | 0 | ? snprintf(buf, bufLen, "%d.%d.%s", pPrivInfo->objType, acctId, name ? name : "") |
505 | 0 | : snprintf(buf, bufLen, "%d.%d.%s.%s", pPrivInfo->objType, acctId, name ? name : "", tb ? tb : ""); |
506 | 0 | } |
507 | | |
508 | | // objType.1.db or objType.1.db.tb |
509 | | int32_t privObjKeyParse(const char* str, EPrivObjType* pObjType, char* db, int32_t dbLen, char* tb, int32_t tbLen, |
510 | 0 | bool fullDb) { |
511 | 0 | char* p = strchr(str, '.'); |
512 | 0 | if (!p) { |
513 | 0 | return TSDB_CODE_INVALID_DATA_FMT; |
514 | 0 | } |
515 | 0 | *pObjType = taosStr2Int32(str, NULL, 10); |
516 | 0 | if (errno == ERANGE || *pObjType < PRIV_OBJ_CLUSTER || *pObjType >= PRIV_OBJ_MAX) { |
517 | 0 | return TSDB_CODE_INVALID_DATA_FMT; |
518 | 0 | } |
519 | 0 | char* pNext = strchr(p + 1, '.'); |
520 | 0 | if (!pNext) { |
521 | 0 | return TSDB_CODE_INVALID_DATA_FMT; |
522 | 0 | } |
523 | 0 | char* qNext = strchr(pNext + 1, '.'); |
524 | 0 | if (qNext) { |
525 | 0 | size_t dbLength = qNext - (fullDb ? (p + 1) : (pNext + 1)); |
526 | 0 | if (dbLength >= (size_t)dbLen) { |
527 | 0 | return TSDB_CODE_INVALID_DATA_FMT; |
528 | 0 | } |
529 | 0 | tstrncpy(db, fullDb ? (p + 1) : (pNext + 1), dbLength + 1); |
530 | 0 | tstrncpy(tb, qNext + 1, tbLen); |
531 | 0 | } else { |
532 | 0 | tstrncpy(db, fullDb ? (p + 1) : (pNext + 1), dbLen); |
533 | 0 | tb[0] = '\0'; |
534 | 0 | } |
535 | 0 | return TSDB_CODE_SUCCESS; |
536 | 0 | } |
537 | | |
538 | 0 | const char* privObjGetName(EPrivObjType objType) { |
539 | 0 | if (objType < PRIV_OBJ_CLUSTER || objType >= PRIV_OBJ_MAX) { |
540 | 0 | return "UNKNOWN"; |
541 | 0 | } |
542 | 0 | return __privObjInfo[objType].name; |
543 | 0 | } |
544 | | |
545 | 0 | int32_t privObjGetLevel(EPrivObjType objType) { |
546 | 0 | if (objType < PRIV_OBJ_CLUSTER || objType >= PRIV_OBJ_MAX) { |
547 | 0 | return -1; |
548 | 0 | } |
549 | 0 | return __privObjInfo[objType].level; |
550 | 0 | } |
551 | | |
552 | 0 | int32_t getSysRoleType(const char* roleName) { |
553 | 0 | if (strcmp(roleName, TSDB_ROLE_SYSDBA) == 0) { |
554 | 0 | return T_ROLE_SYSDBA; |
555 | 0 | } else if (strcmp(roleName, TSDB_ROLE_SYSSEC) == 0) { |
556 | 0 | return T_ROLE_SYSSEC; |
557 | 0 | } else if (strcmp(roleName, TSDB_ROLE_SYSAUDIT) == 0) { |
558 | 0 | return T_ROLE_SYSAUDIT; |
559 | 0 | } else if (strcmp(roleName, TSDB_ROLE_SYSAUDIT_LOG) == 0) { |
560 | 0 | return T_ROLE_SYSAUDIT_LOG; |
561 | 0 | } else if (strcmp(roleName, TSDB_ROLE_SYSINFO_0) == 0) { |
562 | 0 | return T_ROLE_SYSINFO_0; |
563 | 0 | } else if (strcmp(roleName, TSDB_ROLE_SYSINFO_1) == 0) { |
564 | 0 | return T_ROLE_SYSINFO_1; |
565 | 0 | } |
566 | 0 | return 0; |
567 | 0 | } |
568 | | |
569 | 0 | bool isPrivInheritName(const char* name) { |
570 | 0 | if (name && (name[0] == 'S' || name[0] == 's')) { |
571 | 0 | if (taosStrncasecmp(name, TSDB_ROLE_SYSDBA, 7) == 0 || taosStrncasecmp(name, TSDB_ROLE_SYSSEC, 7) == 0 || |
572 | 0 | taosStrncasecmp(name, TSDB_ROLE_SYSAUDIT, 9) == 0 || taosStrncasecmp(name, TSDB_ROLE_SYSAUDIT_LOG, 13) == 0 || |
573 | 0 | taosStrncasecmp(name, TSDB_ROLE_SYSINFO_0, 10) == 0 || taosStrncasecmp(name, TSDB_ROLE_SYSINFO_1, 10) == 0) { |
574 | 0 | return true; |
575 | 0 | } |
576 | 0 | } |
577 | 0 | return false; |
578 | 0 | } |
579 | | |
580 | 0 | int32_t privTblPolicyCopy(SPrivTblPolicy* dest, SPrivTblPolicy* src) { |
581 | 0 | dest->updateUs = src->updateUs; |
582 | 0 | dest->condLen = src->condLen; |
583 | 0 | if (src->cond) { |
584 | 0 | if (!(dest->cond = taosStrdup(src->cond))) { |
585 | 0 | return terrno; |
586 | 0 | } |
587 | 0 | } else { |
588 | 0 | dest->cond = NULL; |
589 | 0 | } |
590 | | |
591 | 0 | if (taosArrayGetSize(src->cols) > 0) { |
592 | 0 | dest->cols = taosArrayDup(src->cols, NULL); |
593 | 0 | if (!dest->cols) return terrno; |
594 | 0 | } else { |
595 | 0 | dest->cols = NULL; |
596 | 0 | } |
597 | 0 | return 0; |
598 | 0 | } |
599 | | |
600 | 0 | int32_t privTblPoliciesAdd(SPrivTblPolicies* dest, SPrivTblPolicies* src, bool deepCopy, bool setUpdateTimeMax) { |
601 | 0 | int32_t code = 0, lino = 0; |
602 | 0 | if (deepCopy) { |
603 | 0 | if (taosArrayGetSize(src->policy) == 0) { |
604 | 0 | dest->policy = NULL; |
605 | 0 | goto _exit; |
606 | 0 | } |
607 | 0 | if (!dest->policy) { |
608 | 0 | dest->policy = taosArrayInit(TARRAY_SIZE(src->policy), sizeof(SPrivTblPolicy)); |
609 | 0 | if (!dest->policy) { |
610 | 0 | TAOS_CHECK_EXIT(terrno); |
611 | 0 | } |
612 | 0 | } |
613 | 0 | for (int32_t j = 0; j < TARRAY_SIZE(src->policy); ++j) { |
614 | 0 | SPrivTblPolicy* pSrcPolicy = (SPrivTblPolicy*)TARRAY_GET_ELEM(src->policy, j); |
615 | 0 | SPrivTblPolicy destPolicy = {0}; |
616 | 0 | if ((code = privTblPolicyCopy(&destPolicy, pSrcPolicy))) { |
617 | 0 | privTblPolicyFree(&destPolicy); |
618 | 0 | TAOS_CHECK_EXIT(code); |
619 | 0 | } |
620 | 0 | if (setUpdateTimeMax) destPolicy.updateUs = INT64_MAX; |
621 | 0 | if (!taosArrayPush(dest->policy, &destPolicy)) { |
622 | 0 | privTblPolicyFree(&destPolicy); |
623 | 0 | TAOS_CHECK_EXIT(terrno); |
624 | 0 | } |
625 | 0 | } |
626 | 0 | } else { |
627 | 0 | dest->policy = src->policy; |
628 | 0 | } |
629 | 0 | _exit: |
630 | 0 | return code; |
631 | 0 | } |
632 | | |
633 | 0 | int32_t privTblPoliciesMerge(SPrivTblPolicies* dest, SPrivTblPolicies* src, bool updateWithLatest) { |
634 | 0 | int32_t code = 0, lino = 0; |
635 | 0 | if (taosArrayGetSize(src->policy) == 0) { |
636 | 0 | dest->policy = NULL; |
637 | 0 | goto _exit; |
638 | 0 | } |
639 | 0 | if (!dest->policy) { |
640 | 0 | dest->policy = taosArrayInit(TARRAY_SIZE(src->policy), sizeof(SPrivTblPolicy)); |
641 | 0 | if (!dest->policy) { |
642 | 0 | TAOS_CHECK_EXIT(terrno); |
643 | 0 | } |
644 | 0 | } |
645 | | // only 1 element exist in the table policy array currently |
646 | 0 | for (int32_t j = 0; j < TARRAY_SIZE(src->policy); ++j) { |
647 | 0 | SPrivTblPolicy* pSrcPolicy = (SPrivTblPolicy*)TARRAY_GET_ELEM(src->policy, j); |
648 | 0 | SPrivTblPolicy* pDestPolicy = taosArrayGet(dest->policy, 0); |
649 | |
|
650 | 0 | bool needAdd = false; |
651 | 0 | if (!pDestPolicy) { |
652 | 0 | needAdd = true; |
653 | 0 | } else if (updateWithLatest && (pSrcPolicy->updateUs > pDestPolicy->updateUs)) { |
654 | 0 | taosArrayClearEx(dest->policy, privTblPolicyFree); |
655 | 0 | needAdd = true; |
656 | 0 | } |
657 | 0 | if (!needAdd) { |
658 | 0 | break; |
659 | 0 | } |
660 | | |
661 | 0 | SPrivTblPolicy destPolicy = {0}; |
662 | 0 | if ((code = privTblPolicyCopy(&destPolicy, pSrcPolicy))) { |
663 | 0 | privTblPolicyFree(&destPolicy); |
664 | 0 | TAOS_CHECK_EXIT(code); |
665 | 0 | } |
666 | 0 | if (!taosArrayPush(dest->policy, &destPolicy)) { |
667 | 0 | privTblPolicyFree(&destPolicy); |
668 | 0 | TAOS_CHECK_EXIT(terrno); |
669 | 0 | } |
670 | 0 | } |
671 | 0 | _exit: |
672 | 0 | return code; |
673 | 0 | } |
674 | | |
675 | | bool privHasObjPrivilege(SHashObj* privs, int32_t acctId, const char* objName, const char* tbName, |
676 | 0 | const SPrivInfo* privInfo, bool recursive) { |
677 | 0 | if (tbName != NULL) { |
678 | 0 | if (privInfo->objLevel == 0 || privInfo->objType <= PRIV_OBJ_DB) { |
679 | 0 | uError("invalid privilege info for table level check, privType:%d, objType:%d, objLevel:%d\n", privInfo->privType, |
680 | 0 | privInfo->objType, privInfo->objLevel); |
681 | 0 | } |
682 | 0 | } |
683 | |
|
684 | 0 | if (taosHashGetSize(privs) == 0) return false; |
685 | | |
686 | 0 | const char* pObjName = objName; |
687 | 0 | const char* pTbName = tbName; |
688 | 0 | char key[TSDB_PRIV_MAX_KEY_LEN] = {0}; |
689 | 0 | int32_t klen = 0; |
690 | |
|
691 | 0 | _retry: |
692 | 0 | klen = privObjKey(privInfo, acctId, pObjName, pTbName, key, sizeof(key)); |
693 | |
|
694 | 0 | SPrivObjPolicies* policies = taosHashGet(privs, key, klen + 1); |
695 | 0 | if (policies && PRIV_HAS(&policies->policy, privInfo->privType)) { |
696 | 0 | return true; |
697 | 0 | } |
698 | | |
699 | 0 | if (!recursive) goto _exit; |
700 | | |
701 | 0 | if (pTbName && !(pTbName[0] == '*' && pTbName[1] == 0)) { |
702 | 0 | pTbName = "*"; |
703 | 0 | goto _retry; |
704 | 0 | } |
705 | 0 | if (pObjName && !(pObjName[0] == '*' && pObjName[1] == 0)) { |
706 | 0 | pObjName = "*"; |
707 | 0 | goto _retry; |
708 | 0 | } |
709 | 0 | _exit: |
710 | 0 | return false; |
711 | 0 | } |
712 | | |
713 | | SPrivTblPolicy* privGetConstraintTblPrivileges(SHashObj* privs, int32_t acctId, const char* objName, const char* tbName, |
714 | 0 | const SPrivInfo* privInfo) { |
715 | 0 | if (taosHashGetSize(privs) == 0) return NULL; |
716 | | |
717 | 0 | const char* pObjName = objName; |
718 | 0 | const char* pTbName = tbName; |
719 | 0 | char key[TSDB_PRIV_MAX_KEY_LEN] = {0}; |
720 | 0 | int32_t klen = 0; |
721 | |
|
722 | 0 | klen = privObjKey(privInfo, acctId, pObjName, pTbName, key, sizeof(key)); |
723 | |
|
724 | 0 | SPrivTblPolicies* policies = taosHashGet(privs, key, klen + 1); |
725 | 0 | if (policies) { |
726 | 0 | return (SPrivTblPolicy*)taosArrayGet(policies->policy, 0); |
727 | 0 | } |
728 | | |
729 | 0 | return NULL; |
730 | 0 | } |
731 | | |
732 | 0 | const SPrivInfo* privInfoGet(EPrivType privType) { |
733 | 0 | (void)taosThreadOnce(&privInit, initPrivLookup); |
734 | 0 | SPrivInfo* result = (privType >= 0 && privType <= MAX_PRIV_TYPE) ? privLookup[privType] : NULL; |
735 | 0 | if (!result) terrno = TSDB_CODE_APP_ERROR; |
736 | 0 | return result; |
737 | 0 | } |
738 | | |
739 | 0 | const char* privInfoGetName(EPrivType privType) { |
740 | 0 | const SPrivInfo* privInfo = privInfoGet(privType); |
741 | 0 | return privInfo ? privInfo->name : "privUnkown"; |
742 | 0 | } |
743 | | |
744 | 0 | void privAddSetByObjType(SPrivSet* fromSet, SPrivSet* toSet, uint8_t objType) { |
745 | 0 | SPrivIter privIter = {0}; |
746 | 0 | privIterInit(&privIter, fromSet); |
747 | 0 | SPrivInfo* pPrivInfo = NULL; |
748 | 0 | while (privIterNext(&privIter, &pPrivInfo)) { |
749 | 0 | if (pPrivInfo->objType == objType) { |
750 | 0 | privAddType(toSet, pPrivInfo->privType); |
751 | 0 | } |
752 | 0 | } |
753 | 0 | } |
754 | | |
755 | 0 | EPrivObjType privDeduceObjType(SPrivSet* privSet) { |
756 | 0 | uint32_t objTypeMask = 0; // extend to uint64_t if needed |
757 | |
|
758 | 0 | if (PRIV_OBJ_MAX >= 32) { |
759 | 0 | return PRIV_OBJ_NONE; |
760 | 0 | } |
761 | | |
762 | 0 | SPrivIter privIter = {0}; |
763 | 0 | privIterInit(&privIter, privSet); |
764 | 0 | SPrivInfo* pPrivInfo = NULL; |
765 | |
|
766 | 0 | while (privIterNext(&privIter, &pPrivInfo)) { |
767 | 0 | if (pPrivInfo->category == PRIV_CATEGORY_SYSTEM) { |
768 | 0 | return PRIV_OBJ_NONE; |
769 | 0 | } |
770 | 0 | if (pPrivInfo->category == PRIV_CATEGORY_OBJECT) { |
771 | 0 | switch (pPrivInfo->objType) { |
772 | 0 | case PRIV_OBJ_DB: |
773 | 0 | objTypeMask |= (1 << PRIV_OBJ_DB); |
774 | 0 | break; |
775 | 0 | case PRIV_OBJ_TBL: |
776 | 0 | objTypeMask |= (1 << PRIV_OBJ_TBL); |
777 | 0 | break; |
778 | 0 | case PRIV_OBJ_VIEW: |
779 | 0 | objTypeMask |= (1 << PRIV_OBJ_VIEW); |
780 | 0 | break; |
781 | 0 | case PRIV_OBJ_TOPIC: |
782 | 0 | objTypeMask |= (1 << PRIV_OBJ_TOPIC); |
783 | 0 | break; |
784 | 0 | case PRIV_OBJ_IDX: |
785 | 0 | objTypeMask |= (1 << PRIV_OBJ_IDX); |
786 | 0 | break; |
787 | 0 | case PRIV_OBJ_RSMA: |
788 | 0 | objTypeMask |= (1 << PRIV_OBJ_RSMA); |
789 | 0 | break; |
790 | 0 | case PRIV_OBJ_TSMA: |
791 | 0 | objTypeMask |= (1 << PRIV_OBJ_TSMA); |
792 | 0 | break; |
793 | 0 | case PRIV_OBJ_STREAM: |
794 | 0 | objTypeMask |= (1 << PRIV_OBJ_STREAM); |
795 | 0 | break; |
796 | 0 | case PRIV_OBJ_XTASK: |
797 | 0 | objTypeMask |= (1 << PRIV_OBJ_XTASK); |
798 | 0 | break; |
799 | 0 | default: |
800 | 0 | return PRIV_OBJ_NONE; |
801 | 0 | } |
802 | 0 | } else if (pPrivInfo->privType == PRIV_CM_SUBSCRIBE) { |
803 | 0 | objTypeMask |= (1 << PRIV_OBJ_TOPIC); |
804 | 0 | } |
805 | 0 | if (objTypeMask > 0) { |
806 | 0 | uint32_t mask = objTypeMask & (objTypeMask - 1); |
807 | 0 | if (mask > 0) return PRIV_OBJ_NONE; |
808 | 0 | } |
809 | 0 | } |
810 | 0 | if (objTypeMask == 0) return PRIV_OBJ_NONE; |
811 | | |
812 | 0 | int32_t bitPos = BUILDIN_CTZL(objTypeMask); |
813 | 0 | if (bitPos < 0 || bitPos >= PRIV_OBJ_MAX) { |
814 | 0 | return PRIV_OBJ_NONE; |
815 | 0 | } |
816 | 0 | return bitPos; |
817 | 0 | } |