1 // Copyright 2010 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "utils/passwd.hpp" 30 31 extern "C" { 32 #include <sys/wait.h> 33 34 #include <pwd.h> 35 #include <unistd.h> 36 } 37 38 #include <cstdlib> 39 #include <stdexcept> 40 41 #include <atf-c++.hpp> 42 43 namespace passwd_ns = utils::passwd; 44 45 46 ATF_TEST_CASE_WITHOUT_HEAD(user__public_fields); 47 ATF_TEST_CASE_BODY(user__public_fields) 48 { 49 const passwd_ns::user user("the-name", 1, 2); 50 ATF_REQUIRE_EQ("the-name", user.name); 51 ATF_REQUIRE_EQ(1, user.uid); 52 ATF_REQUIRE_EQ(2, user.gid); 53 } 54 55 56 ATF_TEST_CASE_WITHOUT_HEAD(user__is_root__true); 57 ATF_TEST_CASE_BODY(user__is_root__true) 58 { 59 const passwd_ns::user user("i-am-root", 0, 10); 60 ATF_REQUIRE(user.is_root()); 61 } 62 63 64 ATF_TEST_CASE_WITHOUT_HEAD(user__is_root__false); 65 ATF_TEST_CASE_BODY(user__is_root__false) 66 { 67 const passwd_ns::user user("i-am-not-root", 123, 10); 68 ATF_REQUIRE(!user.is_root()); 69 } 70 71 72 ATF_TEST_CASE_WITHOUT_HEAD(current_user); 73 ATF_TEST_CASE_BODY(current_user) 74 { 75 const passwd_ns::user user = passwd_ns::current_user(); 76 ATF_REQUIRE_EQ(::getuid(), user.uid); 77 ATF_REQUIRE_EQ(::getgid(), user.gid); 78 } 79 80 81 ATF_TEST_CASE_WITHOUT_HEAD(current_user__fake); 82 ATF_TEST_CASE_BODY(current_user__fake) 83 { 84 const passwd_ns::user new_user("someone-else", ::getuid() + 1, 0); 85 passwd_ns::set_current_user_for_testing(new_user); 86 87 const passwd_ns::user user = passwd_ns::current_user(); 88 ATF_REQUIRE(::getuid() != user.uid); 89 ATF_REQUIRE_EQ(new_user.uid, user.uid); 90 } 91 92 93 ATF_TEST_CASE_WITHOUT_HEAD(find_user_by_name__ok); 94 ATF_TEST_CASE_BODY(find_user_by_name__ok) 95 { 96 const struct ::passwd* pw = ::getpwuid(::getuid()); 97 ATF_REQUIRE(pw != NULL); 98 99 const passwd_ns::user user = passwd_ns::find_user_by_name(pw->pw_name); 100 ATF_REQUIRE_EQ(::getuid(), user.uid); 101 ATF_REQUIRE_EQ(::getgid(), user.gid); 102 ATF_REQUIRE_EQ(pw->pw_name, user.name); 103 } 104 105 106 ATF_TEST_CASE_WITHOUT_HEAD(find_user_by_name__fail); 107 ATF_TEST_CASE_BODY(find_user_by_name__fail) 108 { 109 ATF_REQUIRE_THROW_RE(std::runtime_error, "Failed.*user 'i-do-not-exist'", 110 passwd_ns::find_user_by_name("i-do-not-exist")); 111 } 112 113 114 ATF_TEST_CASE_WITHOUT_HEAD(find_user_by_name__fake); 115 ATF_TEST_CASE_BODY(find_user_by_name__fake) 116 { 117 std::vector< passwd_ns::user > users; 118 users.push_back(passwd_ns::user("myself2", 20, 40)); 119 users.push_back(passwd_ns::user("myself1", 10, 15)); 120 users.push_back(passwd_ns::user("myself3", 30, 60)); 121 passwd_ns::set_mock_users_for_testing(users); 122 123 const passwd_ns::user user = passwd_ns::find_user_by_name("myself1"); 124 ATF_REQUIRE_EQ(10, user.uid); 125 ATF_REQUIRE_EQ(15, user.gid); 126 ATF_REQUIRE_EQ("myself1", user.name); 127 128 ATF_REQUIRE_THROW_RE(std::runtime_error, "Failed.*user 'root'", 129 passwd_ns::find_user_by_name("root")); 130 } 131 132 133 ATF_TEST_CASE_WITHOUT_HEAD(find_user_by_uid__ok); 134 ATF_TEST_CASE_BODY(find_user_by_uid__ok) 135 { 136 const passwd_ns::user user = passwd_ns::find_user_by_uid(::getuid()); 137 ATF_REQUIRE_EQ(::getuid(), user.uid); 138 ATF_REQUIRE_EQ(::getgid(), user.gid); 139 140 const struct ::passwd* pw = ::getpwuid(::getuid()); 141 ATF_REQUIRE(pw != NULL); 142 ATF_REQUIRE_EQ(pw->pw_name, user.name); 143 } 144 145 146 ATF_TEST_CASE_WITHOUT_HEAD(find_user_by_uid__fake); 147 ATF_TEST_CASE_BODY(find_user_by_uid__fake) 148 { 149 std::vector< passwd_ns::user > users; 150 users.push_back(passwd_ns::user("myself2", 20, 40)); 151 users.push_back(passwd_ns::user("myself1", 10, 15)); 152 users.push_back(passwd_ns::user("myself3", 30, 60)); 153 passwd_ns::set_mock_users_for_testing(users); 154 155 const passwd_ns::user user = passwd_ns::find_user_by_uid(10); 156 ATF_REQUIRE_EQ(10, user.uid); 157 ATF_REQUIRE_EQ(15, user.gid); 158 ATF_REQUIRE_EQ("myself1", user.name); 159 160 ATF_REQUIRE_THROW_RE(std::runtime_error, "Failed.*user.*UID 0", 161 passwd_ns::find_user_by_uid(0)); 162 } 163 164 165 ATF_INIT_TEST_CASES(tcs) 166 { 167 ATF_ADD_TEST_CASE(tcs, user__public_fields); 168 ATF_ADD_TEST_CASE(tcs, user__is_root__true); 169 ATF_ADD_TEST_CASE(tcs, user__is_root__false); 170 171 ATF_ADD_TEST_CASE(tcs, current_user); 172 ATF_ADD_TEST_CASE(tcs, current_user__fake); 173 174 ATF_ADD_TEST_CASE(tcs, find_user_by_name__ok); 175 ATF_ADD_TEST_CASE(tcs, find_user_by_name__fail); 176 ATF_ADD_TEST_CASE(tcs, find_user_by_name__fake); 177 ATF_ADD_TEST_CASE(tcs, find_user_by_uid__ok); 178 ATF_ADD_TEST_CASE(tcs, find_user_by_uid__fake); 179 } 180