Skip to content

Commit effa88f

Browse files
committed
Add referrer checks for access status
1 parent c5f8a40 commit effa88f

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/libstore/local-store.cc

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -858,11 +858,11 @@ StorePathSet LocalStore::queryAllValidPaths()
858858
}
859859

860860

861-
void LocalStore::queryReferrers(State & state, const StorePath & path, StorePathSet & referrers)
861+
void LocalStore::queryReferrers(State & state, const StorePath & path, StorePathSet & referrers, bool accessCheck)
862862
{
863863
auto useQueryReferrers(state.stmts->QueryReferrers.use()(printStorePath(path)));
864864

865-
if (!canAccess(path)) throw AccessDenied("Access Denied");
865+
if (accessCheck && !canAccess(path)) throw AccessDenied("Access Denied");
866866

867867
while (useQueryReferrers.next())
868868
referrers.insert(parseStorePath(useQueryReferrers.getStr(0)));
@@ -1086,7 +1086,7 @@ void LocalStore::setCurrentAccessStatus(const Path & path, const LocalStore::Acc
10861086

10871087
auto info = promise.get_future().get();
10881088

1089-
if (info){
1089+
if (info) {
10901090
for (auto reference : info->references) {
10911091
if (reference == storePath) continue;
10921092
auto otherStatus = getCurrentAccessStatus(printStorePath(reference));
@@ -1103,6 +1103,28 @@ void LocalStore::setCurrentAccessStatus(const Path & path, const LocalStore::Acc
11031103
}
11041104
}
11051105
}
1106+
1107+
StorePathSet referrers;
1108+
retrySQLite<void>([&]() {
1109+
auto state(_state.lock());
1110+
queryReferrers(*state, storePath, referrers, false);
1111+
});
1112+
1113+
for (auto referrer : referrers) {
1114+
if (referrer == storePath) continue;
1115+
auto otherStatus = getCurrentAccessStatus(printStorePath(referrer));
1116+
if (!status.isProtected) continue;
1117+
if (!otherStatus.isProtected)
1118+
throw AccessDenied("can not make %s protected because it is referenced by a non-protected path %s", path, printStorePath(referrer));
1119+
std::vector<AccessControlEntity> difference;
1120+
std::set_difference(otherStatus.entities.begin(), otherStatus.entities.end(), status.entities.begin(), status.entities.end(),std::inserter(difference, difference.begin()));
1121+
1122+
if (! difference.empty()) {
1123+
std::string entities;
1124+
for (auto entity : difference) entities += ACL::printTag(entity) + ", ";
1125+
throw AccessDenied("can not deny %s access to %s because it is referenced by a path %s to which they do not have access", entities.substr(0, entities.size()-2), path, printStorePath(referrer));
1126+
}
1127+
}
11061128
}
11071129
}
11081130

src/libstore/local-store.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ private:
371371

372372
// Internal versions that are not wrapped in retry_sqlite.
373373
bool isValidPath_(State & state, const StorePath & path);
374-
void queryReferrers(State & state, const StorePath & path, StorePathSet & referrers);
374+
void queryReferrers(State & state, const StorePath & path, StorePathSet & referrers, bool accessCheck = true);
375375

376376
/**
377377
* Add signatures to a ValidPathInfo or Realisation using the secret keys

0 commit comments

Comments
 (0)