1 /*
2 * Copyright (c) 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 #define LOG_TAG "UdmfServiceImpl"
17
18 #include "udmf_service_impl.h"
19
20 #include "iservice_registry.h"
21 #include "ipc_skeleton.h"
22 #include "tokenid_kit.h"
23
24 #include "accesstoken_kit.h"
25 #include "checker_manager.h"
26 #include "dfx_types.h"
27 #include "distributed_kv_data_manager.h"
28 #include "file.h"
29 #include "lifecycle/lifecycle_manager.h"
30 #include "log_print.h"
31 #include "preprocess_utils.h"
32 #include "reporter.h"
33 #include "uri_permission_manager.h"
34 #include "uri.h"
35 #include "udmf_conversion.h"
36 #include "udmf_radar_reporter.h"
37 #include "utils/anonymous.h"
38 #include "bootstrap.h"
39 #include "metadata/store_meta_data.h"
40 #include "metadata/meta_data_manager.h"
41 #include "device_manager_adapter.h"
42 namespace OHOS {
43 namespace UDMF {
44 using namespace Security::AccessToken;
45 using FeatureSystem = DistributedData::FeatureSystem;
46 using UdmfBehaviourMsg = OHOS::DistributedDataDfx::UdmfBehaviourMsg;
47 using Reporter = OHOS::DistributedDataDfx::Reporter;
48 using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter;
49 using StoreMetaData = OHOS::DistributedData::StoreMetaData;
50 using namespace RadarReporter;
51 constexpr const char *DRAG_AUTHORIZED_PROCESSES[] = {"msdp_sa", "collaboration_service"};
52 constexpr const char *DATA_PREFIX = "udmf://";
53 constexpr const char *FILE_SCHEME = "file";
54 constexpr const char *PRIVILEGE_READ_AND_KEEP = "readAndKeep";
55 constexpr const char *MANAGE_UDMF_APP_SHARE_OPTION = "ohos.permission.MANAGE_UDMF_APP_SHARE_OPTION";
56 __attribute__((used)) UdmfServiceImpl::Factory UdmfServiceImpl::factory_;
Factory()57 UdmfServiceImpl::Factory::Factory()
58 {
59 ZLOGI("Register udmf creator!");
60 FeatureSystem::GetInstance().RegisterCreator("udmf", [this]() {
61 if (product_ == nullptr) {
62 product_ = std::make_shared<UdmfServiceImpl>();
63 }
64 return product_;
65 }, FeatureSystem::BIND_NOW);
66 }
67
~Factory()68 UdmfServiceImpl::Factory::~Factory()
69 {
70 product_ = nullptr;
71 }
72
UdmfServiceImpl()73 UdmfServiceImpl::UdmfServiceImpl()
74 {
75 CheckerManager::GetInstance().LoadCheckers();
76 }
77
SetData(CustomOption & option,UnifiedData & unifiedData,std::string & key)78 int32_t UdmfServiceImpl::SetData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
79 {
80 ZLOGD("start");
81 int32_t res = E_OK;
82 UdmfBehaviourMsg msg;
83 auto find = UD_INTENTION_MAP.find(option.intention);
84 msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
85 msg.operation = "insert";
86 std::string bundleName;
87 if (!PreProcessUtils::GetHapBundleNameByToken(option.tokenId, bundleName)) {
88 msg.appId = "unknown";
89 res = E_ERROR;
90 } else {
91 msg.appId = bundleName;
92 res = SaveData(option, unifiedData, key);
93 }
94 auto errFind = ERROR_MAP.find(res);
95 msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
96 msg.dataType = unifiedData.GetTypes();
97 msg.dataSize = unifiedData.GetSize();
98 Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg);
99 return res;
100 }
101
SaveData(CustomOption & option,UnifiedData & unifiedData,std::string & key)102 int32_t UdmfServiceImpl::SaveData(CustomOption &option, UnifiedData &unifiedData, std::string &key)
103 {
104 if (!unifiedData.IsValid()) {
105 ZLOGE("UnifiedData is invalid.");
106 return E_INVALID_PARAMETERS;
107 }
108
109 if (!UnifiedDataUtils::IsValidIntention(option.intention)) {
110 ZLOGE("Invalid parameters intention: %{public}d.", option.intention);
111 return E_INVALID_PARAMETERS;
112 }
113
114 // imput runtime info before put it into store and save one privilege
115 if (PreProcessUtils::RuntimeDataImputation(unifiedData, option) != E_OK) {
116 ZLOGE("Imputation failed");
117 return E_ERROR;
118 }
119
120 std::string intention = unifiedData.GetRuntime()->key.intention;
121 if (intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
122 int32_t ret = PreProcessUtils::SetRemoteUri(option.tokenId, unifiedData);
123 if (ret != E_OK) {
124 ZLOGE("SetRemoteUri failed, ret: %{public}d, bundleName:%{public}s.", ret,
125 unifiedData.GetRuntime()->createPackage.c_str());
126 return ret;
127 }
128 }
129
130 for (const auto &record : unifiedData.GetRecords()) {
131 record->SetUid(PreProcessUtils::GenerateId());
132 }
133
134 auto store = StoreCache::GetInstance().GetStore(intention);
135 if (store == nullptr) {
136 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
137 return E_DB_ERROR;
138 }
139
140 if (!UnifiedDataUtils::IsPersist(intention) && store->Clear() != E_OK) {
141 ZLOGE("Clear store failed, intention: %{public}s.", intention.c_str());
142 return E_DB_ERROR;
143 }
144
145 UdmfConversion::InitValueObject(unifiedData);
146 if (store->Put(unifiedData) != E_OK) {
147 ZLOGE("Put unified data failed, intention: %{public}s.", intention.c_str());
148 return E_DB_ERROR;
149 }
150 key = unifiedData.GetRuntime()->key.GetUnifiedKey();
151 ZLOGD("Put unified data successful, key: %{public}s.", key.c_str());
152 return E_OK;
153 }
154
GetData(const QueryOption & query,UnifiedData & unifiedData)155 int32_t UdmfServiceImpl::GetData(const QueryOption &query, UnifiedData &unifiedData)
156 {
157 ZLOGD("start");
158 int32_t res = E_OK;
159 UdmfBehaviourMsg msg;
160 auto find = UD_INTENTION_MAP.find(query.intention);
161 msg.channel = find == UD_INTENTION_MAP.end() ? "invalid" : find->second;
162 msg.operation = "insert";
163 std::string bundleName;
164 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
165 msg.appId = "unknown";
166 res = E_ERROR;
167 } else {
168 msg.appId = bundleName;
169 res = RetrieveData(query, unifiedData);
170 }
171 auto errFind = ERROR_MAP.find(res);
172 msg.result = errFind == ERROR_MAP.end() ? "E_ERROR" : errFind->second;
173 msg.dataType = unifiedData.GetTypes();
174 msg.dataSize = unifiedData.GetSize();
175 Reporter::GetInstance()->BehaviourReporter()->UDMFReport(msg);
176 return res;
177 }
178
RetrieveData(const QueryOption & query,UnifiedData & unifiedData)179 int32_t UdmfServiceImpl::RetrieveData(const QueryOption &query, UnifiedData &unifiedData)
180 {
181 UnifiedKey key(query.key);
182 if (!key.IsValid()) {
183 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
184 return E_INVALID_PARAMETERS;
185 }
186 auto store = StoreCache::GetInstance().GetStore(key.intention);
187 if (store == nullptr) {
188 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
189 return E_DB_ERROR;
190 }
191 int32_t res = store->Get(query.key, unifiedData);
192 if (res != E_OK) {
193 ZLOGE("Get data from store failed, res: %{public}d, key: %{public}s.", res, query.key.c_str());
194 return res;
195 }
196
197 if (!unifiedData.IsComplete()) {
198 ZLOGE("Get data from DB is incomplete, key: %{public}s.", query.key.c_str());
199 return E_NOT_FOUND;
200 }
201
202 CheckerManager::CheckInfo info;
203 info.tokenId = query.tokenId;
204 std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
205 if (runtime == nullptr) {
206 return E_DB_ERROR;
207 }
208 if (!CheckerManager::GetInstance().IsValid(runtime->privileges, info) && !IsPermissionInCache(query)) {
209 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
210 BizScene::GET_DATA, GetDataStage::VERIFY_PRIVILEGE, StageRes::FAILED, E_NO_PERMISSION);
211 return E_NO_PERMISSION;
212 }
213
214 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
215 int32_t ret = ProcessUri(query, unifiedData);
216 if (ret != E_OK) {
217 ZLOGE("ProcessUri failed. ret=%{public}d", ret);
218 return E_NO_PERMISSION;
219 }
220 }
221 if (!IsReadAndKeep(runtime->privileges, query)) {
222 if (LifeCycleManager::GetInstance().OnGot(key) != E_OK) {
223 ZLOGE("Remove data failed, intention: %{public}s.", key.intention.c_str());
224 return E_DB_ERROR;
225 }
226 }
227
228 privilegeCache_.erase(query.key);
229
230 PreProcessUtils::SetRemoteData(unifiedData);
231 return E_OK;
232 }
233
IsPermissionInCache(const QueryOption & query)234 bool UdmfServiceImpl::IsPermissionInCache(const QueryOption &query)
235 {
236 auto iter = privilegeCache_.find(query.key);
237 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId) {
238 return true;
239 }
240 return false;
241 }
242
IsReadAndKeep(const std::vector<Privilege> & privileges,const QueryOption & query)243 bool UdmfServiceImpl::IsReadAndKeep(const std::vector<Privilege> &privileges, const QueryOption &query)
244 {
245 for (const auto &privilege : privileges) {
246 if (privilege.tokenId == query.tokenId && privilege.readPermission == PRIVILEGE_READ_AND_KEEP) {
247 return true;
248 }
249 }
250
251 auto iter = privilegeCache_.find(query.key);
252 if (iter != privilegeCache_.end() && iter->second.tokenId == query.tokenId &&
253 iter->second.readPermission == PRIVILEGE_READ_AND_KEEP) {
254 return true;
255 }
256 return false;
257 }
258
ProcessUri(const QueryOption & query,UnifiedData & unifiedData)259 int32_t UdmfServiceImpl::ProcessUri(const QueryOption &query, UnifiedData &unifiedData)
260 {
261 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
262 auto records = unifiedData.GetRecords();
263 if (unifiedData.GetRuntime() == nullptr) {
264 return E_DB_ERROR;
265 }
266 std::string sourceDeviceId = unifiedData.GetRuntime()->deviceId;
267 if (localDeviceId != sourceDeviceId) {
268 SetRemoteUri(query, records);
269 }
270 std::string bundleName;
271 if (!PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName)) {
272 ZLOGE("GetHapBundleNameByToken fail, key=%{public}s, tokenId=%{private}d.", query.key.c_str(), query.tokenId);
273 return E_ERROR;
274 }
275 if (localDeviceId == sourceDeviceId && query.tokenId == unifiedData.GetRuntime()->tokenId) {
276 ZLOGW("No need to grant uri permissions, queryKey=%{public}s.", query.key.c_str());
277 return E_OK;
278 }
279 std::vector<Uri> allUri;
280 for (auto record : records) {
281 if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
282 auto file = static_cast<File *>(record.get());
283 if (file->GetUri().empty()) {
284 ZLOGW("Get uri is empty, key=%{public}s.", query.key.c_str());
285 continue;
286 }
287 Uri uri(file->GetUri());
288 std::string scheme = uri.GetScheme();
289 std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
290 if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
291 ZLOGW("Get authority is empty or uri scheme not equals to file, key=%{public}s.", query.key.c_str());
292 continue;
293 }
294 allUri.push_back(uri);
295 }
296 }
297 if (UriPermissionManager::GetInstance().GrantUriPermission(allUri, query.tokenId, query.key) != E_OK) {
298 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
299 BizScene::GET_DATA, GetDataStage::GRANT_URI_PERMISSION, StageRes::FAILED, E_NO_PERMISSION);
300 ZLOGE("GrantUriPermission fail, bundleName=%{public}s, key=%{public}s.",
301 bundleName.c_str(), query.key.c_str());
302 return E_NO_PERMISSION;
303 }
304 return E_OK;
305 }
306
SetRemoteUri(const QueryOption & query,std::vector<std::shared_ptr<UnifiedRecord>> & records)307 void UdmfServiceImpl::SetRemoteUri(const QueryOption &query, std::vector<std::shared_ptr<UnifiedRecord>> &records)
308 {
309 for (auto record : records) {
310 if (record != nullptr && PreProcessUtils::IsFileType(record->GetType())) {
311 auto file = static_cast<File *>(record.get());
312 std::string remoteUri = file->GetRemoteUri();
313 if (remoteUri.empty()) {
314 ZLOGW("Get remoteUri is empyt, key=%{public}s.", query.key.c_str());
315 continue;
316 }
317 file->SetUri(remoteUri); // cross dev, need dis path.
318 }
319 }
320 }
321
GetBatchData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)322 int32_t UdmfServiceImpl::GetBatchData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
323 {
324 ZLOGD("start");
325 std::vector<UnifiedData> dataSet;
326 std::shared_ptr<Store> store;
327 auto status = QueryDataCommon(query, dataSet, store);
328 if (status != E_OK) {
329 ZLOGE("QueryDataCommon failed.");
330 return status;
331 }
332 if (dataSet.empty()) {
333 ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
334 return E_OK;
335 }
336 for (auto &data : dataSet) {
337 PreProcessUtils::SetRemoteData(data);
338 unifiedDataSet.push_back(data);
339 }
340 return E_OK;
341 }
342
UpdateData(const QueryOption & query,UnifiedData & unifiedData)343 int32_t UdmfServiceImpl::UpdateData(const QueryOption &query, UnifiedData &unifiedData)
344 {
345 UnifiedKey key(query.key);
346 if (!unifiedData.IsValid() || !key.IsValid()) {
347 ZLOGE("data is invalid, or key is invalid. key=%{public}s.", query.key.c_str());
348 return E_INVALID_PARAMETERS;
349 }
350 std::string bundleName;
351 PreProcessUtils::GetHapBundleNameByToken(query.tokenId, bundleName);
352 if (key.bundleName != bundleName) {
353 ZLOGE("update data failed by %{public}s, key: %{public}s.", bundleName.c_str(), query.key.c_str());
354 return E_INVALID_PARAMETERS;
355 }
356 auto store = StoreCache::GetInstance().GetStore(key.intention);
357 if (store == nullptr) {
358 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
359 return E_DB_ERROR;
360 }
361 UnifiedData data;
362 int32_t res = store->Get(query.key, data);
363 if (res != E_OK) {
364 ZLOGE("Get data from store failed, intention: %{public}s.", key.intention.c_str());
365 return res;
366 }
367 if (data.IsEmpty()) {
368 ZLOGE("Invalid parameter, unified data has no record; intention: %{public}s.", key.intention.c_str());
369 return E_INVALID_PARAMETERS;
370 }
371 std::shared_ptr<Runtime> runtime = data.GetRuntime();
372 if (runtime == nullptr) {
373 return E_DB_ERROR;
374 }
375 if (runtime->tokenId != query.tokenId) {
376 ZLOGE("update data failed, query option tokenId not equals data's tokenId");
377 return E_INVALID_PARAMETERS;
378 }
379 runtime->lastModifiedTime = PreProcessUtils::GetTimestamp();
380 unifiedData.SetRuntime(*runtime);
381 for (auto &record : unifiedData.GetRecords()) {
382 record->SetUid(PreProcessUtils::GenerateId());
383 }
384 UdmfConversion::InitValueObject(unifiedData);
385 if (store->Update(unifiedData) != E_OK) {
386 ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
387 return E_DB_ERROR;
388 }
389 return E_OK;
390 }
391
DeleteData(const QueryOption & query,std::vector<UnifiedData> & unifiedDataSet)392 int32_t UdmfServiceImpl::DeleteData(const QueryOption &query, std::vector<UnifiedData> &unifiedDataSet)
393 {
394 ZLOGD("start");
395 std::vector<UnifiedData> dataSet;
396 std::shared_ptr<Store> store;
397 auto status = QueryDataCommon(query, dataSet, store);
398 if (status != E_OK) {
399 ZLOGE("QueryDataCommon failed.");
400 return status;
401 }
402 if (dataSet.empty()) {
403 ZLOGW("DataSet has no data, key: %{public}s, intention: %{public}d.", query.key.c_str(), query.intention);
404 return E_OK;
405 }
406 std::shared_ptr<Runtime> runtime;
407 std::vector<std::string> deleteKeys;
408 for (const auto &data : dataSet) {
409 runtime = data.GetRuntime();
410 if (runtime == nullptr) {
411 return E_DB_ERROR;
412 }
413 if (runtime->tokenId == query.tokenId) {
414 unifiedDataSet.push_back(data);
415 deleteKeys.push_back(runtime->key.key);
416 }
417 }
418 if (deleteKeys.empty()) {
419 ZLOGE("Delete nothing. There is no data belonging to this application");
420 return E_OK;
421 }
422 ZLOGI("Delete data start. size: %{public}zu.", deleteKeys.size());
423 if (store->DeleteBatch(deleteKeys) != E_OK) {
424 ZLOGE("Remove data failed.");
425 return E_DB_ERROR;
426 }
427 return E_OK;
428 }
429
GetSummary(const QueryOption & query,Summary & summary)430 int32_t UdmfServiceImpl::GetSummary(const QueryOption &query, Summary &summary)
431 {
432 ZLOGD("start");
433 UnifiedKey key(query.key);
434 if (!key.IsValid()) {
435 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
436 return E_INVALID_PARAMETERS;
437 }
438
439 auto store = StoreCache::GetInstance().GetStore(key.intention);
440 if (store == nullptr) {
441 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
442 return E_DB_ERROR;
443 }
444
445 if (store->GetSummary(query.key, summary) != E_OK) {
446 ZLOGE("Store get summary failed, intention: %{public}s.", key.intention.c_str());
447 return E_DB_ERROR;
448 }
449 return E_OK;
450 }
451
AddPrivilege(const QueryOption & query,Privilege & privilege)452 int32_t UdmfServiceImpl::AddPrivilege(const QueryOption &query, Privilege &privilege)
453 {
454 ZLOGD("start");
455 UnifiedKey key(query.key);
456 if (!key.IsValid()) {
457 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
458 return E_INVALID_PARAMETERS;
459 }
460
461 std::string processName;
462 if (!PreProcessUtils::GetNativeProcessNameByToken(query.tokenId, processName)) {
463 return E_ERROR;
464 }
465
466 if (key.intention == UD_INTENTION_MAP.at(UD_INTENTION_DRAG)) {
467 if (find(DRAG_AUTHORIZED_PROCESSES, std::end(DRAG_AUTHORIZED_PROCESSES), processName) ==
468 std::end(DRAG_AUTHORIZED_PROCESSES)) {
469 ZLOGE("Process: %{public}s has no permission to intention: drag", processName.c_str());
470 return E_NO_PERMISSION;
471 }
472 } else {
473 ZLOGE("Intention: %{public}s has no authorized processes", key.intention.c_str());
474 return E_NO_PERMISSION;
475 }
476
477 auto store = StoreCache::GetInstance().GetStore(key.intention);
478 if (store == nullptr) {
479 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
480 return E_DB_ERROR;
481 }
482
483 UnifiedData data;
484 int32_t res = store->Get(query.key, data);
485 if (res == E_NOT_FOUND) {
486 privilegeCache_[query.key] = privilege;
487 ZLOGW("Add privilege in cache, key: %{public}s.", query.key.c_str());
488 return E_OK;
489 }
490 if (res != E_OK) {
491 ZLOGE("Get data from store failed, res:%{public}d,intention: %{public}s.", res, key.intention.c_str());
492 return res;
493 }
494 if (data.GetRuntime() == nullptr) {
495 return E_DB_ERROR;
496 }
497 data.GetRuntime()->privileges.emplace_back(privilege);
498 UdmfConversion::InitValueObject(data);
499 if (store->Update(data) != E_OK) {
500 ZLOGE("Update unified data failed, intention: %{public}s.", key.intention.c_str());
501 return E_DB_ERROR;
502 }
503 return E_OK;
504 }
505
Sync(const QueryOption & query,const std::vector<std::string> & devices)506 int32_t UdmfServiceImpl::Sync(const QueryOption &query, const std::vector<std::string> &devices)
507 {
508 ZLOGD("start");
509 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
510 BizScene::SYNC_DATA, SyncDataStage::SYNC_BEGIN, StageRes::IDLE, BizState::DFX_BEGIN);
511 UnifiedKey key(query.key);
512 if (!key.IsValid()) {
513 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
514 return E_INVALID_PARAMETERS;
515 }
516
517 auto store = StoreCache::GetInstance().GetStore(key.intention);
518 if (store == nullptr) {
519 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
520 return E_DB_ERROR;
521 }
522
523 if (store->Sync(devices) != E_OK) {
524 ZLOGE("Store sync failed, intention: %{public}s.", key.intention.c_str());
525 RadarReporterAdapter::ReportFail(std::string(__FUNCTION__),
526 BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::FAILED, E_DB_ERROR, BizState::DFX_ABNORMAL_END);
527 return E_DB_ERROR;
528 }
529 RadarReporterAdapter::ReportNormal(std::string(__FUNCTION__),
530 BizScene::SYNC_DATA, SyncDataStage::SYNC_END, StageRes::SUCCESS, BizState::DFX_NORMAL_END);
531 return E_OK;
532 }
533
IsRemoteData(const QueryOption & query,bool & result)534 int32_t UdmfServiceImpl::IsRemoteData(const QueryOption &query, bool &result)
535 {
536 UnifiedKey key(query.key);
537 if (!key.IsValid()) {
538 ZLOGE("Unified key: %{public}s is invalid.", query.key.c_str());
539 return E_INVALID_PARAMETERS;
540 }
541
542 auto store = StoreCache::GetInstance().GetStore(key.intention);
543 if (store == nullptr) {
544 ZLOGE("Get store failed, intention: %{public}s.", key.intention.c_str());
545 return E_DB_ERROR;
546 }
547
548 UnifiedData unifiedData;
549 if (store->Get(query.key, unifiedData) != E_OK) {
550 ZLOGE("Store get unifiedData failed, intention: %{public}s.", key.intention.c_str());
551 return E_DB_ERROR;
552 }
553 std::shared_ptr<Runtime> runtime = unifiedData.GetRuntime();
554 if (runtime == nullptr) {
555 ZLOGE("Store get runtime failed, key: %{public}s.", query.key.c_str());
556 return E_DB_ERROR;
557 }
558
559 std::string localDeviceId = PreProcessUtils::GetLocalDeviceId();
560 if (localDeviceId != runtime->deviceId) {
561 result = true;
562 }
563 return E_OK;
564 }
565
SetAppShareOption(const std::string & intention,int32_t shareOption)566 int32_t UdmfServiceImpl::SetAppShareOption(const std::string &intention, int32_t shareOption)
567 {
568 if (intention.empty() || shareOption >= SHARE_OPTIONS_BUTT || shareOption < IN_APP) {
569 ZLOGE("SetAppShareOption : para is invalid, intention: %{public}s, shareOption:%{public}d.",
570 intention.c_str(), shareOption);
571 return E_INVALID_PARAMETERS;
572 }
573
574 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
575 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
576 bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID());
577 if (!isSystemApp && !hasSharePermission) {
578 ZLOGE("No system permission and no shareOption permission, intention: %{public}s.", intention.c_str());
579 return E_NO_PERMISSION;
580 }
581 auto store = StoreCache::GetInstance().GetStore(intention);
582 if (store == nullptr) {
583 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
584 return E_DB_ERROR;
585 }
586
587 std::string shareOptionTmp;
588 if (store->GetLocal(std::to_string(accessTokenIDEx), shareOptionTmp) == E_OK) {
589 ZLOGE("SetAppShareOption failed, shareOption has already been set, %{public}s.", shareOptionTmp.c_str());
590 return E_SETTINGS_EXISTED;
591 }
592
593 if (store->PutLocal(std::to_string(accessTokenIDEx), ShareOptionsUtil::GetEnumStr(shareOption)) != E_OK) {
594 ZLOGE("Store get unifiedData failed, intention: %{public}d.", shareOption);
595 return E_DB_ERROR;
596 }
597 return E_OK;
598 }
599
GetAppShareOption(const std::string & intention,int32_t & shareOption)600 int32_t UdmfServiceImpl::GetAppShareOption(const std::string &intention, int32_t &shareOption)
601 {
602 if (intention.empty()) {
603 ZLOGE("GetAppShareOption : para is invalid, %{public}s is invalid.", intention.c_str());
604 return E_INVALID_PARAMETERS;
605 }
606 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
607 auto store = StoreCache::GetInstance().GetStore(intention);
608 if (store == nullptr) {
609 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
610 return E_DB_ERROR;
611 }
612 std::string appShareOption;
613 int32_t ret = store->GetLocal(std::to_string(accessTokenIDEx), appShareOption);
614 if (ret != E_OK) {
615 ZLOGE("GetAppShareOption empty, intention: %{public}s.", intention.c_str());
616 return ret;
617 }
618 ZLOGI("GetAppShareOption, intention: %{public}s, appShareOption:%{public}s.",
619 intention.c_str(), appShareOption.c_str());
620 shareOption = ShareOptionsUtil::GetEnumNum(appShareOption);
621 return E_OK;
622 }
623
RemoveAppShareOption(const std::string & intention)624 int32_t UdmfServiceImpl::RemoveAppShareOption(const std::string &intention)
625 {
626 if (intention.empty()) {
627 ZLOGE("intention: %{public}s is invalid.", intention.c_str());
628 return E_INVALID_PARAMETERS;
629 }
630 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
631 bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
632 bool hasSharePermission = VerifyPermission(MANAGE_UDMF_APP_SHARE_OPTION, IPCSkeleton::GetCallingTokenID());
633 if (!isSystemApp && !hasSharePermission) {
634 ZLOGE("No system permission and no shareOption permission, intention: %{public}s.", intention.c_str());
635 return E_NO_PERMISSION;
636 }
637 auto store = StoreCache::GetInstance().GetStore(intention);
638 if (store == nullptr) {
639 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
640 return E_DB_ERROR;
641 }
642
643 UnifiedData unifiedData;
644 if (store->DeleteLocal(std::to_string(accessTokenIDEx)) != E_OK) {
645 ZLOGE("Store DeleteLocal failed, intention: %{public}s.", intention.c_str());
646 return E_DB_ERROR;
647 }
648 return E_OK;
649 }
650
OnInitialize()651 int32_t UdmfServiceImpl::OnInitialize()
652 {
653 ZLOGD("start");
654 Status status = LifeCycleManager::GetInstance().OnStart();
655 if (status != E_OK) {
656 ZLOGE("OnStart execute failed, status: %{public}d", status);
657 }
658 status = LifeCycleManager::GetInstance().StartLifeCycleTimer();
659 if (status != E_OK) {
660 ZLOGE("StartLifeCycleTimer start failed, status: %{public}d", status);
661 }
662 return DistributedData::FeatureSystem::STUB_SUCCESS;
663 }
664
QueryDataCommon(const QueryOption & query,std::vector<UnifiedData> & dataSet,std::shared_ptr<Store> & store)665 int32_t UdmfServiceImpl::QueryDataCommon(
666 const QueryOption &query, std::vector<UnifiedData> &dataSet, std::shared_ptr<Store> &store)
667 {
668 auto find = UD_INTENTION_MAP.find(query.intention);
669 std::string intention = find == UD_INTENTION_MAP.end() ? intention : find->second;
670 if (!UnifiedDataUtils::IsValidOptions(query.key, intention)) {
671 ZLOGE("Unified key: %{public}s and intention: %{public}s is invalid.", query.key.c_str(), intention.c_str());
672 return E_INVALID_PARAMETERS;
673 }
674 std::string dataPrefix = DATA_PREFIX + intention;
675 UnifiedKey key(query.key);
676 key.IsValid();
677 if (intention.empty()) {
678 dataPrefix = key.key;
679 intention = key.intention;
680 }
681 ZLOGD("dataPrefix = %{public}s, intention: %{public}s.", dataPrefix.c_str(), intention.c_str());
682 store = StoreCache::GetInstance().GetStore(intention);
683 if (store == nullptr) {
684 ZLOGE("Get store failed, intention: %{public}s.", intention.c_str());
685 return E_DB_ERROR;
686 }
687 if (store->GetBatchData(dataPrefix, dataSet) != E_OK) {
688 ZLOGE("Get dataSet failed, dataPrefix: %{public}s.", dataPrefix.c_str());
689 return E_DB_ERROR;
690 }
691 return E_OK;
692 }
693
OnBind(const BindInfo & bindInfo)694 int32_t UdmfServiceImpl::OnBind(const BindInfo &bindInfo)
695 {
696 executors_ = bindInfo.executors;
697 StoreCache::GetInstance().SetThreadPool(bindInfo.executors);
698 LifeCycleManager::GetInstance().SetThreadPool(bindInfo.executors);
699 UriPermissionManager::GetInstance().SetThreadPool(bindInfo.executors);
700 return 0;
701 }
702
ResolveAutoLaunch(const std::string & identifier,DBLaunchParam & param)703 int32_t UdmfServiceImpl::ResolveAutoLaunch(const std::string &identifier, DBLaunchParam ¶m)
704 {
705 ZLOGI("user:%{public}s appId:%{public}s storeId:%{public}s identifier:%{public}s", param.userId.c_str(),
706 param.appId.c_str(), DistributedData::Anonymous::Change(param.storeId).c_str(),
707 DistributedData::Anonymous::Change(identifier).c_str());
708
709 std::vector<StoreMetaData> metaData;
710 auto prefix = StoreMetaData::GetPrefix({ DmAdapter::GetInstance().GetLocalDevice().uuid });
711 if (!DistributedData::MetaDataManager::GetInstance().LoadMeta(prefix, metaData)) {
712 ZLOGE("no meta data appId:%{public}s", param.appId.c_str());
713 return E_NOT_FOUND;
714 }
715
716 for (const auto &storeMeta : metaData) {
717 if (storeMeta.storeType < StoreMetaData::StoreType::STORE_KV_BEGIN ||
718 storeMeta.storeType > StoreMetaData::StoreType::STORE_KV_END ||
719 storeMeta.appId != DistributedData::Bootstrap::GetInstance().GetProcessLabel()) {
720 continue;
721 }
722 auto identifierTag = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId,
723 storeMeta.storeId, true);
724 if (identifier != identifierTag) {
725 continue;
726 }
727 auto store = StoreCache::GetInstance().GetStore(storeMeta.storeId);
728 if (store == nullptr) {
729 ZLOGE("GetStore fail, storeId:%{public}s", DistributedData::Anonymous::Change(storeMeta.storeId).c_str());
730 continue;
731 }
732 ZLOGI("storeId:%{public}s,appId:%{public}s,user:%{public}s",
733 DistributedData::Anonymous::Change(storeMeta.storeId).c_str(),
734 storeMeta.appId.c_str(), storeMeta.user.c_str());
735 return E_OK;
736 }
737 return E_OK;
738 }
739
VerifyPermission(const std::string & permission,uint32_t callerTokenId)740 bool UdmfServiceImpl::VerifyPermission(const std::string &permission, uint32_t callerTokenId)
741 {
742 if (permission.empty()) {
743 return true;
744 }
745 int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerTokenId, permission);
746 if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
747 ZLOGE("Permission denied. status:%{public}d, token:0x%{public}x, permission:%{public}s",
748 status, callerTokenId, permission.c_str());
749 return false;
750 }
751 return true;
752 }
753 } // namespace UDMF
754 } // namespace OHOS