• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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