Skip to content
API Documentation
BastionGuard™
bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp} Namespace Reference

Classes

struct  CommandResult

Functions

bool executableExists (const char *path) noexcept
std::string firstExecutable (std::initializer_list< const char * > candidates)
CommandResult runCommand (const std::vector< std::string > &arguments) noexcept
bool startsWithPath (const std::filesystem::path &path, const std::filesystem::path &prefix) noexcept
bool isSystemdUnitExtension (const std::string &extension)
std::optional< std::string > systemdUnitName (const std::filesystem::path &path)
ServiceActionResult resultFrom (const std::string &operation, const ServiceTarget &target, const std::vector< CommandResult > &results)

Function Documentation

◆ executableExists()

bool bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::executableExists ( const char * path)
noexcept

Definition at line 21 of file SystemServiceControl.cpp.

22{
23 return path && ::access(path, X_OK) == 0;
24}

References executableExists().

Referenced by executableExists(), and firstExecutable().

◆ firstExecutable()

std::string bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::firstExecutable ( std::initializer_list< const char * > candidates)

Definition at line 26 of file SystemServiceControl.cpp.

27{
28 for (const char* candidate : candidates) {
29 if (executableExists(candidate))
30 return candidate;
31 }
32 return {};
33}

References executableExists(), and firstExecutable().

Referenced by firstExecutable().

◆ isSystemdUnitExtension()

bool bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::isSystemdUnitExtension ( const std::string & extension)

Definition at line 105 of file SystemServiceControl.cpp.

106{
107 return extension == ".service" || extension == ".socket" ||
108 extension == ".timer" || extension == ".path" ||
109 extension == ".mount" || extension == ".automount" ||
110 extension == ".target";
111}

References isSystemdUnitExtension().

Referenced by isSystemdUnitExtension(), and systemdUnitName().

◆ resultFrom()

ServiceActionResult bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::resultFrom ( const std::string & operation,
const ServiceTarget & target,
const std::vector< CommandResult > & results )

Definition at line 130 of file SystemServiceControl.cpp.

133{
134 bool success = true;
135 std::ostringstream message;
136 message << operation << " " << target.name << " using " << toString(target.init);
137 for (const auto& result : results) {
138 if (result.exitCode != 0)
139 success = false;
140 if (!result.output.empty())
141 message << ": " << result.output;
142 }
143 return {success, message.str()};
144}
const char * toString(Mode mode) noexcept
Definition Policy.cpp:6

References bastionguard::rootguard::ServiceTarget::init, bastionguard::rootguard::ServiceTarget::name, resultFrom(), and bastionguard::rootguard::toString().

Referenced by resultFrom().

◆ runCommand()

CommandResult bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::runCommand ( const std::vector< std::string > & arguments)
noexcept

Definition at line 35 of file SystemServiceControl.cpp.

36{
37 CommandResult result;
38 if (arguments.empty())
39 return result;
40
41 int descriptors[2]{};
42 if (::pipe(descriptors) != 0)
43 return result;
44
45 const pid_t child = ::fork();
46 if (child < 0) {
47 ::close(descriptors[0]);
48 ::close(descriptors[1]);
49 return result;
50 }
51
52 if (child == 0) {
53 ::close(descriptors[0]);
54 ::dup2(descriptors[1], STDOUT_FILENO);
55 ::dup2(descriptors[1], STDERR_FILENO);
56 ::close(descriptors[1]);
57
58 std::vector<char*> argv;
59 argv.reserve(arguments.size() + 1);
60 for (const auto& argument : arguments)
61 argv.push_back(const_cast<char*>(argument.c_str()));
62 argv.push_back(nullptr);
63 ::execv(argv.front(), argv.data());
64 _exit(127);
65 }
66
67 ::close(descriptors[1]);
68 std::array<char, 2048> buffer{};
69 for (;;) {
70 const ssize_t count = ::read(descriptors[0], buffer.data(), buffer.size());
71 if (count > 0) {
72 result.output.append(buffer.data(), static_cast<std::size_t>(count));
73 continue;
74 }
75 if (count < 0 && errno == EINTR)
76 continue;
77 break;
78 }
79 ::close(descriptors[0]);
80
81 int status = 0;
82 while (::waitpid(child, &status, 0) < 0 && errno == EINTR) {
83 }
84 if (WIFEXITED(status))
85 result.exitCode = WEXITSTATUS(status);
86 else if (WIFSIGNALED(status))
87 result.exitCode = 128 + WTERMSIG(status);
88 return result;
89}

References bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::CommandResult::exitCode, bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::CommandResult::output, and runCommand().

Referenced by runCommand().

◆ startsWithPath()

bool bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::startsWithPath ( const std::filesystem::path & path,
const std::filesystem::path & prefix )
noexcept

Definition at line 91 of file SystemServiceControl.cpp.

93{
94 const auto normalizedPath = path.lexically_normal();
95 const auto normalizedPrefix = prefix.lexically_normal();
96 auto pathIt = normalizedPath.begin();
97 for (auto prefixIt = normalizedPrefix.begin();
98 prefixIt != normalizedPrefix.end(); ++prefixIt, ++pathIt) {
99 if (pathIt == normalizedPath.end() || *pathIt != *prefixIt)
100 return false;
101 }
102 return true;
103}

References startsWithPath().

Referenced by startsWithPath().

◆ systemdUnitName()

std::optional< std::string > bastionguard::rootguard::anonymous_namespace{SystemServiceControl.cpp}::systemdUnitName ( const std::filesystem::path & path)

Definition at line 113 of file SystemServiceControl.cpp.

114{
115 if (isSystemdUnitExtension(path.extension().string()))
116 return path.filename().string();
117
118 for (auto current = path.parent_path(); !current.empty() && current != current.root_path();
119 current = current.parent_path()) {
120 const std::string name = current.filename().string();
121 if (name.size() > 2 && name.compare(name.size() - 2, 2, ".d") == 0) {
122 const std::string unit = name.substr(0, name.size() - 2);
123 if (isSystemdUnitExtension(std::filesystem::path(unit).extension().string()))
124 return unit;
125 }
126 }
127 return std::nullopt;
128}

References isSystemdUnitExtension(), and systemdUnitName().

Referenced by systemdUnitName().