mirror of
https://github.com/NixOS/nix.git
synced 2025-12-11 19:41:04 +01:00
Merge pull request #14723 from NixOS/peer-info
daemon.cc: Clean up PeerInfo by using std::optional
This commit is contained in:
commit
a95580e468
1 changed files with 35 additions and 32 deletions
|
|
@ -174,22 +174,23 @@ static bool matchUser(std::string_view user, const struct group & gr)
|
|||
*
|
||||
* Otherwise: No.
|
||||
*/
|
||||
static bool matchUser(const std::string & user, const std::string & group, const Strings & users)
|
||||
static bool
|
||||
matchUser(const std::optional<std::string> & user, const std::optional<std::string> & group, const Strings & users)
|
||||
{
|
||||
if (find(users.begin(), users.end(), "*") != users.end())
|
||||
return true;
|
||||
|
||||
if (find(users.begin(), users.end(), user) != users.end())
|
||||
if (user && find(users.begin(), users.end(), *user) != users.end())
|
||||
return true;
|
||||
|
||||
for (auto & i : users)
|
||||
if (i.substr(0, 1) == "@") {
|
||||
if (group == i.substr(1))
|
||||
if (group && *group == i.substr(1))
|
||||
return true;
|
||||
struct group * gr = getgrnam(i.c_str() + 1);
|
||||
if (!gr)
|
||||
continue;
|
||||
if (matchUser(user, *gr))
|
||||
if (user && matchUser(*user, *gr))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -198,12 +199,9 @@ static bool matchUser(const std::string & user, const std::string & group, const
|
|||
|
||||
struct PeerInfo
|
||||
{
|
||||
bool pidKnown;
|
||||
pid_t pid;
|
||||
bool uidKnown;
|
||||
uid_t uid;
|
||||
bool gidKnown;
|
||||
gid_t gid;
|
||||
std::optional<pid_t> pid;
|
||||
std::optional<uid_t> uid;
|
||||
std::optional<gid_t> gid;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -211,7 +209,7 @@ struct PeerInfo
|
|||
*/
|
||||
static PeerInfo getPeerInfo(int remote)
|
||||
{
|
||||
PeerInfo peer = {false, 0, false, 0, false, 0};
|
||||
PeerInfo peer;
|
||||
|
||||
#if defined(SO_PEERCRED)
|
||||
|
||||
|
|
@ -221,9 +219,11 @@ static PeerInfo getPeerInfo(int remote)
|
|||
ucred cred;
|
||||
# endif
|
||||
socklen_t credLen = sizeof(cred);
|
||||
if (getsockopt(remote, SOL_SOCKET, SO_PEERCRED, &cred, &credLen) == -1)
|
||||
throw SysError("getting peer credentials");
|
||||
peer = {true, cred.pid, true, cred.uid, true, cred.gid};
|
||||
if (getsockopt(remote, SOL_SOCKET, SO_PEERCRED, &cred, &credLen) == 0) {
|
||||
peer.pid = cred.pid;
|
||||
peer.uid = cred.uid;
|
||||
peer.gid = cred.gid;
|
||||
}
|
||||
|
||||
#elif defined(LOCAL_PEERCRED)
|
||||
|
||||
|
|
@ -233,9 +233,8 @@ static PeerInfo getPeerInfo(int remote)
|
|||
|
||||
xucred cred;
|
||||
socklen_t credLen = sizeof(cred);
|
||||
if (getsockopt(remote, SOL_LOCAL, LOCAL_PEERCRED, &cred, &credLen) == -1)
|
||||
throw SysError("getting peer credentials");
|
||||
peer = {false, 0, true, cred.cr_uid, false, 0};
|
||||
if (getsockopt(remote, SOL_LOCAL, LOCAL_PEERCRED, &cred, &credLen) == 0)
|
||||
peer.uid = cred.cr_uid;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -266,15 +265,19 @@ static ref<Store> openUncachedStore()
|
|||
*
|
||||
* If the potential client is not allowed to talk to us, we throw an `Error`.
|
||||
*/
|
||||
static std::pair<TrustedFlag, std::string> authPeer(const PeerInfo & peer)
|
||||
static std::pair<TrustedFlag, std::optional<std::string>> authPeer(const PeerInfo & peer)
|
||||
{
|
||||
TrustedFlag trusted = NotTrusted;
|
||||
|
||||
struct passwd * pw = peer.uidKnown ? getpwuid(peer.uid) : 0;
|
||||
std::string user = pw ? pw->pw_name : std::to_string(peer.uid);
|
||||
auto pw = peer.uid ? getpwuid(*peer.uid) : nullptr;
|
||||
auto user = pw ? std::optional<std::string>(pw->pw_name)
|
||||
: peer.uid ? std::optional(std::to_string(*peer.uid))
|
||||
: std::nullopt;
|
||||
|
||||
struct group * gr = peer.gidKnown ? getgrgid(peer.gid) : 0;
|
||||
std::string group = gr ? gr->gr_name : std::to_string(peer.gid);
|
||||
auto gr = peer.gid ? getgrgid(*peer.gid) : 0;
|
||||
auto group = gr ? std::optional<std::string>(gr->gr_name)
|
||||
: peer.gid ? std::optional(std::to_string(*peer.gid))
|
||||
: std::nullopt;
|
||||
|
||||
const Strings & trustedUsers = authorizationSettings.trustedUsers;
|
||||
const Strings & allowedUsers = authorizationSettings.allowedUsers;
|
||||
|
|
@ -283,7 +286,7 @@ static std::pair<TrustedFlag, std::string> authPeer(const PeerInfo & peer)
|
|||
trusted = Trusted;
|
||||
|
||||
if ((!trusted && !matchUser(user, group, allowedUsers)) || group == settings.buildUsersGroup)
|
||||
throw Error("user '%1%' is not allowed to connect to the Nix daemon", user);
|
||||
throw Error("user '%1%' is not allowed to connect to the Nix daemon", user.value_or("<unknown>"));
|
||||
|
||||
return {trusted, std::move(user)};
|
||||
}
|
||||
|
|
@ -360,23 +363,23 @@ static void daemonLoop(std::optional<TrustedFlag> forceTrustClientOpt)
|
|||
|
||||
unix::closeOnExec(remote.get());
|
||||
|
||||
PeerInfo peer{.pidKnown = false};
|
||||
PeerInfo peer;
|
||||
TrustedFlag trusted;
|
||||
std::string user;
|
||||
std::optional<std::string> userName;
|
||||
|
||||
if (forceTrustClientOpt)
|
||||
trusted = *forceTrustClientOpt;
|
||||
else {
|
||||
peer = getPeerInfo(remote.get());
|
||||
auto [_trusted, _user] = authPeer(peer);
|
||||
auto [_trusted, _userName] = authPeer(peer);
|
||||
trusted = _trusted;
|
||||
user = _user;
|
||||
userName = _userName;
|
||||
};
|
||||
|
||||
printInfo(
|
||||
(std::string) "accepted connection from pid %1%, user %2%" + (trusted ? " (trusted)" : ""),
|
||||
peer.pidKnown ? std::to_string(peer.pid) : "<unknown>",
|
||||
peer.uidKnown ? user : "<unknown>");
|
||||
peer.pid ? std::to_string(*peer.pid) : "<unknown>",
|
||||
userName.value_or("<unknown>"));
|
||||
|
||||
// Fork a child to handle the connection.
|
||||
ProcessOptions options;
|
||||
|
|
@ -396,8 +399,8 @@ static void daemonLoop(std::optional<TrustedFlag> forceTrustClientOpt)
|
|||
setSigChldAction(false);
|
||||
|
||||
// For debugging, stuff the pid into argv[1].
|
||||
if (peer.pidKnown && savedArgv[1]) {
|
||||
auto processName = std::to_string(peer.pid);
|
||||
if (peer.pid && savedArgv[1]) {
|
||||
auto processName = std::to_string(*peer.pid);
|
||||
strncpy(savedArgv[1], processName.c_str(), strlen(savedArgv[1]));
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +417,7 @@ static void daemonLoop(std::optional<TrustedFlag> forceTrustClientOpt)
|
|||
} catch (Error & error) {
|
||||
auto ei = error.info();
|
||||
// FIXME: add to trace?
|
||||
ei.msg = HintFmt("error processing connection: %1%", ei.msg.str());
|
||||
ei.msg = HintFmt("while processing connection: %1%", ei.msg.str());
|
||||
logError(ei);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue