From 43acd01979039b248cb7f033b82e36d778d0ebec Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 27 Sep 2014 19:45:30 +0200 Subject: [PATCH 1/1] allow fetcher setup without directory creation apt-get download and changelog as well as apt-helper reuse the acquire system for their own proposes without requiring the directories the fetcher wants to create, which is a problem if you run them as non-root and the directories do not exist as it greets you with: E: Archives directory /var/cache/apt/archives/partial is missing. - Acquire (13: Permission denied) Closes: 762898 --- apt-pkg/acquire.cc | 30 ++++++++++++++----------- apt-pkg/acquire.h | 5 ++++- cmdline/apt-get.cc | 9 ++++---- cmdline/apt-helper.cc | 3 ++- test/integration/test-apt-get-changelog | 6 +++++ test/integration/test-apt-get-download | 27 ++++++++++++++++++++-- test/integration/test-apt-helper | 14 ++++++------ 7 files changed, 66 insertions(+), 28 deletions(-) diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index f0a88a538..8119e4487 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -73,23 +73,27 @@ pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), Queues(0), Wor // --------------------------------------------------------------------- /* Do everything needed to be a complete Acquire object and report the success (or failure) back so the user knows that something is wrong… */ -bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock) +bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock, + bool const createDirectories) { Log = Progress; // check for existence and possibly create auxiliary directories - string const listDir = _config->FindDir("Dir::State::lists"); - string const partialListDir = listDir + "partial/"; - string const archivesDir = _config->FindDir("Dir::Cache::Archives"); - string const partialArchivesDir = archivesDir + "partial/"; - - if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false && - CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false) - return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str()); - - if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::Cache"), partialArchivesDir) == false && - CreateAPTDirectoryIfNeeded(archivesDir, partialArchivesDir) == false) - return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str()); + if (createDirectories == true) + { + string const listDir = _config->FindDir("Dir::State::lists"); + string const partialListDir = listDir + "partial/"; + string const archivesDir = _config->FindDir("Dir::Cache::Archives"); + string const partialArchivesDir = archivesDir + "partial/"; + + if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false && + CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false) + return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str()); + + if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::Cache"), partialArchivesDir) == false && + CreateAPTDirectoryIfNeeded(archivesDir, partialArchivesDir) == false) + return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str()); + } if (Lock.empty() == true || _config->FindB("Debug::NoLocking", false) == true) return true; diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index a92ecc24c..7bceb4323 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -352,8 +352,11 @@ class pkgAcquire * \param Lock defines a lock file that should be acquired to ensure * only one Acquire class is in action at the time or an empty string * if no lock file should be used. + * \param createDirectories can be used to disable the creation of directories, + * e.g. if the fetcher is used with different directories later on */ - bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = ""); + bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = "", + bool const createDirectories = true); void SetLog(pkgAcquireStatus *Progress) { Log = Progress; } diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index a5cafc39d..6d03c7eec 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -626,14 +626,14 @@ static bool DoDownload(CommandLine &CmdL) APT::CacheSetHelper helper(c0out); APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper); + CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0)); pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat) == false) + if (Fetcher.Setup(&Stat, "", false) == false) return false; pkgRecords Recs(Cache); @@ -1536,7 +1536,7 @@ static bool DoChangelog(CommandLine &CmdL) APT::CacheSetHelper helper(c0out); APT::VersionList verset = APT::VersionList::FromCommandLine(Cache, - CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper); + CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper); if (verset.empty() == true) return false; pkgAcquire Fetcher; @@ -1551,7 +1551,8 @@ static bool DoChangelog(CommandLine &CmdL) } AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - Fetcher.Setup(&Stat); + if (Fetcher.Setup(&Stat, "",false) == false) + return false; bool const downOnly = _config->FindB("APT::Get::Download-Only", false); diff --git a/cmdline/apt-helper.cc b/cmdline/apt-helper.cc index dd43ea1bc..b89df61d6 100644 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@ -51,7 +51,8 @@ static bool DoDownloadFile(CommandLine &CmdL) pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); - Fetcher.Setup(&Stat); + if (Fetcher.Setup(&Stat, "", false) == false) + return false; std::string download_uri = CmdL.FileList[1]; std::string targetfile = CmdL.FileList[2]; std::string hash; diff --git a/test/integration/test-apt-get-changelog b/test/integration/test-apt-get-changelog index 4ee113482..02d6c39ab 100755 --- a/test/integration/test-apt-get-changelog +++ b/test/integration/test-apt-get-changelog @@ -13,6 +13,12 @@ setupaptarchive --no-update changetowebserver testsuccess aptget update +# simulate normal user with non-existent root-owned directories +rm -rf rootdir/var/cache/apt/archives/ +mkdir rootdir/var/cache/apt/archives/ +addtrap 'prefix' "chmod -f -R +w $PWD/rootdir/var/cache/apt/archives || true;" +chmod -R -w rootdir/var/cache/apt/archives + echo 'Apt::Changelogs::Server "http://localhost:8080/";' > rootdir/etc/apt/apt.conf.d/changelog.conf testequal "'http://localhost:8080//pool/apt_1.0/changelog'" aptget changelog apt --print-uris diff --git a/test/integration/test-apt-get-download b/test/integration/test-apt-get-download index be3144e1f..58ed44f8f 100755 --- a/test/integration/test-apt-get-download +++ b/test/integration/test-apt-get-download @@ -20,10 +20,19 @@ testdownload() { fi msgtest "Test download of package file $1 with" "$APT" testsuccess --nomsg aptget download ${APT} - testsuccess test -f $1 - rm $1 + testsuccess test -f "$1" + rm -f "$1" } +# normal case as "root" +testdownload apt_2.0_all.deb apt + +# simulate normal user with non-existent root-owned directories +rm -rf rootdir/var/cache/apt/archives/ +mkdir rootdir/var/cache/apt/archives/ +addtrap 'prefix' "chmod -f -R +w $PWD/rootdir/var/cache/apt/archives || true;" +chmod -R -w rootdir/var/cache/apt/archives + # normal case(es) testdownload apt_1.0_all.deb apt stable testdownload apt_2.0_all.deb apt @@ -45,3 +54,17 @@ rm -f apt_1.0_all.deb apt_2.0_all.deb testsuccess aptget download apt apt apt/unstable apt=2.0 testsuccess test -s apt_2.0_all.deb +# restore "root" rights +chmod -f -R +w $PWD/rootdir/var/cache/apt/archives +rm -rf rootdir/var/cache/apt/archives/ + +# file: debs aren't copied to archives, so change to http which obviously are +changetowebserver +testsuccess aptget update + +# test with already stored deb +testsuccess aptget install -d apt +testsuccess test -s rootdir/var/cache/apt/archives/apt_2.0_all.deb +mv aptarchive/pool/apt_2.0_all.deb aptarchive/pool/apt_2.0_all.deb.gone +testdownload apt_2.0_all.deb apt +mv aptarchive/pool/apt_2.0_all.deb.gone aptarchive/pool/apt_2.0_all.deb diff --git a/test/integration/test-apt-helper b/test/integration/test-apt-helper index c749224ca..42c40bb9e 100755 --- a/test/integration/test-apt-helper +++ b/test/integration/test-apt-helper @@ -5,30 +5,30 @@ TESTDIR=$(readlink -f $(dirname $0)) . $TESTDIR/framework setupenvironment -configarchitecture "i386" +configarchitecture 'i386' changetohttpswebserver test_apt_helper_download() { - echo "foo" > aptarchive/foo + echo 'foo' > aptarchive/foo - msgtest 'apt-file download-file md5sum' + msgtest 'apt-file download-file' 'md5sum' apthelper -qq download-file http://localhost:8080/foo foo2 MD5Sum:d3b07384d113edec49eaa6238ad5ff00 && msgpass || msgfail testfileequal foo2 'foo' - msgtest 'apt-file download-file sha1' + msgtest 'apt-file download-file' 'sha1' apthelper -qq download-file http://localhost:8080/foo foo1 SHA1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 && msgpass || msgfail testfileequal foo1 'foo' - msgtest 'apt-file download-file sha256' + msgtest 'apt-file download-file' 'sha256' apthelper -qq download-file http://localhost:8080/foo foo3 SHA256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c && msgpass || msgfail testfileequal foo3 'foo' - msgtest 'apt-file download-file no-hash' + msgtest 'apt-file download-file' 'no-hash' apthelper -qq download-file http://localhost:8080/foo foo4 && msgpass || msgfail testfileequal foo4 'foo' - msgtest 'apt-file download-file wrong hash' + msgtest 'apt-file download-file' 'wrong hash' if ! apthelper -qq download-file http://localhost:8080/foo foo5 MD5Sum:aabbcc 2>&1 2> download.stderr; then msgpass else -- 2.45.2