aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories/accounts
diff options
context:
space:
mode:
authorAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2016-01-17 12:21:45 -0800
committerAvatar Saleem Abdulrasool <compnerd@compnerd.org> 2016-01-21 13:09:11 -0800
commit6cc7eb47142dcad1cf277ccf31c38fc53746e45e (patch)
tree6c029356fe6b2a580de4875c1e4201e4881deea9 /paludis/repositories/accounts
parent1e359553c2e5da698318714bd77884da0288f4d8 (diff)
downloadpaludis-6cc7eb47142dcad1cf277ccf31c38fc53746e45e.tar.gz
paludis-6cc7eb47142dcad1cf277ccf31c38fc53746e45e.tar.xz
paludis: POSIX_ME_HARDER accounts repository
POSIX permits an indefinite required buffer size for querying GECOS fields. This is currently used in three locations. Previously, paludis would assume that it could perform a sysconf call to retrieve the requisite buffer size for ensuring that the subsequent GECOS field query would not receive a -ERANGE error. However, as it turns out, this is actually a problem even with GLIBC where the NSS may end up querying a service which has a larger field value for the `struct pwd` (glibc sets the return value to the NSS buffer length, aka 1k, but may end up querying a service which provides a larger response). Use local wrappers which perform the size adjustment to avoid an undersized buffer. Localise the functions which query the various GECOS fields which comprise the persona into util.
Diffstat (limited to 'paludis/repositories/accounts')
-rw-r--r--paludis/repositories/accounts/installed_accounts_id.cc40
1 files changed, 13 insertions, 27 deletions
diff --git a/paludis/repositories/accounts/installed_accounts_id.cc b/paludis/repositories/accounts/installed_accounts_id.cc
index a69b26add..ccc876cf4 100644
--- a/paludis/repositories/accounts/installed_accounts_id.cc
+++ b/paludis/repositories/accounts/installed_accounts_id.cc
@@ -22,6 +22,7 @@
#include <paludis/util/pimp-impl.hh>
#include <paludis/util/config_file.hh>
#include <paludis/util/options.hh>
+#include <paludis/util/persona.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/hashes.hh>
#include <paludis/util/visitor_cast.hh>
@@ -117,44 +118,29 @@ InstalledAccountsID::need_keys_added() const
/* depend upon our primary group */
{
- int pwd_buf_sz(sysconf(_SC_GETPW_R_SIZE_MAX));
- if (-1 == pwd_buf_sz || pwd_buf_sz > 1024 * 128)
- {
- Log::get_instance()->message("accounts.getpw_r_size_max", ll_warning, lc_context) <<
- "Got dodgy value " << pwd_buf_sz << " from sysconf(_SC_GETPW_R_SIZE_MAX)";
- pwd_buf_sz = 1024 * 128;
- }
- std::vector<char> pwd_buf(pwd_buf_sz);
-
struct passwd pwd;
- struct passwd * pwd_result;
+ struct passwd *result;
+ std::vector<char> buffer;
- if (0 == getpwnam_r(stringify(name().package()).c_str(), &pwd, &pwd_buf[0], pwd_buf_sz, &pwd_result))
+ if (0 == getpwnam_r_s(stringify(name().package()).c_str(), buffer, pwd, result) || result == nullptr)
{
- int grp_buf_sz(sysconf(_SC_GETGR_R_SIZE_MAX));
- if (-1 == grp_buf_sz || grp_buf_sz > 1024 * 128)
- {
- Log::get_instance()->message("accounts.getgr_r_size_max", ll_warning, lc_context) <<
- "Got dodgy value " << grp_buf_sz << " from sysconf(_SC_GETPW_R_SIZE_MAX)";
- grp_buf_sz = 1024 * 128;
- }
- std::vector<char> grp_buf(grp_buf_sz);
-
struct group grp;
- struct group * grp_result;
- if (0 == getgrgid_r(pwd.pw_gid, &grp, &grp_buf[0], grp_buf_sz, &grp_result) && nullptr != grp_result)
+ struct group *result;
+ std::vector<char> buffer;
+
+ if (0 == getgrgid_r_s(pwd.pw_gid, buffer, grp, result) && nullptr != result)
{
- /* really we should only do this if the group in question is managed by accounts. users
+ /* really we should only do this if the group in question is managed by accounts. Users
* might have accounts installed by hand with a group that's unmanaged. */
groups->insert(stringify(grp.gr_name));
}
else
- Log::get_instance()->message("accounts.getgrgid_r", ll_warning, lc_context) <<
- "getgrgid_r failed for " << name();
+ Log::get_instance()->message("accounts.getgrgid_r", ll_warning, lc_context)
+ << "getgrgid_r failed for " << name();
}
else
- Log::get_instance()->message("accounts.getpwnam_r", ll_warning, lc_context) <<
- "getpwnam_r failed for " << name();
+ Log::get_instance()->message("accounts.getpwnam_r", ll_warning, lc_context)
+ << "getpwnam_r failed for " << name();
}
/* ...and our secondary groups */