Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <unistd.h>
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include "TemporaryFile.h"
     22 
     23 #if defined(__BIONIC__)
     24 #include "../libc/bionic/grp_pwd_file.cpp"
     25 
     26 template <typename T>
     27 class FileUnmapper {
     28  public:
     29   FileUnmapper(T& file) : file_(file) {
     30   }
     31   ~FileUnmapper() {
     32     file_.Unmap();
     33   }
     34 
     35  private:
     36   T& file_;
     37 };
     38 
     39 void FindAndCheckPasswdEntry(PasswdFile* file, const char* name, uid_t uid, gid_t gid,
     40                              const char* dir, const char* shell) {
     41   passwd_state_t name_passwd_state;
     42   ASSERT_TRUE(file->FindByName(name, &name_passwd_state)) << name;
     43 
     44   passwd& name_passwd = name_passwd_state.passwd_;
     45   EXPECT_STREQ(name, name_passwd.pw_name);
     46   EXPECT_EQ(nullptr, name_passwd.pw_passwd);
     47   EXPECT_EQ(uid, name_passwd.pw_uid);
     48   EXPECT_EQ(gid, name_passwd.pw_gid);
     49   EXPECT_EQ(nullptr, name_passwd.pw_gecos);
     50   EXPECT_STREQ(dir, name_passwd.pw_dir);
     51   EXPECT_STREQ(shell, name_passwd.pw_shell);
     52 
     53   passwd_state_t id_passwd_state;
     54   ASSERT_TRUE(file->FindById(uid, &id_passwd_state)) << uid;
     55 
     56   passwd& id_passwd = id_passwd_state.passwd_;
     57   EXPECT_STREQ(name, id_passwd.pw_name);
     58   EXPECT_EQ(nullptr, id_passwd.pw_passwd);
     59   EXPECT_EQ(uid, id_passwd.pw_uid);
     60   EXPECT_EQ(gid, id_passwd.pw_gid);
     61   EXPECT_EQ(nullptr, id_passwd.pw_gecos);
     62   EXPECT_STREQ(dir, id_passwd.pw_dir);
     63   EXPECT_STREQ(shell, id_passwd.pw_shell);
     64 }
     65 
     66 void FindAndCheckGroupEntry(GroupFile* file, const char* name, gid_t gid) {
     67   group_state_t name_group_state;
     68   ASSERT_TRUE(file->FindByName(name, &name_group_state)) << name;
     69 
     70   group& name_group = name_group_state.group_;
     71   EXPECT_STREQ(name, name_group.gr_name);
     72   EXPECT_EQ(nullptr, name_group.gr_passwd);
     73   EXPECT_EQ(gid, name_group.gr_gid);
     74   EXPECT_EQ(name_group.gr_name, name_group.gr_mem[0]);
     75   EXPECT_EQ(nullptr, name_group.gr_mem[1]);
     76 
     77   group_state_t id_group_state;
     78   ASSERT_TRUE(file->FindById(gid, &id_group_state)) << gid;
     79 
     80   group& id_group = id_group_state.group_;
     81   EXPECT_STREQ(name, id_group.gr_name);
     82   EXPECT_EQ(nullptr, id_group.gr_passwd);
     83   EXPECT_EQ(gid, id_group.gr_gid);
     84   EXPECT_EQ(id_group.gr_name, id_group.gr_mem[0]);
     85   EXPECT_EQ(nullptr, id_group.gr_mem[1]);
     86 }
     87 
     88 #endif  // __BIONIC__
     89 
     90 TEST(grp_pwd_file, passwd_file_one_entry) {
     91 #if defined(__BIONIC__)
     92   TemporaryFile file;
     93   ASSERT_NE(-1, file.fd);
     94   static const char test_string[] = "name:password:1:2:user_info:dir:shell\n";
     95   write(file.fd, test_string, sizeof(test_string) - 1);
     96 
     97   PasswdFile passwd_file(file.filename, nullptr);
     98   FileUnmapper unmapper(passwd_file);
     99 
    100   FindAndCheckPasswdEntry(&passwd_file, "name", 1, 2, "dir", "shell");
    101 
    102   EXPECT_FALSE(passwd_file.FindByName("not_name", nullptr));
    103   EXPECT_FALSE(passwd_file.FindById(3, nullptr));
    104 
    105 #else   // __BIONIC__
    106   GTEST_LOG_(INFO) << "This test does nothing.\n";
    107 #endif  // __BIONIC__
    108 }
    109 
    110 TEST(grp_pwd_file, group_file_one_entry) {
    111 #if defined(__BIONIC__)
    112   TemporaryFile file;
    113   ASSERT_NE(-1, file.fd);
    114   static const char test_string[] = "name:password:1:one,two,three\n";
    115   write(file.fd, test_string, sizeof(test_string) - 1);
    116 
    117   GroupFile group_file(file.filename, nullptr);
    118   FileUnmapper unmapper(group_file);
    119 
    120   FindAndCheckGroupEntry(&group_file, "name", 1);
    121 
    122   EXPECT_FALSE(group_file.FindByName("not_name", nullptr));
    123   EXPECT_FALSE(group_file.FindById(3, nullptr));
    124 
    125 #else   // __BIONIC__
    126   GTEST_LOG_(INFO) << "This test does nothing.\n";
    127 #endif  // __BIONIC__
    128 }
    129 
    130 TEST(grp_pwd_file, passwd_file_many_entries) {
    131 #if defined(__BIONIC__)
    132   TemporaryFile file;
    133   ASSERT_NE(-1, file.fd);
    134   static const char test_string[] =
    135       "first:x:1:2::dir:shell\n"
    136       "abc1::3:4::def:abc\n"
    137       "abc2::5:4:abc::abc\n"
    138       "abc3::7:4:abc:def:\n"
    139       "abc4::9:4:::abc\n"
    140       "abc5::11:4:abc:def:abc\n"
    141       "middle-ish::13:4::/:/system/bin/sh\n"
    142       "abc7::15:4:abc::\n"
    143       "abc8::17:4:::\n"
    144       "abc9::19:4:abc:def:abc\n"
    145       "abc10::21:4:abc:def:abc\n"
    146       "abc11::23:4:abc:def:abc\n"
    147       "abc12::25:4:abc:def:abc\n"
    148       "abc13::27:4:abc:def:abc\n"
    149       "last::29:4::last_user_dir:last_user_shell\n";
    150 
    151   write(file.fd, test_string, sizeof(test_string) - 1);
    152 
    153   PasswdFile passwd_file(file.filename, nullptr);
    154   FileUnmapper unmapper(passwd_file);
    155 
    156   FindAndCheckPasswdEntry(&passwd_file, "first", 1, 2, "dir", "shell");
    157   FindAndCheckPasswdEntry(&passwd_file, "middle-ish", 13, 4, "/", "/system/bin/sh");
    158   FindAndCheckPasswdEntry(&passwd_file, "last", 29, 4, "last_user_dir", "last_user_shell");
    159 
    160   EXPECT_FALSE(passwd_file.FindByName("not_name", nullptr));
    161   EXPECT_FALSE(passwd_file.FindById(50, nullptr));
    162 
    163 #else   // __BIONIC__
    164   GTEST_LOG_(INFO) << "This test does nothing.\n";
    165 #endif  // __BIONIC__
    166 }
    167 
    168 TEST(grp_pwd_file, group_file_many_entries) {
    169 #if defined(__BIONIC__)
    170   TemporaryFile file;
    171   ASSERT_NE(-1, file.fd);
    172   static const char test_string[] =
    173       "first:password:1:one,two,three\n"
    174       "abc:def:2:group1,group2,group3\n"
    175       "abc:def:3:\n"
    176       "abc:def:4:\n"
    177       "abc:def:5:\n"
    178       "middle-ish:def_a_password_that_is_over_32_characters_long:6:\n"
    179       "abc:def:7:\n"
    180       "abc:def:8:\n"
    181       "abc:def:20:\n"
    182       "abc:def:25:\n"
    183       "abc:def:27:\n"
    184       "abc:def:52:\n"
    185       "last::800:\n";
    186 
    187   write(file.fd, test_string, sizeof(test_string) - 1);
    188 
    189   GroupFile group_file(file.filename, nullptr);
    190   FileUnmapper unmapper(group_file);
    191 
    192   FindAndCheckGroupEntry(&group_file, "first", 1);
    193   FindAndCheckGroupEntry(&group_file, "middle-ish", 6);
    194   FindAndCheckGroupEntry(&group_file, "last", 800);
    195 
    196   EXPECT_FALSE(group_file.FindByName("not_name", nullptr));
    197   EXPECT_FALSE(group_file.FindById(799, nullptr));
    198 
    199 #else   // __BIONIC__
    200   GTEST_LOG_(INFO) << "This test does nothing.\n";
    201 #endif  // __BIONIC__
    202 }
    203 
    204 TEST(grp_pwd_file, passwd_file_required_prefix) {
    205 #if defined(__BIONIC__)
    206   TemporaryFile file;
    207   ASSERT_NE(-1, file.fd);
    208   static const char test_string[] =
    209       "name:password:1:2:user_info:dir:shell\n"
    210       "vendor_name:password:3:4:user_info:dir:shell\n";
    211   write(file.fd, test_string, sizeof(test_string) - 1);
    212 
    213   PasswdFile passwd_file(file.filename, "vendor_");
    214   FileUnmapper unmapper(passwd_file);
    215 
    216   EXPECT_FALSE(passwd_file.FindByName("name", nullptr));
    217   EXPECT_FALSE(passwd_file.FindById(1, nullptr));
    218 
    219   FindAndCheckPasswdEntry(&passwd_file, "vendor_name", 3, 4, "dir", "shell");
    220 
    221 #else   // __BIONIC__
    222   GTEST_LOG_(INFO) << "This test does nothing.\n";
    223 #endif  // __BIONIC__
    224 }
    225 
    226 TEST(grp_pwd_file, group_file_required_prefix) {
    227 #if defined(__BIONIC__)
    228   TemporaryFile file;
    229   ASSERT_NE(-1, file.fd);
    230   static const char test_string[] =
    231       "name:password:1:one,two,three\n"
    232       "vendor_name:password:2:one,two,three\n";
    233   write(file.fd, test_string, sizeof(test_string) - 1);
    234 
    235   GroupFile group_file(file.filename, "vendor_");
    236   FileUnmapper unmapper(group_file);
    237 
    238   EXPECT_FALSE(group_file.FindByName("name", nullptr));
    239   EXPECT_FALSE(group_file.FindById(1, nullptr));
    240 
    241   FindAndCheckGroupEntry(&group_file, "vendor_name", 2);
    242 
    243 #else   // __BIONIC__
    244   GTEST_LOG_(INFO) << "This test does nothing.\n";
    245 #endif  // __BIONIC__
    246 }
    247