#include <protocols.h>
#include <service_impl.h>
#include <connection.h>
+#include <zone-utils.h>
#include <security-manager.h>
#include <client-offline.h>
int retval;
ClientOffline offlineMode;
if (offlineMode.isOffline()) {
- retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid());
+ retval = SecurityManager::ServiceImpl::appInstall(*p_req, geteuid(), false);
} else {
MessageBuffer send, recv;
if (smack_smackfs_path() == NULL)
return SECURITY_MANAGER_SUCCESS;
+ // FIXME Below modifications related to zones are temporary. Remove when Smack Namespaces
+ // are implemented.
+ std::string zoneId;
+ if (!getZoneIdFromPid(getpid(), zoneId)) {
+ LogError("Failed to get ID of zone");
+ return SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE;
+ }
+
try {
- appLabel = SecurityManager::SmackLabels::generateAppLabel(app_id);
+ appLabel = SecurityManager::zoneSmackLabelGenerate(
+ SecurityManager::SmackLabels::generateAppLabel(app_id), zoneId);
+
} catch (...) {
LogError("Failed to generate smack label for appId: " << app_id);
return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
int retval;
ClientOffline offlineMode;
if (offlineMode.isOffline()) {
- retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid());
+ retval = SecurityManager::ServiceImpl::userAdd(p_req->uid, p_req->utype, geteuid(),
+ false);
} else {
MessageBuffer send, recv;
//server is working
${COMMON_PATH}/file-lock.cpp
${COMMON_PATH}/protocols.cpp
${COMMON_PATH}/message-buffer.cpp
+ ${COMMON_PATH}/master-req.cpp
${COMMON_PATH}/privilege_db.cpp
${COMMON_PATH}/smack-labels.cpp
${COMMON_PATH}/smack-rules.cpp
${COMMON_PATH}/smack-check.cpp
${COMMON_PATH}/service_impl.cpp
+ ${COMMON_PATH}/zone-utils.cpp
)
ADD_LIBRARY(${TARGET_COMMON} SHARED ${COMMON_SOURCES})
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/*
+ * @file master-req.h
+ * @author Lukasz Kostyra <l.kostyra@samsung.com>
+ * @brief Master request calls declaration
+ */
+
+#ifndef _SECURITY_MANAGER_MASTER_REQ_
+#define _SECURITY_MANAGER_MASTER_REQ_
+
+#include <string>
+#include <vector>
+
+#include "protocols.h"
+
+
+namespace SecurityManager {
+namespace MasterReq {
+
+/**
+ * Forwards Cynara Policy Update request to Master Service.
+ *
+ * @param[in] appID Application ID
+ * @param[in] uidstr String containing user identifier
+ * @param[in] oldPkgPrivileges Previously enabled privileges for the package,
+ * Must be sorted and without duplicates
+ * @param[in] newPkgPrivileges Currently enabled privileges for the package,
+ * Must be sorted and without duplicates
+ *
+ * @see CynaraAdmin::UpdateAppPolicy
+ */
+int CynaraPolicyUpdate(const std::string &appId, const std::string &uidstr,
+ const std::vector<std::string> &oldPkgPrivileges,
+ const std::vector<std::string> &newPkgPrivileges);
+
+/**
+ * Forwards Cynara user initialization to Master service.
+ *
+ * @param[in] uidAdded New user UID
+ * @param[in] userType Type of user, enumerated in security-manager.h
+ * @return API return code, as defined in protocols.h
+ *
+ * @see CynaraAdmin::UserInit
+ */
+int CynaraUserInit(const uid_t uidAdded, int userType);
+
+/**
+ * Forwards Cynara user removal to Master service.
+ *
+ * @param[in] uidDeleted Removed user UID
+ * @return API return code, as defined in protocols.h
+ *
+ * @see CynaraAdmin::UserRemove
+ */
+int CynaraUserRemove(const uid_t uidDeleted);
+
+/**
+ * Forwards SMACK rule installation to Master service.
+ *
+ * @param[in] appId ID of application being removed
+ * @param[in] pkgId ID of package being removed
+ * @param[in] pkgContents A list of all applications in the package
+ * @return API return code, as defined in protocols.h
+ *
+ * @see SmackRules::installApplicationRules
+ */
+int SmackInstallRules(const std::string &appId, const std::string &pkgId,
+ const std::vector<std::string> &pkgContents);
+
+/**
+ * Forwards SMACK rule removal to Master service.
+ *
+ * @param[in] appId ID of application being removed
+ * @param[in] pkgId ID of package being removed
+ * @param[in] pkgContents A list of all applications in the package
+ * @param[in] removePkg Flag stating if entire package should be removed
+ * @return API return code, as defined in protocols.h
+ *
+ * @see SmackRules::uninstallPackageRules, SmackRules::uninstallApplicationRules
+ */
+int SmackUninstallRules(const std::string &appId, const std::string &pkgId,
+ const std::vector<std::string> &pkgContents, const bool removePkg);
+
+/**
+ * Forwards policyUpdate API to Master. Arguments are the same as policyUpdate.
+ *
+ * @return API return code, as defined in protocols.h
+ *
+ * @see ServiceImpl::policyUpdate
+ */
+int PolicyUpdate(const std::vector<policy_entry> &policyEntries, uid_t uid, pid_t pid,
+ const std::string &smackLabel);
+
+/**
+ * Forwards getConfiguredPolicy API to Master. Arguments are the same as getConfiguredPolicy.
+ *
+ * @return API return code, as defined in protocols.h
+ *
+ * @see ServiceImpl::getConfiguredPolicy
+ */
+int GetConfiguredPolicy(bool forAdmin, const policy_entry &filter, uid_t uid, pid_t pid,
+ const std::string &smackLabel, std::vector<policy_entry> &policyEntries);
+
+/**
+ * Forwards getPolicy API to Master. Arguments are the same as getPolicy.
+ *
+ * @return API return code, as defined in protocols.h
+ *
+ * @see ServiceImpl::getPolicy
+ */
+int GetPolicy(const policy_entry &filter, uid_t uid, pid_t pid, const std::string &smackLabel,
+ std::vector<policy_entry> &policyEntries);
+
+/**
+ * Forwards policyGetDesc API to Master. Arguments are the same as policyGetDesc.
+ *
+ * @return API return code, as defined in protocols.h
+ *
+ * @see ServiceImpl::policyGetDesc
+ */
+int PolicyGetDesc(std::vector<std::string> &descriptions);
+
+} // namespace MasterReq
+} // namespace SecurityManager
+
+#endif // _SECURITY_MANAGER_MASTER_REQ_
NOOP = 0x90,
};
+enum class MasterSecurityModuleCall
+{
+ CYNARA_UPDATE_POLICY,
+ CYNARA_USER_INIT,
+ CYNARA_USER_REMOVE,
+ POLICY_UPDATE,
+ GET_CONFIGURED_POLICY,
+ GET_POLICY,
+ POLICY_GET_DESC,
+ SMACK_INSTALL_RULES,
+ SMACK_UNINSTALL_RULES,
+};
+
} // namespace SecurityManager
using namespace SecurityManager;
*
* @param[in] req installation request
* @param[in] uid id of the requesting user
+ * @param[in] isSlave Indicates if function should be called under slave mode
*
* @return API return code, as defined in protocols.h
*/
-int appInstall(const app_inst_req &req, uid_t uid);
+int appInstall(const app_inst_req &req, uid_t uid, bool isSlave);
/**
* Process application uninstallation request.
*
* @param[in] req uninstallation request
* @param[in] uid id of the requesting user
+ * @param[in] isSlave Indicates if function should be called under slave mode
*
* @return API return code, as defined in protocols.h
*/
-int appUninstall(const std::string &appId, uid_t uid);
+int appUninstall(const std::string &appId, uid_t uid, bool isSlave);
/**
* Process package id query.
* @param[in] appId application identifier
* @param[in] uid id of the requesting user
* @param[in] pid id of the requesting process (to construct Cynara session id)
+ * @param[in] isSlave Indicates if function should be called under slave mode
* @param[out] gids returned set of allowed group ids
*
* @return API return code, as defined in protocols.h
*/
-int getAppGroups(const std::string &appId, uid_t uid, pid_t pid, std::unordered_set<gid_t> &gids);
+int getAppGroups(const std::string &appId, uid_t uid, pid_t pid, bool isSlave,
+ std::unordered_set<gid_t> &gids);
/**
* Process user adding request.
* @param[in] uidAdded uid of newly created user
* @param[in] userType type of newly created user
* @param[in] uid uid of requesting user
+ * @param[in] isSlave Indicates if function should be called under slave mode
*
* @return API return code, as defined in protocols.h
*/
-int userAdd(uid_t uidAdded, int userType, uid_t uid);
+int userAdd(uid_t uidAdded, int userType, uid_t uid, bool isSlave);
/**
* Process user deletion request.
*
* @param[in] uidDeleted uid of removed user
* @param[in] uid uid of requesting user
+ * @param[in] isSlave Indicates if function should be called under slave mode
*
* @return API return code, as defined in protocols.h
*/
-int userDelete(uid_t uidDeleted, uid_t uid);
+int userDelete(uid_t uidDeleted, uid_t uid, bool isSlave);
/**
* Update policy in Cynara - proper privilege: http://tizen.org/privilege/systemsettings.admin
app_install_path_type pathType);
/**
+ * Sets Smack labels on a directory and its contents, recursively.
+ *
+ * @param appId[in] application's identifier
+ * @param path[in] path to a file or directory to setup
+ * @param pathType[in] type of path to setup. See description of
+ * app_install_path_type in security-manager.h for details
+ * @param zoneId[in] ID of zone for which label should be set
+ */
+void setupPath(const std::string &appId, const std::string &path,
+ app_install_path_type pathType, const std::string &zoneId);
+
+/**
* Sets Smack labels on a <ROOT_APP>/<pkg_id> and <ROOT_APP>/<pkg_id>/<app_id>
* non-recursively
*
const std::string &basePath);
/**
+ * Sets Smack labels on a <ROOT_APP>/<pkg_id> and <ROOT_APP>/<pkg_id>/<app_id>
+ * non-recursively
+ *
+ * @param pkgId[in] package identifier
+ * @param appId[in] application's identifier
+ * @param basePath[in] <ROOT_APP> path
+ * @param zoneId[in] ID of zone for which label should be set
+ */
+void setupCorrectPath(const std::string &pkgId, const std::string &appId,
+ const std::string &basePath, const std::string &zoneId);
+
+/**
* Generates application name for a label fetched from Cynara
*
* @param[in] label string to fetch application name for
const std::string &allowPermissions, const std::string &denyPermissions);
void loadFromFile(const std::string &path);
void addFromTemplate(const std::vector<std::string> &templateRules,
- const std::string &appId, const std::string &pkgId);
- void addFromTemplateFile(const std::string &appId, const std::string &pkgId);
+ const std::string &appId, const std::string &pkgId, const std::string &zoneId);
+ void addFromTemplateFile(const std::string &appId, const std::string &pkgId,
+ const std::string &zoneId);
void apply() const;
void clear() const;
* correct permissions to shared data.
*
* @param[in] pkgContents - a list of all applications inside this package
+ * @param[in] zoneId - ID of zone which requested application install
*/
- void generatePackageCrossDeps(const std::vector<std::string> &pkgContents);
+ void generatePackageCrossDeps(const std::vector<std::string> &pkgContents,
+ const std::string &zoneId);
/**
* Install package-specific smack rules.
*/
static void installApplicationRules(const std::string &appId, const std::string &pkgId,
const std::vector<std::string> &pkgContents);
+
+ /**
+ * Install package-specific smack rules.
+ *
+ * Function creates smack rules using predefined template. Rules are applied
+ * to the kernel and saved on persistent storage so they are loaded on system boot.
+ *
+ * @param[in] appId - application id that is beeing installed
+ * @param[in] pkgId - package id that the application is in
+ * @param[in] pkgContents - a list of all applications in the package
+ * @param[in] zoneId - ID of zone which requested application install
+ */
+ static void installApplicationRules(const std::string &appId, const std::string &pkgId,
+ const std::vector<std::string> &pkgContents, const std::string &zoneId);
/**
* Uninstall package-specific smack rules.
*
* @param[in] appId - application id
* @param[in] pkgId - package id that the application belongs to
* @param[in] appsInPkg - a list of other applications in the same package id that the application belongs to
+ * @param[in] zoneId - ID of zone which requested application uninstall
*/
static void uninstallApplicationRules(const std::string &appId, const std::string &pkgId,
- std::vector<std::string> appsInPkg);
+ std::vector<std::string> appsInPkg, const std::string &zoneId);
/**
* Update package specific rules
*
* @param[in] pkgId - id of the package to update
* @param[in] pkgContents - a list of all applications in the package
+ * @param[in] zoneId - ID of zone which requested application uninstall
*/
- static void updatePackageRules(const std::string &pkgId, const std::vector<std::string> &pkgContents);
+ static void updatePackageRules(const std::string &pkgId,
+ const std::vector<std::string> &pkgContents, const std::string &zoneId);
private:
/**
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file zone-utils.h
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @version 1.0
+ * @brief Definition of Zone utilities
+ */
+
+#ifndef _SECURITY_MANAGER_ZONE_UTILS_H_
+#define _SECURITY_MANAGER_ZONE_UTILS_H_
+
+#include <string>
+
+// FIXME This module is a replacement for Vasum functions.
+//
+// When Vasum will be included into OBS, the module should be removed and vasum-client should
+// be used instead.
+
+namespace SecurityManager
+{
+
+extern const std::string ZONE_HOST;
+
+/**
+ * Extracts Zone ID in which runs process having provided PID.
+ *
+ * This function parses /proc/<pid>/cpuset file and tries to acquire Zone ID name from it.
+ *
+ * @param[in] pid PID of process to get Zone ID from.
+ * @param[out] zoneId Zone ID extracted from cpuset. If process runs in host, returns "host" string.
+ * @return True on success, false on failure.
+ */
+bool getZoneIdFromPid(int pid, std::string& zoneId);
+
+/**
+ * Generates zone-specific label from given @ref label and zone's name @ref zoneName
+ *
+ * @param[in] label Base label, used to generate new zone-specific label
+ * @param[in] zoneName Name of zone for which label will be generated
+ * @return Generated label
+ */
+std::string zoneSmackLabelGenerate(const std::string &label, const std::string &zoneName);
+
+/**
+ * Map @ref hostLabel to @ref zoneLabel using Smack namespaces.
+ *
+ * FIXME This is a placeholder for Vasum API - implement when Smack Namespaces are implemented
+ *
+ * @param[in] hostLabel Smack label as seen from hosts perspective
+ * @param[in] zoneName Zone ID to which label will be mapped
+ * @param[in] zoneLabel Smack label seen from zone's perspective
+ * @return True on success, false on failure
+ */
+bool zoneSmackLabelMap(const std::string &hostLabel, const std::string &zoneName,
+ const std::string &zoneLabel);
+
+/**
+ * Unmap label mapped by zoneSmackLabelMap.
+ *
+ * FIXME This is a placeholder for Vasum API - implement when Smack Namespaces are implemented
+ *
+ * @param[in] hostLabel Label to unmap
+ * @param[in] zoneName Zone ID for which unmapping should be done
+ * @return True on success, false on failure
+ */
+bool zoneSmackLabelUnmap(const std::string &hostLabel, const std::string &zoneName);
+
+} //namespace SecurityManager
+
+#endif //_SECURITY_MANAGER_ZONE_UTILS_H_
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/*
+ * @file master-req.cpp
+ * @author Lukasz Kostyra <l.kostyra@samsung.com>
+ * @brief Definitions of master request calls
+ */
+
+#include "master-req.h"
+
+#include <dpl/serialization.h>
+
+#include "message-buffer.h"
+#include "connection.h"
+
+namespace SecurityManager {
+namespace MasterReq {
+
+int CynaraPolicyUpdate(const std::string &appId, const std::string &uidstr,
+ const std::vector<std::string> &oldPkgPrivileges,
+ const std::vector<std::string> &newPkgPrivileges)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::CYNARA_UPDATE_POLICY));
+ Serialization::Serialize(sendBuf, appId);
+ Serialization::Serialize(sendBuf, uidstr);
+ Serialization::Serialize(sendBuf, oldPkgPrivileges);
+ Serialization::Serialize(sendBuf, newPkgPrivileges);
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, ret);
+
+ return ret;
+}
+
+int CynaraUserInit(const uid_t uidAdded, int userType)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::CYNARA_USER_INIT));
+ Serialization::Serialize(sendBuf, uidAdded);
+ Serialization::Serialize(sendBuf, userType);
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, ret);
+
+ return ret;
+}
+
+int CynaraUserRemove(const uid_t uidDeleted)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::CYNARA_USER_REMOVE));
+ Serialization::Serialize(sendBuf, uidDeleted);
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, ret);
+
+ return ret;
+}
+
+int SmackInstallRules(const std::string &appId, const std::string &pkgId,
+ const std::vector<std::string> &pkgContents)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::SMACK_INSTALL_RULES));
+ Serialization::Serialize(sendBuf, appId);
+ Serialization::Serialize(sendBuf, pkgId);
+ Serialization::Serialize(sendBuf, pkgContents);
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, ret);
+
+ return ret;
+}
+
+int SmackUninstallRules(const std::string &appId, const std::string &pkgId,
+ const std::vector<std::string> &pkgContents, const bool removePkg)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::SMACK_UNINSTALL_RULES));
+ Serialization::Serialize(sendBuf, appId);
+ Serialization::Serialize(sendBuf, pkgId);
+ Serialization::Serialize(sendBuf, pkgContents);
+ Serialization::Serialize(sendBuf, removePkg);
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, ret);
+
+ return ret;
+}
+
+// Following three requests are just forwarded security-manager API calls
+// these do not access Privilege DB, so all can be forwarded to Master
+int PolicyUpdate(const std::vector<policy_entry> &policyEntries, uid_t uid, pid_t pid,
+ const std::string &smackLabel)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::POLICY_UPDATE));
+ Serialization::Serialize(sendBuf, policyEntries);
+ Serialization::Serialize(sendBuf, uid);
+ Serialization::Serialize(sendBuf, pid);
+ Serialization::Serialize(sendBuf, smackLabel);
+
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, ret);
+
+ return ret;
+}
+
+int GetConfiguredPolicy(bool forAdmin, const policy_entry &filter, uid_t uid, pid_t pid,
+ const std::string &smackLabel, std::vector<policy_entry> &policyEntries)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::GET_CONFIGURED_POLICY));
+ Serialization::Serialize(sendBuf, forAdmin);
+ Serialization::Serialize(sendBuf, filter);
+ Serialization::Serialize(sendBuf, uid);
+ Serialization::Serialize(sendBuf, pid);
+ Serialization::Serialize(sendBuf, smackLabel);
+
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS) {
+ Deserialization::Deserialize(retBuf, ret);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, policyEntries);
+ }
+
+ return ret;
+}
+
+int GetPolicy(const policy_entry &filter, uid_t uid, pid_t pid, const std::string &smackLabel,
+ std::vector<policy_entry> &policyEntries)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::GET_POLICY));
+ Serialization::Serialize(sendBuf, filter);
+ Serialization::Serialize(sendBuf, uid);
+ Serialization::Serialize(sendBuf, pid);
+ Serialization::Serialize(sendBuf, smackLabel);
+
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS) {
+ Deserialization::Deserialize(retBuf, ret);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, policyEntries);
+ }
+
+ return ret;
+}
+
+int PolicyGetDesc(std::vector<std::string> &descriptions)
+{
+ int ret;
+ MessageBuffer sendBuf, retBuf;
+ Serialization::Serialize(sendBuf,
+ static_cast<int>(MasterSecurityModuleCall::POLICY_GET_DESC));
+
+ ret = sendToServer(MASTER_SERVICE_SOCKET, sendBuf.Pop(), retBuf);
+ if (ret == SECURITY_MANAGER_API_SUCCESS) {
+ Deserialization::Deserialize(retBuf, ret);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Deserialization::Deserialize(retBuf, descriptions);
+ }
+
+ return ret;
+}
+
+} // namespace MasterReq
+} // namespace SecurityManager
#include "smack-rules.h"
#include "smack-labels.h"
#include "security-manager.h"
+#include "zone-utils.h"
#include "service_impl.h"
+#include "master-req.h"
namespace SecurityManager {
namespace ServiceImpl {
return true;
}
-int appInstall(const app_inst_req &req, uid_t uid)
+static inline bool getZoneId(std::string &zoneId)
+{
+ if (!getZoneIdFromPid(getpid(), zoneId)) {
+ LogError("Failed to get zone ID from current PID");
+ return false;
+ }
+
+ // This function should be called under slave mode only - assumes, that we work inside zone
+ if (zoneId == ZONE_HOST) {
+ LogError("We should not run in host - refusing request");
+ return false;
+ }
+
+ return true;
+}
+
+int appInstall(const app_inst_req &req, uid_t uid, bool isSlave)
{
std::vector<std::string> addedPermissions;
std::vector<std::string> removedPermissions;
std::string appLabel;
std::string pkgLabel;
+ std::string zoneId;
+ if (isSlave) {
+ if (!getZoneId(zoneId)) {
+ LogError("Failed to get Zone ID.");
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ }
+ }
+
if (uid) {
if (uid != req.uid) {
LogError("User " << uid <<
try {
std::vector<std::string> oldAppPrivileges;
- appLabel = SmackLabels::generateAppLabel(req.appId);
+ appLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(req.appId), zoneId);
/* NOTE: we don't use pkgLabel here, but generate it for pkgId validation */
- pkgLabel = SmackLabels::generatePkgLabel(req.pkgId);
+ pkgLabel = zoneSmackLabelGenerate(SmackLabels::generatePkgLabel(req.pkgId), zoneId);
LogDebug("Install parameters: appId: " << req.appId << ", pkgId: " << req.pkgId
<< ", uidstr " << uidstr
<< ", app label: " << appLabel << ", pkg label: " << pkgLabel);
PrivilegeDb::getInstance().UpdateAppPrivileges(req.appId, uid, req.privileges);
/* Get all application ids in the package to generate rules withing the package */
PrivilegeDb::getInstance().GetAppIdsForPkgId(req.pkgId, pkgContents);
- CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, uidstr, oldAppPrivileges,
- req.privileges);
+
+ if (isSlave) {
+ int ret = MasterReq::CynaraPolicyUpdate(req.appId, uidstr, oldAppPrivileges,
+ req.privileges);
+ if (ret != SECURITY_MANAGER_API_SUCCESS) {
+ PrivilegeDb::getInstance().RollbackTransaction();
+ LogError("Error while processing request on master: " << ret);
+ return ret;
+ }
+ } else {
+ CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, uidstr, oldAppPrivileges,
+ req.privileges);
+ }
+
PrivilegeDb::getInstance().CommitTransaction();
LogDebug("Application installation commited to database");
} catch (const PrivilegeDb::Exception::IOError &e) {
try {
if (isCorrectPath)
- SmackLabels::setupCorrectPath(req.pkgId, req.appId, appPath);
+ SmackLabels::setupCorrectPath(req.pkgId, req.appId, appPath, zoneId);
// register paths
for (const auto &appPath : req.appPaths) {
const std::string &path = appPath.first;
app_install_path_type pathType = static_cast<app_install_path_type>(appPath.second);
- SmackLabels::setupPath(req.appId, path, pathType);
+ SmackLabels::setupPath(req.appId, path, pathType, zoneId);
}
- LogDebug("Adding Smack rules for new appId: " << req.appId << " with pkgId: "
- << req.pkgId << ". Applications in package: " << pkgContents.size());
- SmackRules::installApplicationRules(req.appId, req.pkgId, pkgContents);
+ if (isSlave) {
+ LogDebug("Requesting master to add rules for new appId: " << req.appId << " with pkgId: "
+ << req.pkgId << ". Applications in package: " << pkgContents.size());
+ int ret = MasterReq::SmackInstallRules(req.appId, req.pkgId, pkgContents);
+ if (ret != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Master failed to apply package-specific smack rules: " << ret);
+ return ret;
+ }
+ } else {
+ LogDebug("Adding Smack rules for new appId: " << req.appId << " with pkgId: "
+ << req.pkgId << ". Applications in package: " << pkgContents.size());
+ SmackRules::installApplicationRules(req.appId, req.pkgId, pkgContents);
+ }
} catch (const SmackException::Base &e) {
LogError("Error while applying Smack policy for application: " << e.DumpToString());
return SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
- } catch (const std::bad_alloc &e) {
+ } catch (const SecurityManager::Exception &e) {
+ LogError("Security Manager exception: " << e.DumpToString());
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ }catch (const std::bad_alloc &e) {
LogError("Memory allocation error: " << e.what());
return SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
}
return SECURITY_MANAGER_API_SUCCESS;
}
-int appUninstall(const std::string &appId, uid_t uid)
+int appUninstall(const std::string &appId, uid_t uid, bool isSlave)
{
std::string pkgId;
std::string smackLabel;
std::string uidstr;
checkGlobalUser(uid, uidstr);
+ std::string zoneId;
+ if (isSlave) {
+ if (!getZoneId(zoneId)) {
+ LogError("Failed to get Zone ID.");
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ }
+ }
+
try {
std::vector<std::string> oldAppPrivileges;
PrivilegeDb::getInstance().RollbackTransaction();
appExists = false;
} else {
- smackLabel = SmackLabels::generateAppLabel(appId);
+ smackLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(appId), zoneId);
LogDebug("Uninstall parameters: appId: " << appId << ", pkgId: " << pkgId
<< ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
PrivilegeDb::getInstance().GetAppPrivileges(appId, uid, oldAppPrivileges);
PrivilegeDb::getInstance().UpdateAppPrivileges(appId, uid, std::vector<std::string>());
PrivilegeDb::getInstance().RemoveApplication(appId, uid, removePkg);
- CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, uidstr, oldAppPrivileges,
- std::vector<std::string>());
+
+ if (isSlave) {
+ int ret = MasterReq::CynaraPolicyUpdate(appId, uidstr, oldAppPrivileges,
+ std::vector<std::string>());
+ if (ret != SECURITY_MANAGER_API_SUCCESS) {
+ PrivilegeDb::getInstance().RollbackTransaction();
+ LogError("Error while processing request on master: " << ret);
+ return ret;
+ }
+ } else {
+ CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, uidstr, oldAppPrivileges,
+ std::vector<std::string>());
+ }
+
PrivilegeDb::getInstance().CommitTransaction();
LogDebug("Application uninstallation commited to database");
}
return SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
}
- try {
- if (appExists) {
- if (removePkg) {
- LogDebug("Removing Smack rules for deleted pkgId " << pkgId);
- SmackRules::uninstallPackageRules(pkgId);
- }
+ if (appExists) {
+ try {
+ if (isSlave) {
+ LogDebug("Delegating Smack rules removal for deleted pkgId " << pkgId <<
+ " to master");
+ int ret = MasterReq::SmackUninstallRules(appId, pkgId, pkgContents, removePkg);
+ if (ret != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Error while processing uninstall request on master: " << ret);
+ return ret;
+ }
+ } else {
+ if (removePkg) {
+ LogDebug("Removing Smack rules for deleted pkgId " << pkgId);
+ SmackRules::uninstallPackageRules(pkgId);
+ }
- LogDebug("Removing smack rules for deleted appId " << appId);
- SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents);
+ LogDebug ("Removing smack rules for deleted appId " << appId);
+ SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
+ }
+ } catch (const SmackException::Base &e) {
+ LogError("Error while removing Smack rules for application: " << e.DumpToString());
+ return SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
+ } catch (const SecurityManager::Exception &e) {
+ LogError("Security Manager error: " << e.DumpToString());
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation error: " << e.what());
+ return SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
}
- } catch (const SmackException::Base &e) {
- LogError("Error while removing Smack rules for application: " << e.DumpToString());
- return SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
- } catch (const std::bad_alloc &e) {
- LogError("Memory allocation error: " << e.what());
- return SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
}
return SECURITY_MANAGER_API_SUCCESS;
return SECURITY_MANAGER_API_SUCCESS;
}
-int getAppGroups(const std::string &appId, uid_t uid, pid_t pid, std::unordered_set<gid_t> &gids)
+int getAppGroups(const std::string &appId, uid_t uid, pid_t pid, bool isSlave,
+ std::unordered_set<gid_t> &gids)
{
+ // FIXME Temporary solution, see below
+ std::string zoneId;
+ if (isSlave) {
+ if (!getZoneId(zoneId)) {
+ LogError("Failed to get Zone ID.");
+ return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ }
+ }
+
try {
std::string pkgId;
std::string smackLabel;
}
LogDebug("pkgId: " << pkgId);
- smackLabel = SmackLabels::generateAppLabel(appId);
+ // FIXME getAppGroups should work without generating zone-specific labels when
+ // Smack Namespaces will work
+ smackLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(appId), zoneId);
LogDebug("smack label: " << smackLabel);
std::vector<std::string> privileges;
return SECURITY_MANAGER_API_SUCCESS;
}
-int userAdd(uid_t uidAdded, int userType, uid_t uid)
+int userAdd(uid_t uidAdded, int userType, uid_t uid, bool isSlave)
{
if (uid != 0)
return SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED;
- try {
- CynaraAdmin::getInstance().UserInit(uidAdded, static_cast<security_manager_user_type>(userType));
- } catch (CynaraException::InvalidParam &e) {
- return SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
+ if (isSlave) {
+ int ret = MasterReq::CynaraUserInit(uidAdded,
+ static_cast<security_manager_user_type>(userType));
+ if (ret != SECURITY_MANAGER_API_SUCCESS) {
+ LogError("Master failed to initialize user " << uidAdded << " of type " << userType);
+ return ret;
+ }
+ } else {
+ try {
+ CynaraAdmin::getInstance().UserInit(uidAdded, static_cast<security_manager_user_type>(userType));
+ } catch (CynaraException::InvalidParam &e) {
+ return SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
+ }
}
+
return SECURITY_MANAGER_API_SUCCESS;
}
-int userDelete(uid_t uidDeleted, uid_t uid)
+int userDelete(uid_t uidDeleted, uid_t uid, bool isSlave)
{
int ret = SECURITY_MANAGER_API_SUCCESS;
if (uid != 0)
}
for (auto &app: userApps) {
- if (appUninstall(app, uidDeleted) != SECURITY_MANAGER_API_SUCCESS) {
+ if (appUninstall(app, uidDeleted, isSlave) != SECURITY_MANAGER_API_SUCCESS) {
/*if uninstallation of this app fails, just go on trying to uninstall another ones.
we do not have anything special to do about that matter - user will be deleted anyway.*/
ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
}
}
- CynaraAdmin::getInstance().UserRemove(uidDeleted);
+ if (isSlave) {
+ int ret = MasterReq::CynaraUserRemove(uidDeleted);
+ if (ret) {
+ LogError("Master failed to delete user " << uidDeleted);
+ return ret;
+ }
+ } else {
+ CynaraAdmin::getInstance().UserRemove(uidDeleted);
+ }
return ret;
}
#include "security-manager.h"
#include "smack-labels.h"
+#include "zone-utils.h"
namespace SecurityManager {
namespace SmackLabels {
dirSetSmack(path, label, XATTR_NAME_SMACKEXEC, &labelExecs);
}
-void setupPath(const std::string &appId, const std::string &path,
- app_install_path_type pathType)
+void setupPath(const std::string &appId, const std::string &path, app_install_path_type pathType)
+{
+ setupPath(appId, path, pathType, std::string());
+}
+
+void setupPath(const std::string &appId, const std::string &path, app_install_path_type pathType,
+ const std::string &zoneId)
{
std::string label;
bool label_executables, label_transmute;
switch (pathType) {
case SECURITY_MANAGER_PATH_PRIVATE:
case SECURITY_MANAGER_PATH_RW:
- label = generateAppLabel(appId);
+ label = zoneSmackLabelGenerate(generateAppLabel(appId), zoneId);
label_executables = true;
label_transmute = false;
break;
void setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &basePath)
{
+ setupCorrectPath(pkgId, appId, basePath, std::string());
+}
+
+void setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &basePath,
+ const std::string& zoneId)
+{
std::string pkgPath = basePath + "/" + pkgId;
std::string appPath = pkgPath + "/" + appId;
- pathSetSmack(pkgPath.c_str(), generatePkgLabel(pkgId), XATTR_NAME_SMACK);
- pathSetSmack(appPath.c_str(), generateAppLabel(appId), XATTR_NAME_SMACK);
+ pathSetSmack(pkgPath.c_str(), zoneSmackLabelGenerate(generatePkgLabel(pkgId), zoneId), XATTR_NAME_SMACK);
+ pathSetSmack(appPath.c_str(), zoneSmackLabelGenerate(generateAppLabel(appId), zoneId), XATTR_NAME_SMACK);
pathSetSmack(appPath.c_str(), "TRUE", XATTR_NAME_SMACKTRANSMUTE);
}
#include "smack-labels.h"
#include "smack-rules.h"
+#include "zone-utils.h"
namespace SecurityManager {
}
-void SmackRules::addFromTemplateFile(const std::string &appId,
- const std::string &pkgId)
+void SmackRules::addFromTemplateFile(const std::string &appId, const std::string &pkgId,
+ const std::string &zoneId)
{
std::vector<std::string> templateRules;
std::string line;
ThrowMsg(SmackException::FileError, "Error reading template file: " << APP_RULES_TEMPLATE_FILE_PATH);
}
- addFromTemplate(templateRules, appId, pkgId);
+ addFromTemplate(templateRules, appId, pkgId, zoneId);
}
void SmackRules::addFromTemplate(const std::vector<std::string> &templateRules,
- const std::string &appId, const std::string &pkgId)
+ const std::string &appId, const std::string &pkgId, const std::string &zoneId)
{
for (auto rule : templateRules) {
if (rule.empty())
subject = SmackLabels::generateAppLabel(appId);
if (subject == SMACK_PKG_LABEL_TEMPLATE)
- subject = SmackLabels::generatePkgLabel(pkgId);
+ subject = SmackLabels::generatePkgLabel(pkgId);
if (object == SMACK_APP_LABEL_TEMPLATE)
object = SmackLabels::generateAppLabel(appId);
if (object == SMACK_PKG_LABEL_TEMPLATE)
object = SmackLabels::generatePkgLabel(pkgId);
+ if (!zoneId.empty()) {
+ // FIXME replace with vasum calls. See zone-utils.h
+ subject = zoneSmackLabelGenerate(subject, zoneId);
+ object = zoneSmackLabelGenerate(object, zoneId);
+ }
+
add(subject, object, permissions);
}
}
-void SmackRules::generatePackageCrossDeps(const std::vector<std::string> &pkgContents)
+void SmackRules::generatePackageCrossDeps(const std::vector<std::string> &pkgContents,
+ const std::string &zoneId)
{
LogDebug ("Generating cross-package rules");
if (object == subject)
continue;
- subjectLabel = SmackLabels::generateAppLabel(subject);
- objectLabel = SmackLabels::generateAppLabel(object);
+ subjectLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(subject), zoneId);
+ objectLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(object), zoneId);
LogDebug ("Trying to add rule subject: " << subjectLabel << " object: " << objectLabel << " perms: " << appsInPackagePerms);
add(subjectLabel, objectLabel, appsInPackagePerms);
}
void SmackRules::installApplicationRules(const std::string &appId, const std::string &pkgId,
const std::vector<std::string> &pkgContents)
{
+ installApplicationRules(appId, pkgId, pkgContents, std::string());
+}
+
+void SmackRules::installApplicationRules(const std::string &appId, const std::string &pkgId,
+ const std::vector<std::string> &pkgContents, const std::string &zoneId)
+{
SmackRules smackRules;
std::string appPath = getApplicationRulesFilePath(appId);
- smackRules.addFromTemplateFile(appId, pkgId);
+ smackRules.addFromTemplateFile(appId, pkgId, zoneId);
if (smack_smackfs_path() != NULL)
smackRules.apply();
smackRules.saveToFile(appPath);
- updatePackageRules(pkgId, pkgContents);
+ updatePackageRules(pkgId, pkgContents, zoneId);
}
-void SmackRules::updatePackageRules(const std::string &pkgId, const std::vector<std::string> &pkgContents)
+void SmackRules::updatePackageRules(const std::string &pkgId,
+ const std::vector<std::string> &pkgContents, const std::string &zoneId)
{
SmackRules smackRules;
std::string pkgPath = getPackageRulesFilePath(pkgId);
- smackRules.generatePackageCrossDeps(pkgContents);
+ smackRules.generatePackageCrossDeps(pkgContents, zoneId);
if (smack_smackfs_path() != NULL)
smackRules.apply();
}
void SmackRules::uninstallApplicationRules(const std::string &appId,
- const std::string &pkgId, std::vector<std::string> pkgContents)
+ const std::string &pkgId, std::vector<std::string> pkgContents, const std::string &zoneId)
{
uninstallRules(getApplicationRulesFilePath(appId));
- updatePackageRules(pkgId, pkgContents);
+ updatePackageRules(pkgId, pkgContents, zoneId);
}
void SmackRules::uninstallRules(const std::string &path)
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file zone-utils.cpp
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
+ * @version 1.0
+ * @brief Implementation of Zone utility functions
+ */
+
+#include "zone-utils.h"
+
+#include <fstream>
+
+#include <dpl/log/log.h>
+
+// FIXME This module is a replacement for Vasum functions.
+// When Vasum will be included into OBS, the module should be replaced with vasum-client.
+
+namespace {
+
+const std::string CPUSET_HOST = "/";
+const std::string CPUSET_LXC_PREFIX = "/lxc/";
+
+} // namespace
+
+namespace SecurityManager
+{
+
+// ZONE_HOST should be visible outside to other modules
+const std::string ZONE_HOST = "host";
+
+bool getZoneIdFromPid(int pid, std::string& zoneId)
+{
+ //open /proc/<pid>/cpuset and get its contents
+ const std::string path = "/proc/" + std::to_string(pid) + "/cpuset";
+
+ std::ifstream cpusetFile(path);
+ if (!cpusetFile) {
+ LogError("Failed to open cpuset");
+ return false;
+ }
+
+ std::string cpuset;
+ std::getline(cpusetFile, cpuset);
+ cpusetFile.close();
+
+ //check if we are in host
+ if (cpuset == CPUSET_HOST) {
+ zoneId = ZONE_HOST;
+ return true;
+ }
+
+ //in lxc container, cpuset contains "/lxc/<id>" string - try to parse zoneID from there
+ //search for lxc prefix
+ size_t lxcPrefixPos = cpuset.find(CPUSET_LXC_PREFIX);
+ if (lxcPrefixPos == std::string::npos) {
+ LogError("LXC prefix not found - probably other virtualization method is used");
+ return false;
+ }
+
+ //assign zone name and leave
+ zoneId.assign(cpuset, CPUSET_LXC_PREFIX.size(), cpuset.size() - CPUSET_LXC_PREFIX.size());
+ return true;
+}
+
+std::string zoneSmackLabelGenerate(const std::string &label, const std::string &zoneName)
+{
+ if (zoneName.empty() || zoneName == ZONE_HOST) {
+ return label;
+ }
+
+ return zoneName + "::" + label;
+}
+
+bool zoneSmackLabelMap(const std::string &hostLabel, const std::string &zoneName,
+ const std::string &zoneLabel)
+{
+ (void) hostLabel;
+ (void) zoneName;
+ (void) zoneLabel;
+ // FIXME here Vasum should be called and Smack label mapping would commence
+
+ return true;
+}
+
+bool zoneSmackLabelUnmap(const std::string &hostLabel, const std::string &zoneName)
+{
+ (void) hostLabel;
+ (void) zoneName;
+ // FIXME here Vasum should be called and label shall be unmapped.
+
+ return true;
+}
+
+} // namespace SecurityManager
PKG_CHECK_MODULES(SERVER_DEP
REQUIRED
libsystemd-daemon
+ cynara-client
)
FIND_PACKAGE(Boost REQUIRED COMPONENTS program_options)
* @return true on success
*/
bool processOne(const ConnectionID &conn, MessageBuffer &buffer, InterfaceID interfaceID);
+
+ /**
+ * Process Cynara policy update during app installation/uninstallation
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ * @param zoneId ID of zone which requested the call
+ */
+ void processCynaraUpdatePolicy(MessageBuffer &buffer, MessageBuffer &send,
+ const std::string &zoneId);
+
+ /**
+ * Process Cynara user initialization
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ void processCynaraUserInit(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process Cynara user removal
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ void processCynaraUserRemove(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process policy update
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ void processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process configured policy acquisition
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ void processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process policy acquisition from Master
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ */
+ // FIXME this function is not yet implemented.
+ void processGetPolicy(MessageBuffer &buffer, MessageBuffer &send);
+
+ /**
+ * Process policy descriptions list acquisition
+ *
+ * @param send Raw data buffer to be sent
+ */
+ void processPolicyGetDesc(MessageBuffer &send);
+
+ /**
+ * Process SMACK rules installation for package. Map rules using Smack Namespaces.
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ * @param zoneId ID of zone which requested the call
+ */
+ void processSmackInstallRules(MessageBuffer &buffer, MessageBuffer &send,
+ const std::string &zoneId);
+
+ /**
+ * Process SMACK rules uninstallation
+ *
+ * @param buffer Raw received data buffer
+ * @param send Raw data buffer to be sent
+ * @param zoneId ID of zone which requested the call
+ */
+ void processSmackUninstallRules(MessageBuffer &buffer, MessageBuffer &send,
+ const std::string &zoneId);
};
} // namespace SecurityManager
#include <dpl/serialization.h>
#include "protocols.h"
+#include "zone-utils.h"
+#include "cynara.h"
#include "master-service.h"
+#include "smack-rules.h"
+#include "smack-labels.h"
#include "service_impl.h"
namespace SecurityManager {
return false;
}
+ // FIXME this part needs to be updated when Vasum is added to OBS. See zone-utils.h
+ std::string vsmZoneId;
+ if (!getZoneIdFromPid(pid, vsmZoneId)) {
+ LogError("Failed to extract Zone ID! Closing socket.");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+
+ if (vsmZoneId == ZONE_HOST) {
+ LogError("Connection came from host - in master mode this should not happen! Closing.");
+ m_serviceManager->Close(conn);
+ return false;
+ }
+
+ LogInfo("Connection came from Zone " << vsmZoneId);
+
if (IFACE == interfaceID) {
Try {
// deserialize API call type
int call_type_int;
Deserialization::Deserialize(buffer, call_type_int);
- SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
+ MasterSecurityModuleCall call_type = static_cast<MasterSecurityModuleCall>(call_type_int);
switch (call_type) {
+ case MasterSecurityModuleCall::CYNARA_UPDATE_POLICY:
+ LogDebug("call type MasterSecurityModuleCall::CYNARA_UPDATE_POLICY");
+ processCynaraUpdatePolicy(buffer, send, vsmZoneId);
+ break;
+ case MasterSecurityModuleCall::CYNARA_USER_INIT:
+ LogDebug("call type MasterSecurityModuleCall::CYNARA_USER_INIT");
+ processCynaraUserInit(buffer, send);
+ break;
+ case MasterSecurityModuleCall::CYNARA_USER_REMOVE:
+ LogDebug("call type MasterSecurityModuleCall::CYNARA_USER_REMOVE");
+ processCynaraUserRemove(buffer, send);
+ break;
+ case MasterSecurityModuleCall::POLICY_UPDATE:
+ LogDebug("call type MasterSecurityModuleCall::POLICY_UPDATE");
+ processPolicyUpdate(buffer, send);
+ break;
+ case MasterSecurityModuleCall::GET_CONFIGURED_POLICY:
+ LogDebug("call type MasterSecurityModuleCall::GET_CONFIGURED_POLICY");
+ processGetConfiguredPolicy(buffer, send);
+ break;
+ case MasterSecurityModuleCall::GET_POLICY:
+ LogDebug("call type MasterSecurityModuleCall::GET_POLICY");
+ processGetPolicy(buffer, send);
+ break;
+ case MasterSecurityModuleCall::POLICY_GET_DESC:
+ LogDebug("call type MasterSecurityModuleCall::POLICY_GET_DESC");
+ processPolicyGetDesc(send);
+ break;
+ case MasterSecurityModuleCall::SMACK_INSTALL_RULES:
+ LogDebug("call type MasterSecurityModuleCall::SMACK_INSTALL_RULES");
+ processSmackInstallRules(buffer, send, vsmZoneId);
+ break;
+ case MasterSecurityModuleCall::SMACK_UNINSTALL_RULES:
+ LogDebug("call type MasterSecurityModuleCall::SMACK_UNINSTALL_RULES");
+ processSmackUninstallRules(buffer, send, vsmZoneId);
+ break;
default:
LogError("Invalid call: " << call_type_int);
Throw(MasterServiceException::InvalidAction);
return retval;
}
+void MasterService::processCynaraUpdatePolicy(MessageBuffer &buffer, MessageBuffer &send,
+ const std::string &zoneId)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ std::string appId;
+ std::string uidstr;
+ std::vector<std::string> oldAppPrivileges, newAppPrivileges;
+ std::string appLabel, newLabel;
+
+ Deserialization::Deserialize(buffer, appId);
+ Deserialization::Deserialize(buffer, uidstr);
+ Deserialization::Deserialize(buffer, oldAppPrivileges);
+ Deserialization::Deserialize(buffer, newAppPrivileges);
+
+ appLabel = zoneSmackLabelGenerate(SmackLabels::generateAppLabel(appId), zoneId);
+
+ try {
+ CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, uidstr, oldAppPrivileges,
+ newAppPrivileges);
+ } catch (const CynaraException::Base &e) {
+ LogError("Error while setting Cynara rules for application: " << e.DumpToString());
+ goto out;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation while setting Cynara rules for application: " << e.what());
+ ret = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ ret = SECURITY_MANAGER_API_SUCCESS;
+
+out:
+ Serialization::Serialize(send, ret);
+}
+
+void MasterService::processCynaraUserInit(MessageBuffer &buffer, MessageBuffer &send)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
+ uid_t uidAdded;
+ int userType;
+
+ Deserialization::Deserialize(buffer, uidAdded);
+ Deserialization::Deserialize(buffer, userType);
+
+ try {
+ CynaraAdmin::getInstance().UserInit(uidAdded,
+ static_cast<security_manager_user_type>(userType));
+ } catch (CynaraException::InvalidParam &e) {
+ goto out;
+ }
+
+ ret = SECURITY_MANAGER_API_SUCCESS;
+out:
+ Serialization::Serialize(send, ret);
+}
+
+void MasterService::processCynaraUserRemove(MessageBuffer &buffer, MessageBuffer &send)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
+ uid_t uidDeleted;
+
+ Deserialization::Deserialize(buffer, uidDeleted);
+
+ try {
+ CynaraAdmin::getInstance().UserRemove(uidDeleted);
+ } catch (CynaraException::InvalidParam &e) {
+ goto out;
+ }
+
+ ret = SECURITY_MANAGER_API_SUCCESS;
+out:
+ Serialization::Serialize(send, ret);
+}
+
+void MasterService::processPolicyUpdate(MessageBuffer &buffer, MessageBuffer &send)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ std::vector<policy_entry> policyEntries;
+ uid_t uid;
+ pid_t pid;
+ std::string smackLabel;
+
+ Deserialization::Deserialize(buffer, policyEntries);
+ Deserialization::Deserialize(buffer, uid);
+ Deserialization::Deserialize(buffer, pid);
+ Deserialization::Deserialize(buffer, smackLabel);
+
+ ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
+ Serialization::Serialize(send, ret);
+}
+
+void MasterService::processGetConfiguredPolicy(MessageBuffer &buffer, MessageBuffer &send)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ bool forAdmin;
+ policy_entry filter;
+ uid_t uid;
+ pid_t pid;
+ std::string smackLabel;
+ std::vector<policy_entry> policyEntries;
+
+ Deserialization::Deserialize(buffer, forAdmin);
+ Deserialization::Deserialize(buffer, filter);
+ Deserialization::Deserialize(buffer, uid);
+ Deserialization::Deserialize(buffer, pid);
+ Deserialization::Deserialize(buffer, smackLabel);
+
+ ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
+ Serialization::Serialize(send, ret);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Serialization::Serialize(send, policyEntries);
+}
+
+void MasterService::processGetPolicy(MessageBuffer &buffer, MessageBuffer &send)
+{
+ (void) buffer;
+ int ret = SECURITY_MANAGER_API_ERROR_BAD_REQUEST;
+
+ // FIXME getPolicy is not ready to work in Master mode. Uncomment below code when getPolicy will
+ // be implemented for Master.
+ /*
+ policy_entry filter;
+ uid_t uid;
+ pid_t pid;
+ std::string smackLabel;
+ std::vector<policy_entry> policyEntries;
+
+ Deserialization::Deserialize(buffer, filter);
+ Deserialization::Deserialize(buffer, uid);
+ Deserialization::Deserialize(buffer, pid);
+ Deserialization::Deserialize(buffer, smackLabel);
+
+ ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);*/
+ Serialization::Serialize(send, ret);
+ /*if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Serialization::Serialize(send, policyEntries);*/
+}
+
+void MasterService::processPolicyGetDesc(MessageBuffer &send)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ std::vector<std::string> descriptions;
+
+ ret = ServiceImpl::policyGetDesc(descriptions);
+ Serialization::Serialize(send, ret);
+ if (ret == SECURITY_MANAGER_API_SUCCESS)
+ Serialization::Serialize(send, descriptions);
+}
+
+void MasterService::processSmackInstallRules(MessageBuffer &buffer, MessageBuffer &send,
+ const std::string &zoneId)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ std::string appId, pkgId;
+ std::vector<std::string> pkgContents;
+
+ Deserialization::Deserialize(buffer, appId);
+ Deserialization::Deserialize(buffer, pkgId);
+ Deserialization::Deserialize(buffer, pkgContents);
+
+ try {
+ LogDebug("Adding Smack rules for new appId: " << appId << " with pkgId: "
+ << pkgId << ". Applications in package: " << pkgContents.size());
+ SmackRules::installApplicationRules(appId, pkgId, pkgContents, zoneId);
+
+ // FIXME implement zoneSmackLabelMap and check if works when Smack Namespaces are implemented
+ std::string zoneAppLabel = SmackLabels::generateAppLabel(appId);
+ std::string zonePkgLabel = SmackLabels::generatePkgLabel(pkgId);
+ std::string hostAppLabel = zoneSmackLabelGenerate(zoneAppLabel, zoneId);
+ std::string hostPkgLabel = zoneSmackLabelGenerate(zonePkgLabel, zoneId);
+
+ if (!zoneSmackLabelMap(hostAppLabel, zoneId, zoneAppLabel)) {
+ LogError("Failed to apply Smack label mapping for application " << appId);
+ goto out;
+ }
+
+ if (!zoneSmackLabelMap(hostPkgLabel, zoneId, zonePkgLabel)) {
+ LogError("Failed to apply Smack label mapping for package " << pkgId);
+ goto out;
+ }
+ } catch (const SmackException::Base &e) {
+ LogError("Error while adding Smack rules for application: " << e.DumpToString());
+ ret = SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
+ goto out;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation error: " << e.what());
+ ret = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ ret = SECURITY_MANAGER_API_SUCCESS;
+out:
+ Serialization::Serialize(send, ret);
+}
+
+void MasterService::processSmackUninstallRules(MessageBuffer &buffer, MessageBuffer &send,
+ const std::string &zoneId)
+{
+ int ret = SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+ std::string appId, pkgId;
+ std::vector<std::string> pkgContents;
+ bool removePkg = false;
+
+ Deserialization::Deserialize(buffer, appId);
+ Deserialization::Deserialize(buffer, pkgId);
+ Deserialization::Deserialize(buffer, pkgContents);
+ Deserialization::Deserialize(buffer, removePkg);
+
+ try {
+ if (removePkg) {
+ LogDebug("Removing Smack rules for deleted pkgId " << pkgId);
+ SmackRules::uninstallPackageRules(pkgId);
+ }
+
+ LogDebug ("Removing smack rules for deleted appId " << appId);
+ SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents, zoneId);
+
+ // FIXME implement zoneSmackLabelUnmap and check if works when Smack Namespaces are implemented
+ std::string zoneAppLabel = SmackLabels::generateAppLabel(appId);
+ std::string zonePkgLabel = SmackLabels::generatePkgLabel(pkgId);
+ std::string hostAppLabel = zoneSmackLabelGenerate(zoneAppLabel, zoneId);
+ std::string hostPkgLabel = zoneSmackLabelGenerate(zonePkgLabel, zoneId);
+
+ if (!zoneSmackLabelUnmap(hostAppLabel, zoneId)) {
+ LogError("Failed to unmap Smack labels for application " << appId);
+ goto out;
+ }
+
+ if (removePkg) {
+ if (!zoneSmackLabelUnmap(hostPkgLabel, zoneId)) {
+ LogError("Failed to unmap Smack label for package " << pkgId);
+ goto out;
+ }
+ }
+ } catch (const SmackException::Base &e) {
+ LogError("Error while removing Smack rules for application: " << e.DumpToString());
+ ret = SECURITY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED;
+ goto out;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation error: " << e.what());
+ ret = SECURITY_MANAGER_API_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ ret = SECURITY_MANAGER_API_SUCCESS;
+out:
+ Serialization::Serialize(send, ret);
+}
} // namespace SecurityManager
#include "protocols.h"
#include "service.h"
#include "service_impl.h"
+#include "master-req.h"
namespace SecurityManager {
Deserialization::Deserialize(buffer, req.privileges);
Deserialization::Deserialize(buffer, req.appPaths);
Deserialization::Deserialize(buffer, req.uid);
- Serialization::Serialize(send, ServiceImpl::appInstall(req, uid));
+ Serialization::Serialize(send, ServiceImpl::appInstall(req, uid, m_isSlave));
}
void Service::processAppUninstall(MessageBuffer &buffer, MessageBuffer &send, uid_t uid)
std::string appId;
Deserialization::Deserialize(buffer, appId);
- Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid));
+ Serialization::Serialize(send, ServiceImpl::appUninstall(appId, uid, m_isSlave));
}
void Service::processGetPkgId(MessageBuffer &buffer, MessageBuffer &send)
int ret;
Deserialization::Deserialize(buffer, appId);
- ret = ServiceImpl::getAppGroups(appId, uid, pid, gids);
+ ret = ServiceImpl::getAppGroups(appId, uid, pid, m_isSlave, gids);
Serialization::Serialize(send, ret);
if (ret == SECURITY_MANAGER_API_SUCCESS) {
Serialization::Serialize(send, static_cast<int>(gids.size()));
Deserialization::Deserialize(buffer, uidAdded);
Deserialization::Deserialize(buffer, userType);
- ret = ServiceImpl::userAdd(uidAdded, userType, uid);
+ ret = ServiceImpl::userAdd(uidAdded, userType, uid, m_isSlave);
Serialization::Serialize(send, ret);
}
Deserialization::Deserialize(buffer, uidRemoved);
- ret = ServiceImpl::userDelete(uidRemoved, uid);
+ ret = ServiceImpl::userDelete(uidRemoved, uid, m_isSlave);
Serialization::Serialize(send, ret);
}
Deserialization::Deserialize(buffer, policyEntries);
- ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
+ if (m_isSlave) {
+ ret = MasterReq::PolicyUpdate(policyEntries, uid, pid, smackLabel);
+ } else {
+ ret = ServiceImpl::policyUpdate(policyEntries, uid, pid, smackLabel);
+ }
Serialization::Serialize(send, ret);
}
policy_entry filter;
Deserialization::Deserialize(buffer, filter);
std::vector<policy_entry> policyEntries;
- ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
+
+ if (m_isSlave) {
+ ret = MasterReq::GetConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel, policyEntries);
+ } else {
+ ret = ServiceImpl::getConfiguredPolicy(forAdmin, filter, uid, pid, smackLabel,
+ policyEntries);
+ }
+
Serialization::Serialize(send, ret);
Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
for (const auto &policyEntry : policyEntries) {
policy_entry filter;
Deserialization::Deserialize(buffer, filter);
std::vector<policy_entry> policyEntries;
- ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
+
+ if (m_isSlave) {
+ ret = MasterReq::GetPolicy(filter, uid, pid, smackLabel, policyEntries);
+ } else {
+ ret = ServiceImpl::getPolicy(filter, uid, pid, smackLabel, policyEntries);
+ }
+
Serialization::Serialize(send, ret);
Serialization::Serialize(send, static_cast<int>(policyEntries.size()));
for (const auto &policyEntry : policyEntries) {
int ret;
std::vector<std::string> descriptions;
- ret = ServiceImpl::policyGetDesc(descriptions);
+ if (m_isSlave) {
+ ret = MasterReq::PolicyGetDesc(descriptions);
+ } else {
+ ret = ServiceImpl::policyGetDesc(descriptions);
+ }
Serialization::Serialize(send, ret);
if (ret == SECURITY_MANAGER_API_SUCCESS) {
Serialization::Serialize(send, static_cast<int>(descriptions.size()));