• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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