1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "acl.h"
16
17 #include <dlfcn.h>
18 #include <fcntl.h>
19 #include <string>
20 #include <sys/xattr.h>
21 #include <unistd.h>
22 #include "gtest/gtest.h"
23 #include "securec.h"
24 using namespace testing::ext;
25 namespace OHOS::Test {
26 using namespace DATABASE_UTILS;
27 static constexpr uint32_t UID = 2024; // 2024 is test uid
28 static constexpr uint32_t TEST_UID = 2025; // 2025 is test uid
29 class AclTest : public testing::Test {
30 public:
31 static constexpr const char *PATH_ABC = "/data/test/abc";
32 static constexpr const char *PATH_ABC_XIAOMING = "/data/test/abc/xiaoming";
33 static constexpr const char *PATH_ABC_XIAOMING_TEST = "/data/test/abc/xiaoming/test.txt";
34 static constexpr const char *DATA = "SetDefaultUserTest";
35
36 static void SetUpTestCase(void);
37 static void TearDownTestCase(void);
38 void SetUp();
39 void TearDown();
40 void PreOperation() const;
41 };
42
SetUpTestCase(void)43 void AclTest::SetUpTestCase(void)
44 {
45 }
46
TearDownTestCase(void)47 void AclTest::TearDownTestCase(void)
48 {
49 }
50
51 // input testcase setup step,setup invoked before each testcases
SetUp(void)52 void AclTest::SetUp(void)
53 {
54 (void)remove(PATH_ABC);
55 }
56
57 // input testcase teardown step,teardown invoked after each testcases
TearDown(void)58 void AclTest::TearDown(void)
59 {
60 (void)remove(PATH_ABC);
61 }
62
PreOperation() const63 void AclTest::PreOperation() const
64 {
65 mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771
66 int res = mkdir(PATH_ABC, mode);
67 EXPECT_EQ(res, 0) << "directory creation failed." << std::strerror(errno);
68
69 Acl acl(PATH_ABC);
70 acl.SetDefaultUser(UID, Acl::R_RIGHT | Acl::W_RIGHT);
71 acl.SetDefaultGroup(UID, Acl::R_RIGHT | Acl::W_RIGHT);
72
73 res = mkdir(PATH_ABC_XIAOMING, mode);
74 EXPECT_EQ(res, 0) << "directory creation failed." << std::strerror(errno);
75
76 int fd = open(PATH_ABC_XIAOMING_TEST, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
77 EXPECT_NE(fd, -1) << "open file failed." << std::strerror(errno);
78 res = write(fd, DATA, strlen(DATA));
79 EXPECT_NE(res, -1) << "write failed." << std::strerror(errno);
80 res = fsync(fd);
81 EXPECT_NE(res, -1) << "fsync failed." << std::strerror(errno);
82 close(fd);
83 }
84
85 /**
86 * @tc.name: SetDefaultGroup001
87 * @tc.desc: Set default extended properties for groups.
88 * @tc.type: FUNC
89 * @tc.require:
90 * @tc.author: Jiaxing Chang
91 */
92 HWTEST_F(AclTest, SetDefaultGroup001, TestSize.Level0)
93 {
94 mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771
95 int res = mkdir(PATH_ABC, mode);
96 EXPECT_EQ(res, 0) << "directory creation failed.";
97 int rc = Acl(PATH_ABC).SetDefaultGroup(UID, Acl::R_RIGHT | Acl::W_RIGHT);
98 EXPECT_EQ(rc, 0);
99
100 Acl aclNew(PATH_ABC);
101 AclXattrEntry entry(ACL_TAG::GROUP, UID, Acl::R_RIGHT | Acl::W_RIGHT);
102 ASSERT_TRUE(aclNew.HasEntry(entry));
103 }
104
105 /**
106 * @tc.name: SetDefaultpUser001
107 * @tc.desc: Set default extended properties for user.
108 * @tc.type: FUNC
109 * @tc.require:
110 * @tc.author: Jiaxing Chang
111 */
112 HWTEST_F(AclTest, SetDefaultUser001, TestSize.Level0)
113 {
114 mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771
115 int res = mkdir(PATH_ABC, mode);
116 EXPECT_EQ(res, 0) << "directory creation failed.";
117 int rc = Acl(PATH_ABC).SetDefaultUser(UID, Acl::R_RIGHT | Acl::W_RIGHT);
118 EXPECT_EQ(rc, 0);
119
120 Acl aclNew(PATH_ABC);
121 AclXattrEntry entry(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
122 ASSERT_TRUE(aclNew.HasEntry(entry));
123 }
124
125 /**
126 * @tc.name: SetDefaultUser002
127 * @tc.desc: After the main process extends the uid attribute, set this uid to the uid and gid of the child process,
128 * and the child process can access the files created by the main process normally.
129 * @tc.type: FUNC
130 * @tc.require:
131 * @tc.author: Jiaxing Chang
132 */
133 HWTEST_F(AclTest, SetDefaultUser002, TestSize.Level0)
134 {
135 PreOperation();
136 int fd[2];
137 pid_t pid;
138 char buf[100];
139 int res = pipe(fd);
140 ASSERT_TRUE(res >= 0) << "create pipe failed." << std::strerror(errno);
141 pid = fork();
142 ASSERT_TRUE(pid >= 0) << "fork failed." << std::strerror(errno);
143 if (pid == 0) { // subprocess
144 // close the read end of the pipeline.
145 close(fd[0]);
146 // redirect standard output to the write end of the pipeline
147 dup2(fd[1], STDOUT_FILENO);
__anonada29bb90102(const std::string &str, bool isErr) 148 auto exitFun = [&fd](const std::string &str, bool isErr) {
149 std::cout << str << (isErr ? std::strerror(errno) : "") << std::endl;
150 close(fd[1]);
151 _exit(0);
152 };
153 if (setuid(UID) != 0) {
154 exitFun("setuid failed.", true);
155 }
156 if (setgid(UID) != 0) {
157 exitFun("setgid failed.", true);
158 }
159 int file = open(PATH_ABC_XIAOMING_TEST, O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
160 if (file == -1) {
161 exitFun("open file failed.", true);
162 }
163 if (read(file, buf, sizeof(buf)) == -1) {
164 close(file);
165 exitFun("read failed.", true);
166 }
167 close(file);
168 exitFun(buf, false);
169 } else { // main process
170 // close the write end of the pipeline.
171 close(fd[1]);
172 int status;
173 res = waitpid(pid, &status, 0);
174 EXPECT_NE(res, -1) << "waitpid falied." << std::strerror(errno);
175 res = memset_s(buf, sizeof(buf), 0, sizeof(buf));
176 EXPECT_EQ(res, EOK) << "memset_s falied." << std::strerror(errno);
177 res = read(fd[0], buf, sizeof(buf));
178 EXPECT_NE(res, -1) << "read falied." << std::strerror(errno);
179 EXPECT_EQ(std::string(buf, buf + strlen(buf) - 1), std::string(DATA)) << "buffer:[" << buf << "]";
180 close(fd[0]);
181 }
182 }
183
184 /**
185 * @tc.name: AclXattrEntry001
186 * @tc.desc: Test operator.
187 * @tc.type: FUNC
188 * @tc.require:
189 * @tc.author: SQL
190 */
191 HWTEST_F(AclTest, AclXattrEntry001, TestSize.Level0)
192 {
193 AclXattrEntry entryA(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
194 AclXattrEntry entryB(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
195 EXPECT_TRUE(entryA == entryB);
196
197 AclXattrEntry entryC(ACL_TAG::USER, TEST_UID, Acl::R_RIGHT | Acl::W_RIGHT);
198 EXPECT_FALSE(entryA == entryC);
199 }
200
201 /**
202 * @tc.name: AclXattrEntry002
203 * @tc.desc: Test IsValid().
204 * @tc.type: FUNC
205 * @tc.require:
206 * @tc.author: SQL
207 */
208 HWTEST_F(AclTest, AclXattrEntry002, TestSize.Level0)
209 {
210 AclXattrEntry entryA(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
211 auto result = entryA.IsValid();
212 EXPECT_TRUE(result);
213
214 AclXattrEntry entryB(ACL_TAG::GROUP, UID, Acl::R_RIGHT | Acl::W_RIGHT);
215 result = entryB.IsValid();
216 EXPECT_TRUE(result);
217
218 AclXattrEntry entryC(ACL_TAG::UNDEFINED, UID, Acl::R_RIGHT | Acl::W_RIGHT);
219 result = entryC.IsValid();
220 EXPECT_FALSE(result);
221 }
222
223 /**
224 * @tc.name: ACL_PERM001
225 * @tc.desc: Test ACL_PERM.
226 * @tc.type: FUNC
227 * @tc.require:
228 * @tc.author: SQL
229 */
230 HWTEST_F(AclTest, ACL_PERM001, TestSize.Level0)
231 {
232 ACL_PERM perm1;
233 perm1.SetR();
234 perm1.SetW();
235 ACL_PERM perm2;
236 perm2.SetE();
237
238 perm1.Merge(perm2);
239 EXPECT_TRUE(perm1.IsReadable());
240 EXPECT_TRUE(perm1.IsWritable());
241 EXPECT_TRUE(perm1.IsExecutable());
242 }
243 } // namespace OHOS::Test