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