Line data Source code
1 : // Copyright (c) 2018-2024 Made to Order Software Corp. All Rights Reserved 2 : // 3 : // https://snapwebsites.org/project/snapdev 4 : // contact@m2osw.com 5 : // 6 : // This program is free software: you can redistribute it and/or modify 7 : // it under the terms of the GNU General Public License as published by 8 : // the Free Software Foundation, either version 3 of the License, or 9 : // (at your option) any later version. 10 : // 11 : // This program is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : // 16 : // You should have received a copy of the GNU General Public License 17 : // along with this program. If not, see <https://www.gnu.org/licenses/>. 18 : 19 : /** \file 20 : * \brief Verify that the chownnm() function works. 21 : * 22 : * This file implements tests for the chownnm() function. 23 : */ 24 : 25 : // self 26 : // 27 : #include <snapdev/chownnm.h> 28 : 29 : #include <snapdev/file_contents.h> 30 : #include <snapdev/user_groups.h> 31 : 32 : #include "catch_main.h" 33 : 34 : 35 : // C++ lib 36 : // 37 : #include <set> 38 : 39 : 40 : // last include 41 : // 42 : #include <snapdev/poison.h> 43 : 44 : 45 : 46 : 47 2 : CATCH_TEST_CASE("chownnm", "[os]") 48 : { 49 2 : CATCH_START_SECTION("chownnm: change group") 50 : { 51 1 : struct group const * grp(getgrnam("snapwebsites")); 52 1 : if(grp == nullptr) 53 : { 54 0 : std::cerr << "warning: skipping change group test because \"snapwebsites\" group doesn't exist.\n"; 55 : } 56 : else 57 : { 58 1 : char const * user(getenv("USER")); 59 1 : bool permitted(true); 60 1 : CATCH_REQUIRE(user != nullptr); 61 1 : if(strcmp(user, "root") != 0) 62 : { 63 3 : std::set<std::string> our_groups(snapdev::user_group_names<std::set<std::string>>(user)); 64 1 : if(our_groups.find("snapwebsites") == our_groups.end()) 65 : { 66 0 : permitted = false; 67 0 : std::cerr << "error: we expect the tester to be the \"root\" user or part of the \"snapwebsites\" group to run this test section.\n"; 68 : } 69 1 : } 70 : 71 1 : if(permitted) 72 : { 73 1 : std::string const filename(SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/group-test.txt"); 74 1 : snapdev::file_contents system_groups(filename); 75 1 : system_groups.contents("test file--testing changing group\n"); 76 1 : system_groups.write_all(); 77 : 78 1 : struct stat st; 79 1 : CATCH_REQUIRE(stat(filename.c_str(), &st) == 0); 80 1 : if(st.st_gid == grp->gr_gid) 81 : { 82 0 : std::cerr << "warning: your default group is \"snapwebsites\" so the test is not going to change anything\n"; 83 : } 84 : 85 1 : CATCH_REQUIRE(snapdev::chownnm(filename, std::string(), "snapwebsites") == 0); 86 1 : struct stat verify; 87 1 : CATCH_REQUIRE(stat(filename.c_str(), &verify) == 0); 88 1 : CATCH_REQUIRE(verify.st_gid == grp->gr_gid); 89 : 90 : // restore former group 91 : // 92 1 : struct group * org_group(getgrgid(st.st_gid)); 93 1 : CATCH_REQUIRE(org_group != nullptr); 94 1 : CATCH_REQUIRE(snapdev::chownnm(filename, std::string(), org_group->gr_name) == 0); 95 1 : CATCH_REQUIRE(stat(filename.c_str(), &verify) == 0); 96 1 : CATCH_REQUIRE(verify.st_gid == org_group->gr_gid); 97 1 : } 98 : } 99 : } 100 2 : CATCH_END_SECTION() 101 : 102 2 : CATCH_START_SECTION("chownnm: change owner") 103 : { 104 : // TODO: this is contradictory since we can't run this test as root... 105 : // 106 1 : char const * user(getenv("USER")); 107 1 : CATCH_REQUIRE(user != nullptr); 108 1 : struct passwd const * pwd(getpwnam("snapwebsites")); 109 1 : if(pwd == nullptr 110 1 : || strcmp(user, "root") != 0) 111 : { 112 1 : std::cerr << "warning: skipping change owner test because your are not root and/or the \"snapwebsites\" user doesn't exist.\n"; 113 : } 114 : else 115 : { 116 0 : std::string const filename(SNAP_CATCH2_NAMESPACE::g_tmp_dir() + "/owner-test.txt"); 117 0 : snapdev::file_contents system_groups(filename); 118 0 : system_groups.contents("test file--testing changing owner\n"); 119 0 : system_groups.write_all(); 120 : 121 0 : struct stat st; 122 0 : CATCH_REQUIRE(stat(filename.c_str(), &st) == 0); 123 0 : if(st.st_uid == pwd->pw_uid) 124 : { 125 : // this should not happen since we tested above that we are 126 : // root to properly run this test (otherwise we bail out) 127 : // 128 0 : std::cerr << "warning: your default owner is \"snapwebsites\" so the test is not going to change anything\n"; 129 : } 130 : 131 0 : CATCH_REQUIRE(snapdev::chownnm(filename, "snapwebsites", std::string()) == 0); 132 0 : struct stat verify; 133 0 : CATCH_REQUIRE(stat(filename.c_str(), &verify) == 0); 134 0 : CATCH_REQUIRE(verify.st_uid == pwd->pw_uid); 135 : 136 : // restore former group 137 : // 138 0 : struct passwd * org_owner(getpwuid(st.st_uid)); 139 0 : CATCH_REQUIRE(org_owner != nullptr); 140 0 : CATCH_REQUIRE(snapdev::chownnm(filename, std::string(), org_owner->pw_name) == 0); 141 0 : CATCH_REQUIRE(stat(filename.c_str(), &verify) == 0); 142 0 : CATCH_REQUIRE(verify.st_uid == org_owner->pw_uid); 143 0 : } 144 : } 145 2 : CATCH_END_SECTION() 146 2 : } 147 : 148 : 149 : 150 : // vim: ts=4 sw=4 et