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