Serenity Operating System
at master 118 lines 3.7 kB view raw
1/* 2 * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/Vector.h> 10#include <pwd.h> 11 12struct PasswdEntry { 13 DeprecatedString name; 14 uid_t uid {}; 15}; 16 17static Vector<PasswdEntry> get_all_passwd_entries() 18{ 19 Vector<PasswdEntry> entries; 20 setpwent(); 21 while (auto* pwd = getpwent()) { 22 entries.append(PasswdEntry { 23 .name = pwd->pw_name, 24 .uid = pwd->pw_uid, 25 }); 26 } 27 return entries; 28} 29 30TEST_CASE(getpwuid_r) 31{ 32 // Verify that all known passwd entries can be found with getpwuid_r() 33 for (auto const& entry : get_all_passwd_entries()) { 34 struct passwd pwd_buffer = {}; 35 char buffer[4096] = {}; 36 struct passwd* result = nullptr; 37 auto rc = getpwuid_r(entry.uid, &pwd_buffer, buffer, sizeof(buffer), &result); 38 EXPECT_EQ(rc, 0); 39 EXPECT_EQ(entry.uid, result->pw_uid); 40 EXPECT_EQ(entry.name, result->pw_name); 41 } 42 43 // Verify that a bogus UID can't be found with getpwuid_r() 44 { 45 struct passwd pwd_buffer = {}; 46 char buffer[4096] = {}; 47 struct passwd* result = nullptr; 48 auto rc = getpwuid_r(99991999, &pwd_buffer, buffer, sizeof(buffer), &result); 49 EXPECT_EQ(rc, ENOENT); 50 EXPECT_EQ(result, nullptr); 51 } 52 53 // Verify that two calls to getpwuid_r() don't clobber each other. 54 { 55 struct passwd pwd_buffer1 = {}; 56 char buffer1[4096] = {}; 57 struct passwd* result1 = nullptr; 58 auto rc1 = getpwuid_r(0, &pwd_buffer1, buffer1, sizeof(buffer1), &result1); 59 EXPECT_EQ(rc1, 0); 60 EXPECT_NE(result1, nullptr); 61 EXPECT_EQ(result1, &pwd_buffer1); 62 63 struct passwd pwd_buffer2 = {}; 64 char buffer2[4096] = {}; 65 struct passwd* result2 = nullptr; 66 auto rc2 = getpwuid_r(0, &pwd_buffer2, buffer2, sizeof(buffer2), &result2); 67 EXPECT_EQ(rc2, 0); 68 EXPECT_NE(result2, nullptr); 69 EXPECT_EQ(result2, &pwd_buffer2); 70 71 EXPECT_NE(result1, result2); 72 } 73} 74 75TEST_CASE(getpwnam_r) 76{ 77 // Verify that all known passwd entries can be found with getpwnam_r() 78 for (auto const& entry : get_all_passwd_entries()) { 79 struct passwd pwd_buffer = {}; 80 char buffer[4096] = {}; 81 struct passwd* result = nullptr; 82 auto rc = getpwnam_r(entry.name.characters(), &pwd_buffer, buffer, sizeof(buffer), &result); 83 EXPECT_EQ(rc, 0); 84 EXPECT_EQ(entry.uid, result->pw_uid); 85 EXPECT_EQ(entry.name, result->pw_name); 86 } 87 88 // Verify that a bogus name can't be found with getpwnam_r() 89 { 90 struct passwd pwd_buffer = {}; 91 char buffer[4096] = {}; 92 struct passwd* result = nullptr; 93 auto rc = getpwnam_r("99991999", &pwd_buffer, buffer, sizeof(buffer), &result); 94 EXPECT_EQ(rc, ENOENT); 95 EXPECT_EQ(result, nullptr); 96 } 97 98 // Verify that two calls to getpwnam_r() don't clobber each other. 99 { 100 struct passwd pwd_buffer1 = {}; 101 char buffer1[4096] = {}; 102 struct passwd* result1 = nullptr; 103 auto rc1 = getpwnam_r("root", &pwd_buffer1, buffer1, sizeof(buffer1), &result1); 104 EXPECT_EQ(rc1, 0); 105 EXPECT_NE(result1, nullptr); 106 EXPECT_EQ(result1, &pwd_buffer1); 107 108 struct passwd pwd_buffer2 = {}; 109 char buffer2[4096] = {}; 110 struct passwd* result2 = nullptr; 111 auto rc2 = getpwnam_r("root", &pwd_buffer2, buffer2, sizeof(buffer2), &result2); 112 EXPECT_EQ(rc2, 0); 113 EXPECT_NE(result2, nullptr); 114 EXPECT_EQ(result2, &pwd_buffer2); 115 116 EXPECT_NE(result1, result2); 117 } 118}