2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
20 #include <security/pam_ext.h>
21 #include <security/pam_modules.h>
27 #include "krate-builder.h"
29 #include <klay/cgroup.h>
30 #include <klay/namespace.h>
31 #include <klay/exception.h>
32 #include <klay/filesystem.h>
33 #include <klay/xml/parser.h>
34 #include <klay/xml/document.h>
36 #define CGROUP_SUBSYSTEM "krate"
38 #define KRATE_UID_MIN 6000
39 #define KRATE_UID_MAX 6999
41 #define LAZYMOUNT_EXTERN extern
42 #define LAZYMOUNT_LIB "/usr/lib/liblazymount.so.0"
44 std::string buildKrateManifestPath(const std::string& name)
46 return "/home/" + name + "/.config/krate/krate.xml";
49 std::string getKrateName(pam_handle_t* handle)
52 int error = ::pam_get_item(handle, PAM_USER, &retItem);
53 if (error != PAM_SUCCESS) {
54 throw runtime::Exception("Failed to get user");
57 return static_cast<const char*>(retItem);
60 void enterKrate(const std::string& name)
62 std::string path = CGROUP_SUBSYSTEM "/" + name;
65 if (runtime::Cgroup::exist(CGROUP_SUBSYSTEM, path)) {
66 auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
67 if (pids.size() > 0) {
71 runtime::Cgroup::create(CGROUP_SUBSYSTEM, path);
75 runtime::Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid());
76 runtime::Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC);
78 runtime::Namespace::attach(pid);
83 PAM_EXTERN __attribute__((visibility("default")))
84 int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
87 runtime::User user(getKrateName(pamh));
88 enterKrate(user.getName());
89 if (user.getUid() >= KRATE_UID_MIN && user.getUid() <= KRATE_UID_MAX ) {
90 runtime::File flag("/run/user/" + std::to_string(user.getUid()) + "/.container");
94 } catch (runtime::Exception& e) {
95 ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
96 return PAM_SESSION_ERR;
102 PAM_EXTERN __attribute__((visibility("default")))
103 int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
106 std::string name = getKrateName(pamh);
107 auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, name);
108 if (pids.size() <= 1) {
109 std::string path = CGROUP_SUBSYSTEM "/" + name;
110 runtime::Cgroup::destroy(CGROUP_SUBSYSTEM, path);
111 runtime::User user(name);
112 runtime::File flag("/run/user/" + std::to_string(user.getUid()) + "/.container");
116 } catch (runtime::Exception& e) {
117 ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
118 return PAM_SESSION_ERR;
124 #ifdef PAM_MODULE_ENTRY
125 PAM_MODULE_ENTRY("pam_krate");