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 "securec.h"
18 #include "gtest/gtest.h"
19 #include <dlfcn.h>
20 #include <fcntl.h>
21 #include <string>
22 #include <sys/xattr.h>
23 #include <unistd.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
TearDownTestCase(void)45 void AclTest::TearDownTestCase(void) { }
46
47 // input testcase setup step,setup invoked before each testcases
SetUp(void)48 void AclTest::SetUp(void)
49 {
50 (void)remove(PATH_ABC);
51 }
52
53 // input testcase teardown step,teardown invoked after each testcases
TearDown(void)54 void AclTest::TearDown(void)
55 {
56 (void)remove(PATH_ABC);
57 }
58
PreOperation() const59 void AclTest::PreOperation() const
60 {
61 mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771
62 int res = mkdir(PATH_ABC, mode);
63 EXPECT_EQ(res, 0) << "directory creation failed." << std::strerror(errno);
64
65 Acl acl(PATH_ABC);
66 acl.SetDefaultUser(UID, Acl::R_RIGHT | Acl::W_RIGHT);
67 acl.SetDefaultGroup(UID, Acl::R_RIGHT | Acl::W_RIGHT);
68
69 res = mkdir(PATH_ABC_XIAOMING, mode);
70 EXPECT_EQ(res, 0) << "directory creation failed." << std::strerror(errno);
71
72 int fd = open(PATH_ABC_XIAOMING_TEST, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
73 EXPECT_NE(fd, -1) << "open file failed." << std::strerror(errno);
74 res = write(fd, DATA, strlen(DATA));
75 EXPECT_NE(res, -1) << "write failed." << std::strerror(errno);
76 res = fsync(fd);
77 EXPECT_NE(res, -1) << "fsync failed." << std::strerror(errno);
78 close(fd);
79 }
80
81 /**
82 * @tc.name: SetDefaultGroup001
83 * @tc.desc: Set default extended properties for groups.
84 * @tc.type: FUNC
85 * @tc.require:
86 * @tc.author: Jiaxing Chang
87 */
88 HWTEST_F(AclTest, SetDefaultGroup001, TestSize.Level0)
89 {
90 mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771
91 int res = mkdir(PATH_ABC, mode);
92 EXPECT_EQ(res, 0) << "directory creation failed.";
93 int rc = Acl(PATH_ABC).SetDefaultGroup(UID, Acl::R_RIGHT | Acl::W_RIGHT);
94 EXPECT_EQ(rc, 0);
95
96 Acl aclNew(PATH_ABC);
97 AclXattrEntry entry(ACL_TAG::GROUP, UID, Acl::R_RIGHT | Acl::W_RIGHT);
98 ASSERT_TRUE(aclNew.HasEntry(entry));
99 }
100
101 /**
102 * @tc.name: SetDefaultpUser001
103 * @tc.desc: Set default extended properties for user.
104 * @tc.type: FUNC
105 * @tc.require:
106 * @tc.author: Jiaxing Chang
107 */
108 HWTEST_F(AclTest, SetDefaultUser001, TestSize.Level0)
109 {
110 mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH; // 0771
111 int res = mkdir(PATH_ABC, mode);
112 EXPECT_EQ(res, 0) << "directory creation failed.";
113 int rc = Acl(PATH_ABC).SetDefaultUser(UID, Acl::R_RIGHT | Acl::W_RIGHT);
114 EXPECT_EQ(rc, 0);
115
116 Acl aclNew(PATH_ABC);
117 AclXattrEntry entry(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
118 ASSERT_TRUE(aclNew.HasEntry(entry));
119 }
120
121 /**
122 * @tc.name: SetDefaultUser002
123 * @tc.desc: After the main process extends the uid attribute, set this uid to the uid and gid of the child process,
124 * and the child process can access the files created by the main process normally.
125 * @tc.type: FUNC
126 * @tc.require:
127 * @tc.author: Jiaxing Chang
128 */
129 HWTEST_F(AclTest, SetDefaultUser002, TestSize.Level0)
130 {
131 PreOperation();
132 int fd[2];
133 pid_t pid;
134 char buf[100];
135 int res = pipe(fd);
136 ASSERT_TRUE(res >= 0) << "create pipe failed." << std::strerror(errno);
137 pid = fork();
138 ASSERT_TRUE(pid >= 0) << "fork failed." << std::strerror(errno);
139 if (pid == 0) { // subprocess
140 // close the read end of the pipeline.
141 close(fd[0]);
142 // redirect standard output to the write end of the pipeline
143 dup2(fd[1], STDOUT_FILENO);
__anon02610dc10102(const std::string &str, bool isErr) 144 auto exitFun = [&fd](const std::string &str, bool isErr) {
145 std::cout << str << (isErr ? std::strerror(errno) : "") << std::endl;
146 close(fd[1]);
147 _exit(0);
148 };
149 if (setuid(UID) != 0) {
150 exitFun("setuid failed.", true);
151 }
152 if (setgid(UID) != 0) {
153 exitFun("setgid failed.", true);
154 }
155 int file = open(PATH_ABC_XIAOMING_TEST, O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
156 if (file == -1) {
157 exitFun("open file failed.", true);
158 }
159 if (read(file, buf, sizeof(buf)) == -1) {
160 close(file);
161 exitFun("read failed.", true);
162 }
163 close(file);
164 exitFun(buf, false);
165 } else { // main process
166 // close the write end of the pipeline.
167 close(fd[1]);
168 int status;
169 res = waitpid(pid, &status, 0);
170 EXPECT_NE(res, -1) << "waitpid falied." << std::strerror(errno);
171 res = memset_s(buf, sizeof(buf), 0, sizeof(buf));
172 EXPECT_EQ(res, EOK) << "memset_s falied." << std::strerror(errno);
173 res = read(fd[0], buf, sizeof(buf));
174 EXPECT_NE(res, -1) << "read falied." << std::strerror(errno);
175 EXPECT_EQ(std::string(buf, buf + strlen(buf) - 1), std::string(DATA)) << "buffer:[" << buf << "]";
176 close(fd[0]);
177 }
178 }
179
180 /**
181 * @tc.name: AclXattrEntry001
182 * @tc.desc: Test operator.
183 * @tc.type: FUNC
184 * @tc.require:
185 * @tc.author: SQL
186 */
187 HWTEST_F(AclTest, AclXattrEntry001, TestSize.Level0)
188 {
189 AclXattrEntry entryA(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
190 AclXattrEntry entryB(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
191 EXPECT_TRUE(entryA == entryB);
192
193 AclXattrEntry entryC(ACL_TAG::USER, TEST_UID, Acl::R_RIGHT | Acl::W_RIGHT);
194 EXPECT_FALSE(entryA == entryC);
195 }
196
197 /**
198 * @tc.name: AclXattrEntry002
199 * @tc.desc: Test IsValid().
200 * @tc.type: FUNC
201 * @tc.require:
202 * @tc.author: SQL
203 */
204 HWTEST_F(AclTest, AclXattrEntry002, TestSize.Level0)
205 {
206 AclXattrEntry entryA(ACL_TAG::USER, UID, Acl::R_RIGHT | Acl::W_RIGHT);
207 auto result = entryA.IsValid();
208 EXPECT_TRUE(result);
209
210 AclXattrEntry entryB(ACL_TAG::GROUP, UID, Acl::R_RIGHT | Acl::W_RIGHT);
211 result = entryB.IsValid();
212 EXPECT_TRUE(result);
213
214 AclXattrEntry entryC(ACL_TAG::UNDEFINED, UID, Acl::R_RIGHT | Acl::W_RIGHT);
215 result = entryC.IsValid();
216 EXPECT_FALSE(result);
217 }
218
219 /**
220 * @tc.name: ACL_PERM001
221 * @tc.desc: Test ACL_PERM.
222 * @tc.type: FUNC
223 * @tc.require:
224 * @tc.author: SQL
225 */
226 HWTEST_F(AclTest, ACL_PERM001, TestSize.Level0)
227 {
228 ACL_PERM perm1;
229 perm1.SetR();
230 perm1.SetW();
231 ACL_PERM perm2;
232 perm2.SetE();
233
234 perm1.Merge(perm2);
235 EXPECT_TRUE(perm1.IsReadable());
236 EXPECT_TRUE(perm1.IsWritable());
237 EXPECT_TRUE(perm1.IsExecutable());
238 }
239 } // namespace OHOS::Test