From e4d9b207c20f2051be060a8fd32efe69dae78a80 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 29 Mar 2024 15:40:56 -0400 Subject: [PATCH] Factor out `isRootUser` function --- src/libstore/globals.cc | 3 +-- src/libstore/globals.hh | 3 ++- src/libstore/local-store.cc | 7 ++++--- src/libstore/lock.cc | 5 +++-- src/libstore/profiles.cc | 4 ++-- src/libstore/store-api.cc | 2 +- src/libutil/users.cc | 5 +++++ src/libutil/users.hh | 6 ++++++ src/nix-build/nix-build.cc | 6 ++++-- src/nix-env/nix-env.cc | 2 +- src/nix/main.cc | 2 +- 11 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index fa0938d7b25..306e98e2d9e 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -2,7 +2,6 @@ #include "current-process.hh" #include "archive.hh" #include "args.hh" -#include "users.hh" #include "abstract-setting-to-json.hh" #include "compute-levels.hh" @@ -57,7 +56,7 @@ Settings::Settings() , nixManDir(canonPath(NIX_MAN_DIR)) , nixDaemonSocketFile(canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH))) { - buildUsersGroup = getuid() == 0 ? "nixbld" : ""; + buildUsersGroup = isRootUser() ? "nixbld" : ""; allowSymlinkedStore = getEnv("NIX_IGNORE_SYMLINK_STORE") == "1"; auto sslOverride = getEnv("NIX_SSL_CERT_FILE").value_or(getEnv("SSL_CERT_FILE").value_or("")); diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index e6acf0a4f03..b8958898de1 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -5,6 +5,7 @@ #include "config.hh" #include "environment-variables.hh" #include "experimental-features.hh" +#include "users.hh" #include #include @@ -665,7 +666,7 @@ public: Setting sandboxFallback{this, true, "sandbox-fallback", "Whether to disable sandboxing when the kernel doesn't allow it."}; - Setting requireDropSupplementaryGroups{this, getuid() == 0, "require-drop-supplementary-groups", + Setting requireDropSupplementaryGroups{this, isRootUser(), "require-drop-supplementary-groups", R"( Following the principle of least privilege, Nix will attempt to drop supplementary groups when building with sandboxing. diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 1bbeaa912a6..914f0cbe3d6 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -16,6 +16,7 @@ #include "posix-fs-canonicalise.hh" #include "posix-source-accessor.hh" #include "keys.hh" +#include "users.hh" #include #include @@ -223,7 +224,7 @@ LocalStore::LocalStore(const Params & params) /* Optionally, create directories and set permissions for a multi-user install. */ - if (getuid() == 0 && settings.buildUsersGroup != "") { + if (isRootUser() && settings.buildUsersGroup != "") { mode_t perm = 01775; struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); @@ -573,7 +574,7 @@ void LocalStore::openDB(State & state, bool create) void LocalStore::makeStoreWritable() { #if __linux__ - if (getuid() != 0) return; + if (!isRootUser()) return; /* Check if /nix/store is on a read-only mount. */ struct statvfs stat; if (statvfs(realStoreDir.get().c_str(), &stat) != 0) @@ -1570,7 +1571,7 @@ static void makeMutable(const Path & path) /* Upgrade from schema 6 (Nix 0.15) to schema 7 (Nix >= 1.3). */ void LocalStore::upgradeStore7() { - if (getuid() != 0) return; + if (!isRootUser()) return; printInfo("removing immutable bits from the Nix store (this may take a while)..."); makeMutable(realStoreDir); } diff --git a/src/libstore/lock.cc b/src/libstore/lock.cc index 87f55ce496b..023c74e349b 100644 --- a/src/libstore/lock.cc +++ b/src/libstore/lock.cc @@ -2,6 +2,7 @@ #include "file-system.hh" #include "globals.hh" #include "pathlocks.hh" +#include "users.hh" #include #include @@ -192,10 +193,10 @@ std::unique_ptr acquireUserLock(uid_t nrIds, bool useUserNamespace) bool useBuildUsers() { #if __linux__ - static bool b = (settings.buildUsersGroup != "" || settings.autoAllocateUids) && getuid() == 0; + static bool b = (settings.buildUsersGroup != "" || settings.autoAllocateUids) && isRootUser(); return b; #elif __APPLE__ - static bool b = settings.buildUsersGroup != "" && getuid() == 0; + static bool b = settings.buildUsersGroup != "" && isRootUser(); return b; #else return false; diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index e8b88693d26..73d3976f43a 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -308,7 +308,7 @@ std::string optimisticLockProfile(const Path & profile) Path profilesDir() { auto profileRoot = - (getuid() == 0) + isRootUser() ? rootProfilesDir() : createNixStateDir() + "/profiles"; createDirs(profileRoot); @@ -332,7 +332,7 @@ Path getDefaultProfile() // Backwards compatibiliy measure: Make root's profile available as // `.../default` as it's what NixOS and most of the init scripts expect Path globalProfileLink = settings.nixStateDir + "/profiles/default"; - if (getuid() == 0 && !pathExists(globalProfileLink)) { + if (isRootUser() && !pathExists(globalProfileLink)) { replaceSymlink(profile, globalProfileLink); } return absPath(readLink(profileLink), dirOf(profileLink)); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 4356296d45a..62403e633ca 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -1307,7 +1307,7 @@ std::shared_ptr openFromNonUri(const std::string & uri, const Store::Para #if __linux__ else if (!pathExists(stateDir) && params.empty() - && getuid() != 0 + && !isRootUser() && !getEnv("NIX_STORE_DIR").has_value() && !getEnv("NIX_STATE_DIR").has_value()) { diff --git a/src/libutil/users.cc b/src/libutil/users.cc index 95a641322a4..8cb3db43494 100644 --- a/src/libutil/users.cc +++ b/src/libutil/users.cc @@ -113,4 +113,9 @@ std::string expandTilde(std::string_view path) return std::string(path); } + +bool isRootUser() { + return getuid() == 0; +} + } diff --git a/src/libutil/users.hh b/src/libutil/users.hh index cecbb8bfb9e..449e5bbe924 100644 --- a/src/libutil/users.hh +++ b/src/libutil/users.hh @@ -55,4 +55,10 @@ Path createNixStateDir(); */ std::string expandTilde(std::string_view path); + +/** + * Is the current user UID 0 on Unix? + */ +bool isRootUser(); + } diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index 35eef5b8342..8276be8e8bc 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -24,6 +24,7 @@ #include "common-eval-args.hh" #include "attr-path.hh" #include "legacy.hh" +#include "users.hh" using namespace nix; using namespace std::string_literals; @@ -572,8 +573,9 @@ static void main_nix_build(int argc, char * * argv) "BASH=%5%; " "set +e; " R"s([ -n "$PS1" -a -z "$NIX_SHELL_PRESERVE_PROMPT" ] && )s" + - (getuid() == 0 ? R"s(PS1='\n\[\033[1;31m\][nix-shell:\w]\$\[\033[0m\] '; )s" - : R"s(PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s") + + (isRootUser() + ? R"s(PS1='\n\[\033[1;31m\][nix-shell:\w]\$\[\033[0m\] '; )s" + : R"s(PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s") + "if [ \"$(type -t runHook)\" = function ]; then runHook shellHook; fi; " "unset NIX_ENFORCE_PURITY; " "shopt -u nullglob; " diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 9288d89a1a8..177344044a6 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -1414,7 +1414,7 @@ static int main_nix_env(int argc, char * * argv) replaceSymlink( defaultChannelsDir(), nixExprPath + "/channels"); - if (getuid() != 0) + if (!isRootUser()) replaceSymlink( rootChannelsDir(), nixExprPath + "/channels_root"); diff --git a/src/nix/main.cc b/src/nix/main.cc index 22f9e7931e8..36256f3d0c6 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -348,7 +348,7 @@ void mainWrapped(int argc, char * * argv) initGC(); #if __linux__ - if (getuid() == 0) { + if (isRootUser()) { try { saveMountNamespace(); if (unshare(CLONE_NEWNS) == -1)