Move a library/tools to libkrate git
[platform/core/security/krate.git] / module / krate.cpp
1 /*
2  *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  */
16
17 #include <dlfcn.h>
18 #include <syslog.h>
19 #include <security/pam_ext.h>
20 #include <security/pam_modules.h>
21
22 #include <string>
23 #include <vector>
24 #include <iostream>
25
26 #include "krate-guard.h"
27 #include "krate-builder.h"
28 #include "common/session.h"
29
30 #include <klay/exception.h>
31 #include <klay/filesystem.h>
32 #include <klay/xml/parser.h>
33 #include <klay/xml/document.h>
34
35 #define KRATE_UID_MIN 60001
36 #define KRATE_UID_MAX 60100
37
38 #define LAZYMOUNT_EXTERN extern
39 #define LAZYMOUNT_LIB "/usr/lib/liblazymount.so.0"
40
41 std::string buildKrateManifestPath(const std::string& name)
42 {
43         return "/home/" + name + "/.config/krate/krate.xml";
44 }
45
46 std::string getKrateName(pam_handle_t* handle)
47 {
48         const void* retItem;
49         int error = ::pam_get_item(handle, PAM_USER, &retItem);
50         if (error != PAM_SUCCESS) {
51                 throw runtime::Exception("Failed to get user");
52         }
53
54         return static_cast<const char*>(retItem);
55 }
56
57 static int wait_condition(void)
58 {
59     int r;
60     void *h;
61
62     int (*wait_mount_user)(void);
63
64     r = access(LAZYMOUNT_LIB, F_OK);
65     if (r < 0){
66         fprintf(stderr, "cannot find lazymount module - No support lazymount\n");
67         return 0;
68     }
69
70     h = dlopen(LAZYMOUNT_LIB, RTLD_LAZY);
71     if (!h) {
72         fprintf(stderr, "lazymount module dlopen error\n");
73         return -1;
74     }
75
76         do{
77         wait_mount_user = (int (*)())dlsym(h, "wait_mount_user");
78         if (!wait_mount_user) {
79             fprintf(stderr, "dlsym wait_mount_user error\n");
80             dlclose(h);
81             return -1;
82         }
83     } while (0);
84
85     r = wait_mount_user();
86     if (r < 0) {
87         fprintf(stderr, "wait_mout_user failed\n");
88         dlclose(h);
89         return r;
90     }
91
92     dlclose(h);
93     return 0;
94 }
95
96 extern "C" {
97 LAZYMOUNT_EXTERN  __attribute__((visibility("default")))
98 int container_preprocess(char* id) {
99         std::cout << "kraterize (UID " << id << ")..." << std::endl << std::flush;
100         try {
101                 runtime::User user(std::stoi(std::string(id)));
102                 KrateGuard krateGuard(user.getName());
103                 krateGuard.wait();
104
105                 auto sessionBuilder = [](const runtime::User& user) {
106                         KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
107                         builder.unshareNamespace();
108                 };
109                 createSession(user, sessionBuilder);
110
111                 if (user.getUid() >= KRATE_UID_MIN && user.getUid() <= KRATE_UID_MAX ) {
112                         wait_condition();
113                 }
114         } catch (runtime::Exception& e) {
115                 std::cerr << "krate error : " << e.what() <<std::endl << std::flush;
116                 return -1;
117         }
118
119         std::cout << "krate preprocess completed!" << std::endl << std::flush;
120         return 0;
121 }
122
123 LAZYMOUNT_EXTERN  __attribute__((visibility("default")))
124 int container_postprocess(char* id) {
125         try {
126                 runtime::User user(std::stoi(std::string(id)));
127                 KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
128                 builder.mountOwnFilesystem();
129         } catch (runtime::Exception& e) {
130                 std::cerr << "krate error : " << e.what() << std::endl << std::flush;
131                 return -1;
132         }
133         std::cout << "krate postprocess completed!" << std::endl << std::flush;
134         std::cout << "kraterized!" << std::endl << std::flush;
135         return 0;
136 }
137
138 PAM_EXTERN  __attribute__((visibility("default")))
139 int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
140 {
141         try {
142                 runtime::User user(getKrateName(pamh));
143                 KrateGuard krateGuard(user.getName());
144                 krateGuard.wait();
145
146                 auto sessionBuilder = [](const runtime::User& user) {
147                         KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
148                         builder.unshareNamespace();
149                         builder.mountOwnFilesystem();
150                 };
151                 createSession(user, sessionBuilder);
152         } catch (runtime::Exception& e) {
153                 ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
154                 return PAM_SESSION_ERR;
155         }
156
157         return PAM_SUCCESS;
158 }
159
160 PAM_EXTERN  __attribute__((visibility("default")))
161 int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
162 {
163         try {
164                 runtime::User user(getKrateName(pamh));
165                 KrateGuard krateGuard(user.getName());
166                 krateGuard.wait();
167
168                 destroySession(user);
169         } catch (runtime::Exception& e) {
170                 ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
171                 return PAM_SESSION_ERR;
172         }
173
174         return PAM_SUCCESS;
175 }
176
177 #ifdef PAM_MODULE_ENTRY
178 PAM_MODULE_ENTRY("pam_krate");
179 #endif
180
181 }