2 * Copyright (c) 2015-2016 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.
18 * @file temp_test_user.cpp
19 * @author Jan Cybulski (j.cybulski@partner.samsung.com)
20 * @author Rafal Krypa (j.cybulski@samsung.com)
22 * @brief File with class for users management
27 #include <tests_common.h>
28 #include <temp_test_user.h>
29 #include <glib-object.h>
30 #include <dpl/test/test_runner.h>
33 #include <sys/prctl.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
37 TemporaryTestUser::TemporaryTestUser(TemporaryTestUser &&other)
38 : m_uid(other.m_uid), m_gid(other.m_gid), m_userName(std::move(other.m_userName)),
39 m_userType(other.m_userType), m_offline(other.m_offline), m_creatorPid(other.m_creatorPid)
41 other.m_creatorPid = -1;
44 void TemporaryTestUser::create(void)
50 Below line of code is a hack for Gumd commit that removes Smack management capabilities:
52 | commit 9b45c1afa49103dcb4101f4b28bf7c145f3294a6
53 |/ Author: Yunmi Ha <yunmi.ha@samsung.com>
54 | Date: Tue Jul 5 13:40:16 2016 +0900
56 | Remove smack capability
58 | with wearable profile, CAP_MAC_ADMIN and CAP_MAC_OVERRIDE capabilities are removed.
59 | (can't use useradd/del/modify function without offline option.)
60 | with other profile, only CAP_MAC_OVERRIDE capability is removed.
62 | For this, gumd launcher was changed to systemd.
64 | Change-Id: Ic95fceed41afc41e37e93606c3abf830536ac7d6
65 | Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
69 bool ret = m_runner.userCreate(m_userName, m_userType, m_offline, m_uid, m_gid);
70 RUNNER_ASSERT_MSG(ret, "Failed to add user");
71 RUNNER_ASSERT_MSG(m_uid != 0, "Something strange happened during user creation. uid == 0.");
72 RUNNER_ASSERT_MSG(m_gid != 0, "Something strange happened during user creation. gid == 0.");
75 void TemporaryTestUser::remove(void)
80 m_runner.userRemove(m_uid, m_offline);
84 TemporaryTestUser::~TemporaryTestUser()
86 if (m_creatorPid == getpid())
90 TemporaryTestUser::GumdRunner TemporaryTestUser::m_runner = TemporaryTestUser::GumdRunner();
92 TemporaryTestUser::GumdRunner::GumdRunner()
95 int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
96 RUNNER_ASSERT_MSG(ret != -1, "socketpair() failed");
99 RUNNER_ASSERT_MSG(pid != -1, "fork() failed");
107 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // Don't outlive parent process
108 run(); // Never returns
112 TemporaryTestUser::GumdRunner::~GumdRunner()
117 bool TemporaryTestUser::GumdRunner::userCreate(std::string userName,
118 GumUserType userType, bool offline, uid_t &uid, gid_t &gid)
120 put(static_cast<int>(opType::USER_CREATE));
121 put(userName.size());
122 put(userName.c_str(), userName.size());
126 bool ret = get<bool>();
134 bool TemporaryTestUser::GumdRunner::userRemove(uid_t uid, bool offline)
136 put(static_cast<int>(opType::USER_REMOVE));
143 void TemporaryTestUser::GumdRunner::run()
145 DEFINE_SMARTPTR(g_object_unref, GumUser, GumUserPtr);
148 switch(static_cast<opType>(get<int>())) {
149 case opType::USER_CREATE:
151 size_t userNameLen = get<size_t>();
152 std::unique_ptr<char[]> userNamePtr(new char[userNameLen + 1]);
153 get(userNamePtr.get(), userNameLen);
154 userNamePtr[userNameLen] = '\0';
155 GumUserType userType = get<GumUserType>();
156 bool offline = get<bool>();
162 GumUserPtr userPtr(gum_user_create_sync(offline));
164 g_object_set(G_OBJECT(userPtr.get()),
165 "username", userNamePtr.get(),
166 "usertype", userType,
168 gboolean ret = gum_user_add_sync(userPtr.get());
170 g_object_get(G_OBJECT(userPtr.get()), "uid", &uid, nullptr);
171 g_object_get(G_OBJECT(userPtr.get()), "gid", &gid, nullptr);
184 case opType::USER_REMOVE:
186 uid_t uid = get<uid_t>();
187 bool offline = get<bool>();
190 GumUserPtr userPtr(gum_user_get_sync(uid, offline));
192 gboolean ret = gum_user_delete_sync(userPtr.get(), TRUE);
193 result = (ret == TRUE);
195 put(static_cast<bool>(result));
202 void TemporaryTestUser::GumdRunner::get(void *buf, size_t cnt)
205 for (size_t pos = 0; pos < cnt; pos += ret) {
206 ret = TEMP_FAILURE_RETRY(
207 read(m_sock, static_cast<char *>(buf) + pos, cnt - pos));
208 RUNNER_ASSERT_MSG(ret != -1, "read() failed");
212 void TemporaryTestUser::GumdRunner::put(const void *buf, size_t cnt)
215 for (size_t pos = 0; pos < cnt; pos += ret) {
216 ret = TEMP_FAILURE_RETRY(
217 write(m_sock, static_cast<const char *>(buf) + pos, cnt - pos));
218 RUNNER_ASSERT_MSG(ret != -1, "write() failed");
223 T TemporaryTestUser::GumdRunner::get()
231 void TemporaryTestUser::GumdRunner::put(const T x)