aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-11-28 20:49:17 +0100
committerEelco Dolstra <edolstra@gmail.com>2022-11-28 20:49:17 +0100
commitff12d1c1a1bb0dcea5a9ac6b8a5036d7e5dc11ca (patch)
tree70b26cf0815e7a09fcf75b85cf0c88bbcfbcd04f
parentfc1458561086a6cf2c1311294c9089785288aea3 (diff)
Check that auto-allocated UIDs don't clash with existing accounts
-rw-r--r--src/libstore/lock.cc14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/libstore/lock.cc b/src/libstore/lock.cc
index 7459d837d..2858137d6 100644
--- a/src/libstore/lock.cc
+++ b/src/libstore/lock.cc
@@ -127,13 +127,10 @@ struct AutoUserLock : UserLock
{
settings.requireExperimentalFeature(Xp::AutoAllocateUids);
assert(settings.startId > 0);
- assert(settings.startId % maxIdsPerBuild == 0);
assert(settings.uidCount % maxIdsPerBuild == 0);
assert((uint64_t) settings.startId + (uint64_t) settings.uidCount <= std::numeric_limits<uid_t>::max());
assert(nrIds <= maxIdsPerBuild);
- // FIXME: check whether the id range overlaps any known users
-
createDirs(settings.nixStateDir + "/userpool2");
size_t nrSlots = settings.uidCount / maxIdsPerBuild;
@@ -150,11 +147,18 @@ struct AutoUserLock : UserLock
throw SysError("opening user lock '%s'", fnUserLock);
if (lockFile(fd.get(), ltWrite, false)) {
+
+ auto firstUid = settings.startId + i * maxIdsPerBuild;
+
+ auto pw = getpwuid(firstUid);
+ if (pw)
+ throw Error("auto-allocated UID %d clashes with existing user account '%s'", firstUid, pw->pw_name);
+
auto lock = std::make_unique<AutoUserLock>();
lock->fdUserLock = std::move(fd);
- lock->firstUid = settings.startId + i * maxIdsPerBuild;
+ lock->firstUid = firstUid;
if (useChroot)
- lock->firstGid = lock->firstUid;
+ lock->firstGid = firstUid;
else {
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
if (!gr)