1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "access_token_open_callback.h"
17
18 #include "access_token_error.h"
19 #include "access_token.h"
20 #include "accesstoken_common_log.h"
21 #include "token_field_const.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 namespace {
27 constexpr const char* INTEGER_STR = " integer not null,";
28 constexpr const char* TEXT_STR = " text not null,";
29 // back up name is xxx_slave fixed, can not be changed
30 constexpr const char* DATABASE_NAME_BACK = "access_token_slave.db";
31
32 constexpr const uint32_t FLAG_HANDLE_FROM_ONE_TO_TWO = 1;
33 constexpr const uint32_t FLAG_HANDLE_FROM_TWO_TO_THREE = 1 << 1;
34 constexpr const uint32_t FLAG_HANDLE_FROM_THREE_TO_FOUR = 1 << 2;
35 constexpr const uint32_t FLAG_HANDLE_FROM_FOUR_TO_FIVE = 1 << 3;
36 }
37
CreateHapTokenInfoTable(NativeRdb::RdbStore & rdbStore)38 int32_t AccessTokenOpenCallback::CreateHapTokenInfoTable(NativeRdb::RdbStore& rdbStore)
39 {
40 std::string tableName;
41 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_HAP_INFO, tableName);
42
43 std::string sql = "create table if not exists " + tableName;
44 sql.append(" (")
45 .append(TokenFiledConst::FIELD_TOKEN_ID)
46 .append(INTEGER_STR)
47 .append(TokenFiledConst::FIELD_USER_ID)
48 .append(INTEGER_STR)
49 .append(TokenFiledConst::FIELD_BUNDLE_NAME)
50 .append(TEXT_STR)
51 .append(TokenFiledConst::FIELD_INST_INDEX)
52 .append(INTEGER_STR)
53 .append(TokenFiledConst::FIELD_DLP_TYPE)
54 .append(INTEGER_STR)
55 .append(TokenFiledConst::FIELD_APP_ID)
56 .append(TEXT_STR)
57 .append(TokenFiledConst::FIELD_DEVICE_ID)
58 .append(TEXT_STR)
59 .append(TokenFiledConst::FIELD_APL)
60 .append(INTEGER_STR)
61 .append(TokenFiledConst::FIELD_TOKEN_VERSION)
62 .append(INTEGER_STR)
63 .append(TokenFiledConst::FIELD_TOKEN_ATTR)
64 .append(INTEGER_STR)
65 .append(TokenFiledConst::FIELD_API_VERSION)
66 .append(INTEGER_STR)
67 .append(TokenFiledConst::FIELD_FORBID_PERM_DIALOG)
68 .append(INTEGER_STR)
69 .append("primary key(")
70 .append(TokenFiledConst::FIELD_TOKEN_ID)
71 .append("))");
72
73 return rdbStore.ExecuteSql(sql);
74 }
75
CreateNativeTokenInfoTable(NativeRdb::RdbStore & rdbStore)76 int32_t AccessTokenOpenCallback::CreateNativeTokenInfoTable(NativeRdb::RdbStore& rdbStore)
77 {
78 std::string tableName;
79 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_NATIVE_INFO, tableName);
80
81 std::string sql = "create table if not exists " + tableName;
82 sql.append(" (")
83 .append(TokenFiledConst::FIELD_TOKEN_ID)
84 .append(INTEGER_STR)
85 .append(TokenFiledConst::FIELD_PROCESS_NAME)
86 .append(TEXT_STR)
87 .append(TokenFiledConst::FIELD_TOKEN_VERSION)
88 .append(INTEGER_STR)
89 .append(TokenFiledConst::FIELD_TOKEN_ATTR)
90 .append(INTEGER_STR)
91 .append(TokenFiledConst::FIELD_DCAP)
92 .append(TEXT_STR)
93 .append(TokenFiledConst::FIELD_NATIVE_ACLS)
94 .append(TEXT_STR)
95 .append(TokenFiledConst::FIELD_APL)
96 .append(INTEGER_STR)
97 .append("primary key(")
98 .append(TokenFiledConst::FIELD_TOKEN_ID)
99 .append("))");
100
101 return rdbStore.ExecuteSql(sql);
102 }
103
CreatePermissionDefinitionTable(NativeRdb::RdbStore & rdbStore)104 int32_t AccessTokenOpenCallback::CreatePermissionDefinitionTable(NativeRdb::RdbStore& rdbStore)
105 {
106 std::string tableName;
107 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_DEF, tableName);
108
109 std::string sql = "create table if not exists " + tableName;
110 sql.append(" (")
111 .append(TokenFiledConst::FIELD_TOKEN_ID)
112 .append(INTEGER_STR)
113 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
114 .append(TEXT_STR)
115 .append(TokenFiledConst::FIELD_BUNDLE_NAME)
116 .append(TEXT_STR)
117 .append(TokenFiledConst::FIELD_GRANT_MODE)
118 .append(INTEGER_STR)
119 .append(TokenFiledConst::FIELD_AVAILABLE_LEVEL)
120 .append(INTEGER_STR)
121 .append(TokenFiledConst::FIELD_PROVISION_ENABLE)
122 .append(INTEGER_STR)
123 .append(TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE)
124 .append(INTEGER_STR)
125 .append(TokenFiledConst::FIELD_LABEL)
126 .append(TEXT_STR)
127 .append(TokenFiledConst::FIELD_LABEL_ID)
128 .append(INTEGER_STR)
129 .append(TokenFiledConst::FIELD_DESCRIPTION)
130 .append(TEXT_STR)
131 .append(TokenFiledConst::FIELD_DESCRIPTION_ID)
132 .append(INTEGER_STR)
133 .append(TokenFiledConst::FIELD_AVAILABLE_TYPE)
134 .append(INTEGER_STR)
135 .append(TokenFiledConst::FIELD_KERNEL_EFFECT)
136 .append(" integer, ")
137 .append(TokenFiledConst::FIELD_HAS_VALUE)
138 .append(" integer, ")
139 .append("primary key(")
140 .append(TokenFiledConst::FIELD_TOKEN_ID)
141 .append(",")
142 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
143 .append("))");
144
145 return rdbStore.ExecuteSql(sql);
146 }
147
CreatePermissionStateTable(NativeRdb::RdbStore & rdbStore)148 int32_t AccessTokenOpenCallback::CreatePermissionStateTable(NativeRdb::RdbStore& rdbStore)
149 {
150 std::string tableName;
151 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_STATE, tableName);
152
153 std::string sql = "create table if not exists " + tableName;
154 sql.append(" (")
155 .append(TokenFiledConst::FIELD_TOKEN_ID)
156 .append(INTEGER_STR)
157 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
158 .append(TEXT_STR)
159 .append(TokenFiledConst::FIELD_DEVICE_ID)
160 .append(TEXT_STR)
161 .append(TokenFiledConst::FIELD_GRANT_IS_GENERAL + " integer,")
162 .append(TokenFiledConst::FIELD_GRANT_STATE)
163 .append(INTEGER_STR)
164 .append(TokenFiledConst::FIELD_GRANT_FLAG)
165 .append(INTEGER_STR)
166 .append("primary key(")
167 .append(TokenFiledConst::FIELD_TOKEN_ID)
168 .append(",")
169 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
170 .append(",")
171 .append(TokenFiledConst::FIELD_DEVICE_ID)
172 .append("))");
173
174 return rdbStore.ExecuteSql(sql);
175 }
176
CreatePermissionRequestToggleStatusTable(NativeRdb::RdbStore & rdbStore)177 int32_t AccessTokenOpenCallback::CreatePermissionRequestToggleStatusTable(NativeRdb::RdbStore& rdbStore)
178 {
179 std::string tableName;
180 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS, tableName);
181
182 std::string sql = "create table if not exists " + tableName;
183 sql.append(" (")
184 .append(TokenFiledConst::FIELD_USER_ID)
185 .append(INTEGER_STR)
186 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
187 .append(TEXT_STR)
188 .append(TokenFiledConst::FIELD_REQUEST_TOGGLE_STATUS)
189 .append(INTEGER_STR)
190 .append("primary key(")
191 .append(TokenFiledConst::FIELD_USER_ID)
192 .append(",")
193 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
194 .append("))");
195
196 return rdbStore.ExecuteSql(sql);
197 }
198
CreatePermissionExtendValueTable(NativeRdb::RdbStore & rdbStore)199 int32_t AccessTokenOpenCallback::CreatePermissionExtendValueTable(NativeRdb::RdbStore& rdbStore)
200 {
201 std::string tableName;
202 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_EXTEND_VALUE, tableName);
203
204 std::string sql = "create table if not exists " + tableName;
205 sql.append(" (")
206 .append(TokenFiledConst::FIELD_TOKEN_ID)
207 .append(INTEGER_STR)
208 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
209 .append(TEXT_STR)
210 .append(TokenFiledConst::FIELD_VALUE)
211 .append(TEXT_STR)
212 .append("primary key(")
213 .append(TokenFiledConst::FIELD_TOKEN_ID)
214 .append(",")
215 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
216 .append(",")
217 .append(TokenFiledConst::FIELD_VALUE)
218 .append("))");
219
220 return rdbStore.ExecuteSql(sql);
221 }
222
OnCreate(NativeRdb::RdbStore & rdbStore)223 int32_t AccessTokenOpenCallback::OnCreate(NativeRdb::RdbStore& rdbStore)
224 {
225 LOGI(ATM_DOMAIN, ATM_TAG, "DB OnCreate.");
226
227 int32_t res = CreateHapTokenInfoTable(rdbStore);
228 if (res != NativeRdb::E_OK) {
229 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table hap_token_info_table.");
230 return res;
231 }
232
233 res = CreateNativeTokenInfoTable(rdbStore);
234 if (res != NativeRdb::E_OK) {
235 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table native_token_info_table.");
236 return res;
237 }
238
239 res = CreatePermissionDefinitionTable(rdbStore);
240 if (res != NativeRdb::E_OK) {
241 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_definition_table.");
242 return res;
243 }
244
245 res = CreatePermissionStateTable(rdbStore);
246 if (res != NativeRdb::E_OK) {
247 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_state_table.");
248 return res;
249 }
250
251 res = CreatePermissionRequestToggleStatusTable(rdbStore);
252 if (res != NativeRdb::E_OK) {
253 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_request_toggle_status_table.");
254 return res;
255 }
256
257 res = CreatePermissionExtendValueTable(rdbStore);
258 if (res != NativeRdb::E_OK) {
259 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_extend_value_table.");
260 return res;
261 }
262
263 std::string dbBackPath = std::string(DATABASE_PATH) + std::string(DATABASE_NAME_BACK);
264 if (access(dbBackPath.c_str(), NativeRdb::E_OK) != 0) {
265 return 0;
266 }
267
268 // if OnCreate solution found back up db, restore from backup, may be origin db has lost
269 LOGW(ATM_DOMAIN, ATM_TAG, "Detech origin database disappear, restore from backup!");
270
271 res = rdbStore.Restore("");
272 if (res != NativeRdb::E_OK) {
273 LOGE(ATM_DOMAIN, ATM_TAG, "Db restore failed, res is %{public}d.", res);
274 }
275
276 LOGW(ATM_DOMAIN, ATM_TAG, "Database restore from backup success!");
277
278 return 0;
279 }
280
AddAvailableTypeColumn(NativeRdb::RdbStore & rdbStore)281 int32_t AccessTokenOpenCallback::AddAvailableTypeColumn(NativeRdb::RdbStore& rdbStore)
282 {
283 std::string tableName;
284 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_DEF, tableName);
285
286 // check if column available_type exsit
287 std::string checkSql = "SELECT 1 FROM " + tableName + " WHERE " +
288 TokenFiledConst::FIELD_AVAILABLE_TYPE + "=" + std::to_string(ATokenAvailableTypeEnum::NORMAL);
289
290 int32_t checkRes = rdbStore.ExecuteSql(checkSql);
291 LOGI(ATM_DOMAIN, ATM_TAG, "Check result is %{public}d.", checkRes);
292 if (checkRes == NativeRdb::E_OK) {
293 // success means there exsit column available_type in table
294 return NativeRdb::E_OK;
295 }
296
297 // alter table add column
298 std::string sql = "alter table " + tableName + " add column " +
299 TokenFiledConst::FIELD_AVAILABLE_TYPE + " integer default " + std::to_string(ATokenAvailableTypeEnum::NORMAL);
300
301 int32_t res = rdbStore.ExecuteSql(sql);
302 LOGI(ATM_DOMAIN, ATM_TAG, "Insert column result is %{public}d.", res);
303
304 return res;
305 }
306
AddRequestToggleStatusColumn(NativeRdb::RdbStore & rdbStore)307 int32_t AccessTokenOpenCallback::AddRequestToggleStatusColumn(NativeRdb::RdbStore& rdbStore)
308 {
309 std::string tableName;
310 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_REQUEST_TOGGLE_STATUS, tableName);
311
312 // check if column status exsit
313 std::string checkSql = "SELECT 1 FROM " + tableName + " WHERE " +
314 TokenFiledConst::FIELD_REQUEST_TOGGLE_STATUS + "=" + std::to_string(0);
315
316 int32_t checkRes = rdbStore.ExecuteSql(checkSql);
317 LOGI(ATM_DOMAIN, ATM_TAG, "Check result is %{public}d.", checkRes);
318 if (checkRes == NativeRdb::E_OK) {
319 // success means there exsit column status in table
320 return NativeRdb::E_OK;
321 }
322
323 // alter table add column
324 std::string sql = "alter table " + tableName + " add column " +
325 TokenFiledConst::FIELD_REQUEST_TOGGLE_STATUS + " integer default " + std::to_string(0); // 0: close
326
327 int32_t res = rdbStore.ExecuteSql(sql);
328 LOGI(ATM_DOMAIN, ATM_TAG, "Insert column result is %{public}d.", res);
329
330 return res;
331 }
332
AddPermDialogCapColumn(NativeRdb::RdbStore & rdbStore)333 int32_t AccessTokenOpenCallback::AddPermDialogCapColumn(NativeRdb::RdbStore& rdbStore)
334 {
335 std::string tableName;
336 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_HAP_INFO, tableName);
337
338 // check if column perm_dialog_cap_state exsit
339 std::string checkSql = "SELECT 1 FROM " + tableName + " WHERE " +
340 TokenFiledConst::FIELD_FORBID_PERM_DIALOG + "=" + std::to_string(0);
341
342 int32_t checkRes = rdbStore.ExecuteSql(checkSql);
343 LOGI(ATM_DOMAIN, ATM_TAG, "Check result is %{public}d.", checkRes);
344 if (checkRes == NativeRdb::E_OK) {
345 // success means there exsit column perm_dialog_cap_state in table
346 return NativeRdb::E_OK;
347 }
348
349 // alter table add column
350 std::string sql = "alter table " + tableName + " add column " +
351 TokenFiledConst::FIELD_FORBID_PERM_DIALOG + " integer default " + std::to_string(false);
352
353 int32_t res = rdbStore.ExecuteSql(sql);
354 LOGI(ATM_DOMAIN, ATM_TAG, "Insert column result is %{public}d.", res);
355
356 return res;
357 }
358
AddKernelEffectAndHasValueColumn(NativeRdb::RdbStore & rdbStore)359 int32_t AccessTokenOpenCallback::AddKernelEffectAndHasValueColumn(NativeRdb::RdbStore& rdbStore)
360 {
361 std::string tableName;
362 AccessTokenDbUtil::GetTableNameByType(AtmDataType::ACCESSTOKEN_PERMISSION_DEF, tableName);
363
364 // check if column kernel_effect exsit
365 std::string checkSql = "SELECT 1 FROM " + tableName + " WHERE " + TokenFiledConst::FIELD_KERNEL_EFFECT + "=" +
366 std::to_string(0);
367
368 int32_t checkRes = rdbStore.ExecuteSql(checkSql);
369 if (checkRes == NativeRdb::E_OK) {
370 return NativeRdb::E_OK; // success means there exsit column kernel_effect in table
371 }
372
373 // alter table add column kernel_effect
374 std::string executeSql = "alter table " + tableName + " add column " + TokenFiledConst::FIELD_KERNEL_EFFECT +
375 " integer default " + std::to_string(false);
376
377 int32_t executeRes = rdbStore.ExecuteSql(executeSql);
378 if (executeRes != NativeRdb::E_OK) {
379 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column kernel_effect to table %{public}s, errCode is %{public}d.",
380 tableName.c_str(), executeRes);
381 return executeRes;
382 }
383
384 LOGI(ATM_DOMAIN, ATM_TAG, "Success to add column kernel_effect to permission_definition_table.");
385
386 // check if column has_value exsit
387 checkSql = "SELECT 1 FROM " + tableName + " WHERE " + TokenFiledConst::FIELD_HAS_VALUE + "=" + std::to_string(0);
388
389 checkRes = rdbStore.ExecuteSql(checkSql);
390 if (checkRes == NativeRdb::E_OK) {
391 return NativeRdb::E_OK; // success means there exsit column has_value in table
392 }
393
394 // alter table add column has_value
395 executeSql = "alter table " + tableName + " add column " + TokenFiledConst::FIELD_HAS_VALUE +
396 " integer default " + std::to_string(0);
397
398 executeRes = rdbStore.ExecuteSql(executeSql);
399 if (executeRes != NativeRdb::E_OK) {
400 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column has_value to table %{public}s, errCode is %{public}d.",
401 tableName.c_str(), executeRes);
402 return executeRes;
403 }
404
405 LOGI(ATM_DOMAIN, ATM_TAG, "Success to add column has_value to permission_definition_table.");
406
407 return NativeRdb::E_OK;
408 }
409
HandleUpgradeWithFlag(NativeRdb::RdbStore & rdbStore,uint32_t flag)410 int32_t AccessTokenOpenCallback::HandleUpgradeWithFlag(NativeRdb::RdbStore& rdbStore, uint32_t flag)
411 {
412 int32_t res = NativeRdb::E_OK;
413
414 if ((flag & FLAG_HANDLE_FROM_ONE_TO_TWO) == FLAG_HANDLE_FROM_ONE_TO_TWO) {
415 res = AddAvailableTypeColumn(rdbStore);
416 if (res != NativeRdb::E_OK) {
417 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column available_type.");
418 return res;
419 }
420
421 res = AddPermDialogCapColumn(rdbStore);
422 if (res != NativeRdb::E_OK) {
423 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column perm_dialog_cap_state.");
424 return res;
425 }
426 }
427
428 if ((flag & FLAG_HANDLE_FROM_TWO_TO_THREE) == FLAG_HANDLE_FROM_TWO_TO_THREE) {
429 res = CreatePermissionRequestToggleStatusTable(rdbStore);
430 if (res != NativeRdb::E_OK) {
431 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_request_toggle_status_table.");
432 return res;
433 }
434 }
435
436 if ((flag & FLAG_HANDLE_FROM_THREE_TO_FOUR) == FLAG_HANDLE_FROM_THREE_TO_FOUR) {
437 res = AddRequestToggleStatusColumn(rdbStore);
438 if (res != NativeRdb::E_OK) {
439 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to add column status.");
440 return res;
441 }
442 }
443
444 if ((flag & FLAG_HANDLE_FROM_FOUR_TO_FIVE) == FLAG_HANDLE_FROM_FOUR_TO_FIVE) {
445 res = CreatePermissionExtendValueTable(rdbStore);
446 if (res != NativeRdb::E_OK) {
447 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create table permission_extend_bool_table.");
448 return res;
449 }
450
451 return AddKernelEffectAndHasValueColumn(rdbStore);
452 }
453
454 return res;
455 }
456
GetUpgradeFlag(int32_t currentVersion,int32_t targetVersion,uint32_t & flag)457 void AccessTokenOpenCallback::GetUpgradeFlag(int32_t currentVersion, int32_t targetVersion, uint32_t& flag)
458 {
459 if ((targetVersion >= DATABASE_VERSION_2) && (currentVersion < DATABASE_VERSION_2)) {
460 flag += FLAG_HANDLE_FROM_ONE_TO_TWO;
461 }
462
463 if ((targetVersion >= DATABASE_VERSION_3) && (currentVersion < DATABASE_VERSION_3)) {
464 flag += FLAG_HANDLE_FROM_TWO_TO_THREE;
465 }
466
467 if ((targetVersion >= DATABASE_VERSION_4) && (currentVersion < DATABASE_VERSION_4)) {
468 flag += FLAG_HANDLE_FROM_THREE_TO_FOUR;
469 }
470
471 if ((targetVersion >= DATABASE_VERSION_5) && (currentVersion < DATABASE_VERSION_5)) {
472 flag += FLAG_HANDLE_FROM_FOUR_TO_FIVE;
473 }
474 }
475
OnUpgrade(NativeRdb::RdbStore & rdbStore,int32_t currentVersion,int32_t targetVersion)476 int32_t AccessTokenOpenCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int32_t currentVersion, int32_t targetVersion)
477 {
478 LOGI(ATM_DOMAIN, ATM_TAG, "DB OnUpgrade from currentVersion %{public}d to targetVersion %{public}d.",
479 currentVersion, targetVersion);
480
481 uint32_t flag = 0;
482 GetUpgradeFlag(currentVersion, targetVersion, flag);
483
484 return HandleUpgradeWithFlag(rdbStore, flag);
485 }
486 } // namespace AccessToken
487 } // namespace Security
488 } // namespace OHOS
489