namespace SecurityManager {
+/**
+ * Rules for apps and users are organized into set of buckets stored in Cynara.
+ * Bucket is set of rules (app, uid, privilege) -> (DENY, ALLOW, BUCKET, ...).
+ * |------------------------|
+ * | <<allow>> |
+ * | PRIVACY_MANAGER |
+ * |------------------------|
+ * | A U P policy|
+ * |------------------------|
+ * | app1 uid1 priv1 DENY |
+ * | * uid2 priv2 DENY |
+ * | * * * Bucket:MAIN|
+ * |------------------------|
+ *
+ * For details about buckets see Cynara documentation.
+ *
+ * Security Manager currently defines 8 buckets:
+ * - PRIVACY_MANAGER - first bucket during search (which is actually default bucket
+ * with empty string as id). If user specifies his preference then required rule
+ * is created here.
+ * - MAIN - holds rules denied by manufacturer, redirects to MANIFESTS
+ * bucket and holds entries for each user pointing to User Type
+ * specific buckets
+ * - MANIFESTS - stores rules needed by installed apps (from package
+ * manifest)
+ * - USER_TYPE_ADMIN
+ * - USER_TYPE_SYSTEM
+ * - USER_TYPE_NORMAL
+ * - USER_TYPE_GUEST - they store privileges from templates for apropriate
+ * user type. ALLOW rules only.
+ * - ADMIN - stores custom rules introduced by device administrator.
+ * Ignored if no matching rule found.
+ *
+ * Below is basic layout of buckets:
+ *
+ * |------------------------|
+ * | <<allow>> |
+ * | PRIVACY_MANAGER |
+ * | |
+ * | * * * Bucket:MAIN| |------------------|
+ * |------------------------| | <<deny>> |
+ * | |->| MANIFESTS |
+ * ----------------- | | |
+ * | | |------------------|
+ * V |
+ * |------------------------| |
+ * | <<deny>> |---|
+ * | MAIN |
+ * |---------------| | | |-------------------|
+ * | <<deny>> |<--| * * * Bucket:MANIFESTS|---->| <<deny>> |
+ * | USER_TYPE_SYST| |------------------------| | USER_TYPE_NORMAL |
+ * | | | | | |
+ * |---------------| | | |-------------------|
+ * | | | |
+ * | V V |
+ * | |---------------| |---------------| |
+ * | | <<deny>> | | <<deny>> | |
+ * | |USER_TYPE_GUEST| |USER_TYPE_ADMIN| |
+ * | | | | | |
+ * | |---------------| |---------------| |
+ * | | | |
+ * | |---- -----| |
+ * | | | |
+ * | V V |
+ * | |------------------| |
+ * |-------------> | <<none>> | <---------------|
+ * | ADMIN |
+ * | |
+ * |------------------|
+ *
+ */
+CynaraAdmin::BucketsMap CynaraAdmin::Buckets =
+{
+ { Bucket::PRIVACY_MANAGER, std::string(CYNARA_ADMIN_DEFAULT_BUCKET)},
+ { Bucket::MAIN, std::string("MAIN")},
+ { Bucket::USER_TYPE_ADMIN, std::string("USER_TYPE_ADMIN")},
+ { Bucket::USER_TYPE_NORMAL, std::string("USER_TYPE_NORMAL")},
+ { Bucket::USER_TYPE_GUEST, std::string("USER_TYPE_GUEST") },
+ { Bucket::USER_TYPE_SYSTEM, std::string("USER_TYPE_SYSTEM")},
+ { Bucket::ADMIN, std::string("ADMIN")},
+ { Bucket::MANIFESTS, std::string("MANIFESTS")},
+};
+
CynaraAdminPolicy::CynaraAdminPolicy(const std::string &client, const std::string &user,
const std::string &privilege, Operation operation,
LogDebug("(user = " << user << " label = " << label << ") " <<
"removing privilege " << *oldIter);
policies.push_back(CynaraAdminPolicy(label, user, *oldIter,
- CynaraAdminPolicy::Operation::Delete));
+ CynaraAdminPolicy::Operation::Delete,
+ Buckets.at(Bucket::MANIFESTS)));
++oldIter;
} else {
LogDebug("(user = " << user << " label = " << label << ") " <<
"adding privilege " << *newIter);
policies.push_back(CynaraAdminPolicy(label, user, *newIter,
- CynaraAdminPolicy::Operation::Allow));
+ CynaraAdminPolicy::Operation::Allow,
+ Buckets.at(Bucket::MANIFESTS)));
++newIter;
}
}
LogDebug("(user = " << user << " label = " << label << ") " <<
"removing privilege " << *oldIter);
policies.push_back(CynaraAdminPolicy(label, user, *oldIter,
- CynaraAdminPolicy::Operation::Delete));
+ CynaraAdminPolicy::Operation::Delete,
+ Buckets.at(Bucket::MANIFESTS)));
}
for (; newIter != newPrivileges.end(); ++newIter) {
LogDebug("(user = " << user << " label = " << label << ") " <<
"adding privilege " << *newIter);
policies.push_back(CynaraAdminPolicy(label, user, *newIter,
- CynaraAdminPolicy::Operation::Allow));
+ CynaraAdminPolicy::Operation::Allow,
+ Buckets.at(Bucket::MANIFESTS)));
}
SetPolicies(policies);
}
+void CynaraAdmin::UserInit(uid_t uid, security_manager_user_type userType)
+{
+ Bucket bucket;
+ std::vector<CynaraAdminPolicy> policies;
+
+ switch (userType) {
+ case SM_USER_TYPE_SYSTEM:
+ bucket = Bucket::USER_TYPE_SYSTEM;
+ break;
+ case SM_USER_TYPE_ADMIN:
+ bucket = Bucket::USER_TYPE_ADMIN;
+ break;
+ case SM_USER_TYPE_GUEST:
+ bucket = Bucket::USER_TYPE_GUEST;
+ break;
+ case SM_USER_TYPE_NORMAL:
+ bucket = Bucket::USER_TYPE_NORMAL;
+ break;
+ case SM_USER_TYPE_ANY:
+ case SM_USER_TYPE_NONE:
+ case SM_USER_TYPE_END:
+ default:
+ ThrowMsg(CynaraException::InvalidParam, "User type incorrect");
+ }
+
+ policies.push_back(CynaraAdminPolicy(CYNARA_ADMIN_WILDCARD,
+ std::to_string(static_cast<unsigned int>(uid)),
+ CYNARA_ADMIN_WILDCARD,
+ Buckets.at(bucket),
+ Buckets.at(Bucket::MAIN)));
+
+ CynaraAdmin::getInstance().SetPolicies(policies);
+}
+
+void CynaraAdmin::ListPolicies(
+ const std::string &bucketName,
+ const std::string &appId,
+ const std::string &user,
+ const std::string &privilege,
+ std::vector<CynaraAdminPolicy> &policies)
+{
+ struct cynara_admin_policy ** pp_policies = nullptr;
+
+ checkCynaraError(
+ cynara_admin_list_policies(m_CynaraAdmin, bucketName.c_str(), appId.c_str(),
+ user.c_str(), privilege.c_str(), &pp_policies),
+ "Error while getting list of policies for bucket: " + bucketName);
+
+ for (std::size_t i = 0; pp_policies[i] != nullptr; i++) {
+ policies.push_back(std::move(*static_cast<CynaraAdminPolicy*>(pp_policies[i])));
+
+ free(pp_policies[i]);
+ }
+
+ free(pp_policies);
+
+}
+
Cynara::Cynara()
{
checkCynaraError(