2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Jan Olszak (j.olszak@samsung.com)
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
21 * @author Jan Olszak (j.olszak@samsung.com)
22 * @brief Server class definition
28 #include "containers-manager.hpp"
29 #include "exception.hpp"
31 #include "config/manager.hpp"
32 #include "logger/logger.hpp"
33 #include "utils/glib-loop.hpp"
34 #include "utils/environment.hpp"
35 #include "utils/fs.hpp"
46 #include <boost/filesystem.hpp>
49 #ifndef SECURITY_CONTAINERS_USER
50 #error "SECURITY_CONTAINERS_USER must be defined!"
53 #ifndef INPUT_EVENT_GROUP
54 #error "INPUT_EVENT_GROUP must be defined!"
58 #error "LIBVIRT_GROUP must be defined!"
61 extern char** environ;
63 namespace security_containers {
66 Server::Server(const std::string& configPath, bool runAsRoot)
67 : mConfigPath(configPath)
69 if (!prepareEnvironment(configPath, runAsRoot)) {
70 throw ServerException("Environment setup failed");
82 std::atomic_bool gUpdateTriggered(false);
83 utils::Latch gSignalLatch;
85 void signalHandler(const int sig)
87 LOGI("Got signal " << sig);
90 LOGD("Received SIGUSR1 - triggering update.");
91 gUpdateTriggered = true;
101 signal(SIGINT, signalHandler);
102 signal(SIGTERM, signalHandler);
103 signal(SIGUSR1, signalHandler);
105 LOGI("Starting daemon...");
107 utils::ScopedGlibLoop loop;
108 ContainersManager manager(mConfigPath);
111 LOGI("Daemon started");
115 // Detach containers if we triggered an update
116 if (gUpdateTriggered) {
117 manager.setContainersDetachOnExit();
120 LOGI("Stopping daemon...");
121 // manager.stopAll() will be called in destructor
123 LOGI("Daemon stopped");
126 void Server::reloadIfRequired(char* argv[])
128 if (gUpdateTriggered) {
129 execve(argv[0], argv, environ);
131 LOGE("Failed to reload " << argv[0] << ": " << strerror(errno));
135 void Server::terminate()
137 LOGI("Terminating server");
141 bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot)
143 namespace fs = boost::filesystem;
145 // TODO: currently this config is loaded twice: here and in ContainerManager
146 ContainersManagerConfig config;
147 config::loadFromFile(configPath, config);
149 struct passwd* pwd = ::getpwnam(SECURITY_CONTAINERS_USER);
151 LOGE("getpwnam failed to find user '" << SECURITY_CONTAINERS_USER << "'");
154 uid_t uid = pwd->pw_uid;
155 gid_t gid = pwd->pw_gid;
156 LOGD("security-containers UID = " << uid << ", GID = " << gid);
158 // create directory for dbus socket (if needed)
159 if (!config.runMountPointPrefix.empty()) {
160 if (!utils::createDir(config.runMountPointPrefix, uid, gid,
161 fs::perms::owner_all |
162 fs::perms::group_read | fs::perms::group_exe |
163 fs::perms::others_read | fs::perms::others_exe)) {
168 // Omit supplementaty group setup and root drop if the user is already switched.
169 // This situation will happen during daemon update triggered by SIGUSR1.
170 if (!runAsRoot && geteuid() == uid) {
174 // LIBVIRT_GROUP provides access to libvirt's daemon socket.
175 // INPUT_EVENT_GROUP provides access to /dev/input/event* devices used by InputMonitor.
176 if (!utils::setSuppGroups({LIBVIRT_GROUP, INPUT_EVENT_GROUP})) {
180 // CAP_SYS_ADMIN allows to mount tmpfs' for dbus communication at the runtime.
181 // NOTE: CAP_MAC_OVERRIDE is temporary and must be removed when "smack namespace"
182 // is introduced. The capability is needed to allow modify SMACK labels of
183 // "/var/run/containers/<container>/run" mount point.
184 return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN, CAP_MAC_OVERRIDE}));
188 } // namespace security_containers