1 /*
2 * Copyright (c) 2021-2022 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_db.h"
17
18 #include "accesstoken_log.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace AccessToken {
23 namespace {
24 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenDb"};
25 static const std::string INTEGER_STR = " integer not null,";
26 static const std::string TEXT_STR = " text not null,";
27 }
28
GetInstance()29 AccessTokenDb& AccessTokenDb::GetInstance()
30 {
31 static AccessTokenDb instance;
32 return instance;
33 }
34
~AccessTokenDb()35 AccessTokenDb::~AccessTokenDb()
36 {
37 Close();
38 }
39
OnCreate()40 void AccessTokenDb::OnCreate()
41 {
42 ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__);
43 CreateHapTokenInfoTable();
44 CreateNativeTokenInfoTable();
45 CreatePermissionDefinitionTable();
46 CreatePermissionStateTable();
47 }
48
OnUpdate()49 void AccessTokenDb::OnUpdate()
50 {
51 ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__);
52 AddAvailableTypeColumn();
53 AddPermDialogCapColumn();
54 }
55
AccessTokenDb()56 AccessTokenDb::AccessTokenDb() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION)
57 {
58 SqliteTable hapTokenInfoTable;
59 hapTokenInfoTable.tableName_ = HAP_TOKEN_INFO_TABLE;
60 hapTokenInfoTable.tableColumnNames_ = {
61 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_USER_ID,
62 TokenFiledConst::FIELD_BUNDLE_NAME, TokenFiledConst::FIELD_INST_INDEX, TokenFiledConst::FIELD_DLP_TYPE,
63 TokenFiledConst::FIELD_APP_ID, TokenFiledConst::FIELD_DEVICE_ID,
64 TokenFiledConst::FIELD_APL, TokenFiledConst::FIELD_TOKEN_VERSION,
65 TokenFiledConst::FIELD_TOKEN_ATTR, TokenFiledConst::FIELD_API_VERSION,
66 TokenFiledConst::FIELD_FORBID_PERM_DIALOG
67 };
68
69 SqliteTable nativeTokenInfoTable;
70 nativeTokenInfoTable.tableName_ = NATIVE_TOKEN_INFO_TABLE;
71 nativeTokenInfoTable.tableColumnNames_ = {
72 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PROCESS_NAME,
73 TokenFiledConst::FIELD_TOKEN_VERSION, TokenFiledConst::FIELD_TOKEN_ATTR,
74 TokenFiledConst::FIELD_DCAP, TokenFiledConst::FIELD_NATIVE_ACLS, TokenFiledConst::FIELD_APL
75 };
76
77 SqliteTable permissionDefTable;
78 permissionDefTable.tableName_ = PERMISSION_DEF_TABLE;
79 permissionDefTable.tableColumnNames_ = {
80 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PERMISSION_NAME,
81 TokenFiledConst::FIELD_BUNDLE_NAME, TokenFiledConst::FIELD_GRANT_MODE,
82 TokenFiledConst::FIELD_AVAILABLE_LEVEL, TokenFiledConst::FIELD_PROVISION_ENABLE,
83 TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE, TokenFiledConst::FIELD_LABEL,
84 TokenFiledConst::FIELD_LABEL_ID, TokenFiledConst::FIELD_DESCRIPTION,
85 TokenFiledConst::FIELD_DESCRIPTION_ID, TokenFiledConst::FIELD_AVAILABLE_TYPE
86 };
87
88 SqliteTable permissionStateTable;
89 permissionStateTable.tableName_ = PERMISSION_STATE_TABLE;
90 permissionStateTable.tableColumnNames_ = {
91 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PERMISSION_NAME,
92 TokenFiledConst::FIELD_DEVICE_ID, TokenFiledConst::FIELD_GRANT_IS_GENERAL,
93 TokenFiledConst::FIELD_GRANT_STATE, TokenFiledConst::FIELD_GRANT_FLAG
94 };
95
96 dataTypeToSqlTable_ = {
97 {ACCESSTOKEN_HAP_INFO, hapTokenInfoTable},
98 {ACCESSTOKEN_NATIVE_INFO, nativeTokenInfoTable},
99 {ACCESSTOKEN_PERMISSION_DEF, permissionDefTable},
100 {ACCESSTOKEN_PERMISSION_STATE, permissionStateTable},
101 };
102
103 Open();
104 }
105
Add(const DataType type,const std::vector<GenericValues> & values)106 int AccessTokenDb::Add(const DataType type, const std::vector<GenericValues>& values)
107 {
108 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
109 std::string prepareSql = CreateInsertPrepareSqlCmd(type);
110 auto statement = Prepare(prepareSql);
111 BeginTransaction();
112 bool isExecuteSuccessfully = true;
113 for (const auto& value : values) {
114 std::vector<std::string> columnNames = value.GetAllKeys();
115 for (const auto& columnName : columnNames) {
116 statement.Bind(columnName, value.Get(columnName));
117 }
118 int ret = statement.Step();
119 if (ret != Statement::State::DONE) {
120 ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", SpitError().c_str());
121 isExecuteSuccessfully = false;
122 }
123 statement.Reset();
124 }
125 if (!isExecuteSuccessfully) {
126 ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
127 RollbackTransaction();
128 return FAILURE;
129 }
130 ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction.");
131 CommitTransaction();
132 return SUCCESS;
133 }
134
Remove(const DataType type,const GenericValues & conditions)135 int AccessTokenDb::Remove(const DataType type, const GenericValues& conditions)
136 {
137 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
138 std::vector<std::string> columnNames = conditions.GetAllKeys();
139 std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames);
140 auto statement = Prepare(prepareSql);
141 for (const auto& columnName : columnNames) {
142 statement.Bind(columnName, conditions.Get(columnName));
143 }
144 int ret = statement.Step();
145 return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
146 }
147
Modify(const DataType type,const GenericValues & modifyValues,const GenericValues & conditions)148 int AccessTokenDb::Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions)
149 {
150 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
151 std::vector<std::string> modifyColumns = modifyValues.GetAllKeys();
152 std::vector<std::string> conditionColumns = conditions.GetAllKeys();
153 std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyColumns, conditionColumns);
154 auto statement = Prepare(prepareSql);
155 for (const auto& columnName : modifyColumns) {
156 statement.Bind(columnName, modifyValues.Get(columnName));
157 }
158 for (const auto& columnName : conditionColumns) {
159 statement.Bind(columnName, conditions.Get(columnName));
160 }
161 int ret = statement.Step();
162 return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
163 }
164
Find(const DataType type,std::vector<GenericValues> & results)165 int AccessTokenDb::Find(const DataType type, std::vector<GenericValues>& results)
166 {
167 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
168 std::string prepareSql = CreateSelectPrepareSqlCmd(type);
169 auto statement = Prepare(prepareSql);
170 while (statement.Step() == Statement::State::ROW) {
171 int columnCount = statement.GetColumnCount();
172 GenericValues value;
173 for (int i = 0; i < columnCount; i++) {
174 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
175 }
176 results.emplace_back(value);
177 }
178 return SUCCESS;
179 }
180
RefreshAll(const DataType type,const std::vector<GenericValues> & values)181 int AccessTokenDb::RefreshAll(const DataType type, const std::vector<GenericValues>& values)
182 {
183 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
184 std::string deleteSql = CreateDeletePrepareSqlCmd(type);
185 std::string insertSql = CreateInsertPrepareSqlCmd(type);
186 auto deleteStatement = Prepare(deleteSql);
187 auto insertStatement = Prepare(insertSql);
188 BeginTransaction();
189 bool canCommit = deleteStatement.Step() == Statement::State::DONE;
190 for (const auto& value : values) {
191 std::vector<std::string> columnNames = value.GetAllKeys();
192 for (const auto& columnName : columnNames) {
193 insertStatement.Bind(columnName, value.Get(columnName));
194 }
195 int ret = insertStatement.Step();
196 if (ret != Statement::State::DONE) {
197 ACCESSTOKEN_LOG_ERROR(
198 LABEL, "insert failed, errorMsg: %{public}s", SpitError().c_str());
199 canCommit = false;
200 }
201 insertStatement.Reset();
202 }
203 if (!canCommit) {
204 ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
205 RollbackTransaction();
206 return FAILURE;
207 }
208 ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction.");
209 CommitTransaction();
210 return SUCCESS;
211 }
212
CreateInsertPrepareSqlCmd(const DataType type) const213 std::string AccessTokenDb::CreateInsertPrepareSqlCmd(const DataType type) const
214 {
215 auto it = dataTypeToSqlTable_.find(type);
216 if (it == dataTypeToSqlTable_.end()) {
217 return std::string();
218 }
219 std::string sql = "insert into " + it->second.tableName_ + " values(";
220 int i = 1;
221 for (const auto& columnName : it->second.tableColumnNames_) {
222 sql.append(":" + columnName);
223 if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
224 sql.append(",");
225 }
226 i += 1;
227 }
228 sql.append(")");
229 return sql;
230 }
231
CreateDeletePrepareSqlCmd(const DataType type,const std::vector<std::string> & columnNames) const232 std::string AccessTokenDb::CreateDeletePrepareSqlCmd(
233 const DataType type, const std::vector<std::string>& columnNames) const
234 {
235 auto it = dataTypeToSqlTable_.find(type);
236 if (it == dataTypeToSqlTable_.end()) {
237 return std::string();
238 }
239 std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1";
240 for (const auto& columnName : columnNames) {
241 sql.append(" and ");
242 sql.append(columnName + "=:" + columnName);
243 }
244 return sql;
245 }
246
CreateUpdatePrepareSqlCmd(const DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const247 std::string AccessTokenDb::CreateUpdatePrepareSqlCmd(const DataType type, const std::vector<std::string>& modifyColumns,
248 const std::vector<std::string>& conditionColumns) const
249 {
250 if (modifyColumns.empty()) {
251 return std::string();
252 }
253
254 auto it = dataTypeToSqlTable_.find(type);
255 if (it == dataTypeToSqlTable_.end()) {
256 return std::string();
257 }
258
259 std::string sql = "update " + it->second.tableName_ + " set ";
260 int i = 1;
261 for (const auto& columnName : modifyColumns) {
262 sql.append(columnName + "=:" + columnName);
263 if (i < static_cast<int32_t>(modifyColumns.size())) {
264 sql.append(",");
265 }
266 i += 1;
267 }
268
269 if (!conditionColumns.empty()) {
270 sql.append(" where 1 = 1");
271 for (const auto& columnName : conditionColumns) {
272 sql.append(" and ");
273 sql.append(columnName + "=:" + columnName);
274 }
275 }
276 return sql;
277 }
278
CreateSelectPrepareSqlCmd(const DataType type) const279 std::string AccessTokenDb::CreateSelectPrepareSqlCmd(const DataType type) const
280 {
281 auto it = dataTypeToSqlTable_.find(type);
282 if (it == dataTypeToSqlTable_.end()) {
283 return std::string();
284 }
285 std::string sql = "select * from " + it->second.tableName_;
286 return sql;
287 }
288
CreateHapTokenInfoTable() const289 int AccessTokenDb::CreateHapTokenInfoTable() const
290 {
291 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_HAP_INFO);
292 if (it == dataTypeToSqlTable_.end()) {
293 return FAILURE;
294 }
295 std::string sql = "create table if not exists ";
296 sql.append(it->second.tableName_ + " (")
297 .append(TokenFiledConst::FIELD_TOKEN_ID)
298 .append(INTEGER_STR)
299 .append(TokenFiledConst::FIELD_USER_ID)
300 .append(INTEGER_STR)
301 .append(TokenFiledConst::FIELD_BUNDLE_NAME)
302 .append(TEXT_STR)
303 .append(TokenFiledConst::FIELD_INST_INDEX)
304 .append(INTEGER_STR)
305 .append(TokenFiledConst::FIELD_DLP_TYPE)
306 .append(INTEGER_STR)
307 .append(TokenFiledConst::FIELD_APP_ID)
308 .append(TEXT_STR)
309 .append(TokenFiledConst::FIELD_DEVICE_ID)
310 .append(TEXT_STR)
311 .append(TokenFiledConst::FIELD_APL)
312 .append(INTEGER_STR)
313 .append(TokenFiledConst::FIELD_TOKEN_VERSION)
314 .append(INTEGER_STR)
315 .append(TokenFiledConst::FIELD_TOKEN_ATTR)
316 .append(INTEGER_STR)
317 .append(TokenFiledConst::FIELD_API_VERSION)
318 .append(INTEGER_STR)
319 .append(TokenFiledConst::FIELD_FORBID_PERM_DIALOG)
320 .append(INTEGER_STR)
321 .append("primary key(")
322 .append(TokenFiledConst::FIELD_TOKEN_ID)
323 .append("))");
324 return ExecuteSql(sql);
325 }
326
CreateNativeTokenInfoTable() const327 int AccessTokenDb::CreateNativeTokenInfoTable() const
328 {
329 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_NATIVE_INFO);
330 if (it == dataTypeToSqlTable_.end()) {
331 return FAILURE;
332 }
333 std::string sql = "create table if not exists ";
334 sql.append(it->second.tableName_ + " (")
335 .append(TokenFiledConst::FIELD_TOKEN_ID)
336 .append(INTEGER_STR)
337 .append(TokenFiledConst::FIELD_PROCESS_NAME)
338 .append(TEXT_STR)
339 .append(TokenFiledConst::FIELD_TOKEN_VERSION)
340 .append(INTEGER_STR)
341 .append(TokenFiledConst::FIELD_TOKEN_ATTR)
342 .append(INTEGER_STR)
343 .append(TokenFiledConst::FIELD_DCAP)
344 .append(TEXT_STR)
345 .append(TokenFiledConst::FIELD_NATIVE_ACLS)
346 .append(TEXT_STR)
347 .append(TokenFiledConst::FIELD_APL)
348 .append(INTEGER_STR)
349 .append("primary key(")
350 .append(TokenFiledConst::FIELD_TOKEN_ID)
351 .append("))");
352 return ExecuteSql(sql);
353 }
354
CreatePermissionDefinitionTable() const355 int AccessTokenDb::CreatePermissionDefinitionTable() const
356 {
357 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_DEF);
358 if (it == dataTypeToSqlTable_.end()) {
359 return FAILURE;
360 }
361 std::string sql = "create table if not exists ";
362 sql.append(it->second.tableName_ + " (")
363 .append(TokenFiledConst::FIELD_TOKEN_ID)
364 .append(INTEGER_STR)
365 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
366 .append(TEXT_STR)
367 .append(TokenFiledConst::FIELD_BUNDLE_NAME)
368 .append(TEXT_STR)
369 .append(TokenFiledConst::FIELD_GRANT_MODE)
370 .append(INTEGER_STR)
371 .append(TokenFiledConst::FIELD_AVAILABLE_LEVEL)
372 .append(INTEGER_STR)
373 .append(TokenFiledConst::FIELD_PROVISION_ENABLE)
374 .append(INTEGER_STR)
375 .append(TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE)
376 .append(INTEGER_STR)
377 .append(TokenFiledConst::FIELD_LABEL)
378 .append(TEXT_STR)
379 .append(TokenFiledConst::FIELD_LABEL_ID)
380 .append(INTEGER_STR)
381 .append(TokenFiledConst::FIELD_DESCRIPTION)
382 .append(TEXT_STR)
383 .append(TokenFiledConst::FIELD_DESCRIPTION_ID)
384 .append(INTEGER_STR)
385 .append(TokenFiledConst::FIELD_AVAILABLE_TYPE)
386 .append(INTEGER_STR)
387 .append("primary key(")
388 .append(TokenFiledConst::FIELD_TOKEN_ID)
389 .append(",")
390 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
391 .append("))");
392 return ExecuteSql(sql);
393 }
394
AddAvailableTypeColumn() const395 int32_t AccessTokenDb::AddAvailableTypeColumn() const
396 {
397 ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
398 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_DEF);
399 if (it == dataTypeToSqlTable_.end()) {
400 return FAILURE;
401 }
402 std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
403 TokenFiledConst::FIELD_AVAILABLE_TYPE + "=" +
404 std::to_string(ATokenAvailableTypeEnum::NORMAL);
405 int32_t checkResult = ExecuteSql(checkSql);
406 ACCESSTOKEN_LOG_INFO(LABEL, "check result:%{public}d", checkResult);
407 if (checkResult != -1) {
408 return SUCCESS;
409 }
410
411 std::string sql = "alter table ";
412 sql.append(it->second.tableName_ + " add column ")
413 .append(TokenFiledConst::FIELD_AVAILABLE_TYPE)
414 .append(" integer default ")
415 .append(std::to_string(ATokenAvailableTypeEnum::NORMAL));
416 int32_t insertResult = ExecuteSql(sql);
417 ACCESSTOKEN_LOG_INFO(LABEL, "insert column result:%{public}d", insertResult);
418 return insertResult;
419 }
420
AddPermDialogCapColumn() const421 int32_t AccessTokenDb::AddPermDialogCapColumn() const
422 {
423 ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
424 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_HAP_INFO);
425 if (it == dataTypeToSqlTable_.end()) {
426 return FAILURE;
427 }
428 std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
429 TokenFiledConst::FIELD_FORBID_PERM_DIALOG + "=" + std::to_string(false);
430 int32_t checkResult = ExecuteSql(checkSql);
431 ACCESSTOKEN_LOG_INFO(LABEL, "check result:%{public}d", checkResult);
432 if (checkResult != -1) {
433 return SUCCESS;
434 }
435
436 std::string sql = "alter table ";
437 sql.append(it->second.tableName_ + " add column ")
438 .append(TokenFiledConst::FIELD_FORBID_PERM_DIALOG)
439 .append(" integer default ")
440 .append(std::to_string(false));
441 int32_t insertResult = ExecuteSql(sql);
442 ACCESSTOKEN_LOG_INFO(LABEL, "insert column result:%{public}d", insertResult);
443 return insertResult;
444 }
445
CreatePermissionStateTable() const446 int AccessTokenDb::CreatePermissionStateTable() const
447 {
448 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_STATE);
449 if (it == dataTypeToSqlTable_.end()) {
450 return FAILURE;
451 }
452 std::string sql = "create table if not exists ";
453 sql.append(it->second.tableName_ + " (")
454 .append(TokenFiledConst::FIELD_TOKEN_ID)
455 .append(INTEGER_STR)
456 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
457 .append(TEXT_STR)
458 .append(TokenFiledConst::FIELD_DEVICE_ID)
459 .append(TEXT_STR)
460 .append(TokenFiledConst::FIELD_GRANT_IS_GENERAL)
461 .append(INTEGER_STR)
462 .append(TokenFiledConst::FIELD_GRANT_STATE)
463 .append(INTEGER_STR)
464 .append(TokenFiledConst::FIELD_GRANT_FLAG)
465 .append(INTEGER_STR)
466 .append("primary key(")
467 .append(TokenFiledConst::FIELD_TOKEN_ID)
468 .append(",")
469 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
470 .append(",")
471 .append(TokenFiledConst::FIELD_DEVICE_ID)
472 .append("))");
473 return ExecuteSql(sql);
474 }
475 } // namespace AccessToken
476 } // namespace Security
477 } // namespace OHOS
478