#pragma once
-#include <cynara.h>
-#include <channel.h>
+#include <mutex>
+
+#include "cynara.h"
+#include "channel.h"
+#include "mount-monitor.h"
namespace SecurityManager {
class NSMountLogic {
public:
- NSMountLogic(Cynara &cynara, Channel &channel)
- : m_cynara(cynara)
- , m_channel(channel)
- {}
-
struct Entry : public ISerializable {
typedef std::string Privilege;
typedef std::pair<Privilege,bool> PrivilegeStatus;
typedef std::vector<Entry> EntryVector;
+ void RegisterChannel(Channel channel) { m_channel = std::move(channel); }
+
bool check();
+ void mntEventCallback(MntDiffEntry &e);
+
+ bool enabled();
+
+ NSMountLogic(Cynara &cynara);
+
virtual ~NSMountLogic();
-protected:
- void readFiles(void);
- void cynaraCheck(void);
- bool sendJobs();
- EntryVector m_entryVector;
+private:
+ void readFiles(EntryVector &entryVector);
+ void cynaraCheck(EntryVector &entryVector);
+ bool sendJobs(EntryVector &entryVector);
+
Cynara &m_cynara;
- Channel &m_channel;
+ Channel m_channel;
+ MntMonitor *m_mntMonitor = nullptr;
+ std::mutex m_mutex;
};
} // namespace SecurityManager
#include "channel.h"
#include "credentials.h"
#include "cynara.h"
-#include "mount-monitor.h"
+#include "nsmount-logic.h"
#include "security-manager.h"
#include "smack-rules.h"
#include "protocols.h"
* @param[in] channel
*
*/
- void RegisterChannel(Channel channel) { m_channel = std::move(channel); }
+ void RegisterChannel(Channel channel) { m_NSMountLogic.RegisterChannel(std::move(channel)); }
private:
bool authenticate(const Credentials &creds, const std::string &privilege);
PrivilegeDb m_privilegeDb;
CynaraAdmin m_cynaraAdmin;
PrivilegeGids m_privilegeGids;
- Channel m_channel;
- MntMonitor *m_mntMonitor;
+ NSMountLogic m_NSMountLogic;
};
} /* namespace SecurityManager */
* @version 1.0
* @brief Logic for modifying up existing mount namespace.
*/
+
+#include <signal.h>
+
#include <string>
#include <filesystem.h>
#include <protocols.h>
#include <message-buffer.h>
#include <mount-namespace.h>
+#include <worker.h>
#include <dpl/serialization.h>
#include <nsmount-logic.h>
namespace SecurityManager {
-void NSMountLogic::readFiles(void)
+void NSMountLogic::readFiles(EntryVector &entryVector)
{
auto users = FS::getSubDirectoriesFromDirectory(MountNS::getUsersAppsMountPointsPath(), true);
auto last = std::remove_if(users.begin(), users.end(), notNumber);
std::string dir = MountNS::getUserAppsMountPointsPath(toNumber(user));
if (FS::directoryStatus(dir) > 0)
for (auto &smackLabel : FS::getFilesFromDirectory(dir))
- m_entryVector.emplace_back(toNumber(user), smackLabel);
+ entryVector.emplace_back(toNumber(user), smackLabel);
}
}
-void NSMountLogic::cynaraCheck(void)
+void NSMountLogic::cynaraCheck(EntryVector &entryVector)
{
- for (auto &entry : m_entryVector) {
+ for (auto &entry : entryVector) {
if (entry.smackLabel.empty())
continue;
}
}
-bool NSMountLogic::sendJobs(void)
+bool NSMountLogic::sendJobs(EntryVector &entryVector)
{
int status;
MessageBuffer send, recv;
- Serialization::Serialize(send, m_entryVector);
+ Serialization::Serialize(send, entryVector);
if (!m_channel.write(send)) {
LogError("Could not send data to worker!");
return false;
return status == 0;
}
+bool NSMountLogic::enabled()
+{
+ static bool enabled = MountNS::isMountNamespaceEnabled();
+
+ return enabled;
+}
+
bool NSMountLogic::check()
{
+ if (!enabled())
+ return true;
+
+ // Critical section
+ std::lock_guard<std::mutex> guard(m_mutex);
try {
- readFiles();
- cynaraCheck();
- return sendJobs();
+ EntryVector entryVector;
+ readFiles(entryVector);
+ cynaraCheck(entryVector);
+ return sendJobs(entryVector);
} catch (const MessageBuffer::Exception::Base &e) {
LogError("Worker connection failed: " << e.DumpToString());
} catch (const FS::Exception::Base &e) {
return false;
}
+void NSMountLogic::mntEventCallback(MntDiffEntry &e)
+{
+ if (!enabled())
+ return;
+
+ // TODO: react only on mount events on directories related to a privilege
+ // TODO: filter out mount events that are generated by security-manager itself
+ if (e.m_type == MntDiffEntry::Type::MOUNT || e.m_type == MntDiffEntry::Type::UMOUNT)
+ check();
+}
+
+NSMountLogic::NSMountLogic(Cynara &cynara) :
+ m_cynara(cynara)
+{
+ if (!enabled())
+ return;
+
+ m_mntMonitor = new MntMonitor(
+ std::bind(&NSMountLogic::mntEventCallback, this, std::placeholders::_1));
+}
+
NSMountLogic::~NSMountLogic()
-{}
+{
+ if (m_mntMonitor != nullptr)
+ delete m_mntMonitor;
+ m_channel.closeAll();
+}
} // namespace SecurityManager
#include <sys/smack.h>
#include <config.h>
-#include <nsmount-logic.h>
#include "protocols.h"
#include "privilege_db.h"
#include "cynara.h"
} // end of anonymous namespace
-ServiceImpl::ServiceImpl()
+ServiceImpl::ServiceImpl() :
+ m_NSMountLogic(m_cynara)
{
PrivilegeGids::GroupPrivileges group_privileges;
m_privilegeDb.GetGroupsRelatedPrivileges(group_privileges);
m_privilegeGids.init(group_privileges);
-
- if (MountNS::isMountNamespaceEnabled())
- m_mntMonitor = new MntMonitor([this](MntDiffEntry &e) {
- // TODO: react only on mount events on directories related to a privilege
- // TODO: filter out mount events that are generated by security-manager itself
- if (e.m_type == MntDiffEntry::Type::MOUNT || e.m_type == MntDiffEntry::Type::UMOUNT)
- NSMountLogic(m_cynara, m_channel).check();
- });
- else
- m_mntMonitor = nullptr;
}
ServiceImpl::~ServiceImpl()
{
- if (m_mntMonitor != nullptr)
- delete m_mntMonitor;
}
int ServiceImpl::validatePolicy(const Credentials &creds, policy_entry &policyEntry, CynaraAdminPolicy &cyap)
// Apply updates
m_cynaraAdmin.setPolicies(validatedPolicies);
- if (MountNS::isMountNamespaceEnabled())
- NSMountLogic(m_cynara, m_channel).check();
-
+ // Update mount namespaces
+ // TODO: Don't update all users, apps and privileges, filter by policyEntries
+ m_NSMountLogic.check();
} catch (const CynaraException::Base &e) {
LogError("Error while updating Cynara rules: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;