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 &param)
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