Deal with pkexec changing to root's home directory when running a command.

Wow, that's not documented anywhere, and seems like a major gotcha in
pkexec.

Broke enable-tor.
This commit is contained in:
Joey Hess 2019-10-21 12:16:18 -04:00
parent 93f53cda08
commit 9a5d9019ba
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
3 changed files with 38 additions and 21 deletions

View file

@ -1,6 +1,8 @@
git-annex (7.20191018) UNRELEASED; urgency=medium git-annex (7.20191018) UNRELEASED; urgency=medium
* init: Fix a failure when used in a submodule on a crippled filesystem. * init: Fix a failure when used in a submodule on a crippled filesystem.
* enable-tor: Deal with pkexec changing to root's home directory
when running a command.
-- Joey Hess <id@joeyh.name> Mon, 21 Oct 2019 11:01:06 -0400 -- Joey Hess <id@joeyh.name> Mon, 21 Oct 2019 11:01:06 -0400

View file

@ -46,18 +46,19 @@ start os = do
#else #else
start _os = do start _os = do
#endif #endif
uuid <- getUUID
when (uuid == NoUUID) $
giveup "This can only be run in a git-annex repository."
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
curruserid <- liftIO getEffectiveUserID curruserid <- liftIO getEffectiveUserID
if curruserid == 0 if curruserid == 0
then case readish =<< headMaybe os of then case os of
Nothing -> giveup "Need user-id parameter." (uid:[]) -> go uid
Just userid -> go uuid userid (uid:repodir:_) -> do
Annex.changeDirectory repodir
go uid
_ -> giveup "Need user-id parameter."
else starting "enable-tor" (ActionItemOther Nothing) $ do else starting "enable-tor" (ActionItemOther Nothing) $ do
gitannex <- liftIO readProgramFile gitannex <- liftIO readProgramFile
let ps = [Param (cmdname cmd), Param (show curruserid)] cwd <- liftIO getCurrentDirectory
let ps = [Param (cmdname cmd), Param (show curruserid), Param cwd]
sucommand <- liftIO $ mkSuCommand gitannex ps sucommand <- liftIO $ mkSuCommand gitannex ps
maybe noop showLongNote maybe noop showLongNote
(describePasswordPrompt' sucommand) (describePasswordPrompt' sucommand)
@ -67,14 +68,19 @@ start _os = do
[ "Failed to run as root:" , gitannex ] ++ toCommand ps [ "Failed to run as root:" , gitannex ] ++ toCommand ps
) )
#else #else
go uuid 0 go "0"
#endif #endif
where where
go uuid userid = do go suserid = case readish suserid of
(onionaddr, onionport) <- liftIO $ Nothing -> giveup "Unable to parse user-id parameter."
addHiddenService torAppName userid (fromUUID uuid) Just userid -> do
storeP2PAddress $ TorAnnex onionaddr onionport uuid <- getUUID
stop when (uuid == NoUUID) $
giveup "This can only be run in a git-annex repository."
(onionaddr, onionport) <- liftIO $
addHiddenService torAppName userid (fromUUID uuid)
storeP2PAddress $ TorAnnex onionaddr onionport
stop
checkHiddenService :: CommandCleanup checkHiddenService :: CommandCleanup
checkHiddenService = bracket setup cleanup go checkHiddenService = bracket setup cleanup go

View file

@ -61,24 +61,33 @@ runSuCommand Nothing = return False
-- decide based on the system's configuration whether sudo should be used. -- decide based on the system's configuration whether sudo should be used.
mkSuCommand :: String -> [CommandParam] -> IO (Maybe SuCommand) mkSuCommand :: String -> [CommandParam] -> IO (Maybe SuCommand)
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
mkSuCommand cmd ps = firstM (\(SuCommand _ p _) -> inPath p) =<< selectcmds mkSuCommand cmd ps = do
pwd <- getCurrentDirectory
firstM (\(SuCommand _ p _) -> inPath p) =<< selectcmds pwd
where where
selectcmds = ifM (inx <||> (not <$> atconsole)) selectcmds pwd = ifM (inx <||> (not <$> atconsole))
( return (graphicalcmds ++ consolecmds) ( return (graphicalcmds pwd ++ consolecmds pwd)
, return consolecmds , return (consolecmds pwd)
) )
inx = isJust <$> getEnv "DISPLAY" inx = isJust <$> getEnv "DISPLAY"
atconsole = queryTerminal stdInput atconsole = queryTerminal stdInput
-- These will only work when the user is logged into a desktop. -- These will only work when the user is logged into a desktop.
graphicalcmds = graphicalcmds pwd =
[ SuCommand (MayPromptPassword SomePassword) "gksu" [ SuCommand (MayPromptPassword SomePassword) "gksu"
[Param shellcmd] [Param shellcmd]
, SuCommand (MayPromptPassword SomePassword) "kdesu" , SuCommand (MayPromptPassword SomePassword) "kdesu"
[Param "-c", Param shellcmd] [Param "-c", Param shellcmd]
, SuCommand (MayPromptPassword SomePassword) "pkexec" -- pkexec does not run the command in the current
([Param cmd] ++ ps) -- working directory, but in root's HOME.
, SuCommand (MayPromptPassword SomePassword) "pkexec" $
[Param "sh", Param "-c", Param $ unwords
[ "cd", shellEscape pwd
, "&&"
, shellcmd
]
]
-- Available in Debian's menu package; knows about lots of -- Available in Debian's menu package; knows about lots of
-- ways to gain root. -- ways to gain root.
, SuCommand (MayPromptPassword SomePassword) "su-to-root" , SuCommand (MayPromptPassword SomePassword) "su-to-root"
@ -89,7 +98,7 @@ mkSuCommand cmd ps = firstM (\(SuCommand _ p _) -> inPath p) =<< selectcmds
] ]
-- These will only work when run in a console. -- These will only work when run in a console.
consolecmds = consolecmds _pwd =
[ SuCommand (WillPromptPassword RootPassword) "su" [ SuCommand (WillPromptPassword RootPassword) "su"
[Param "-c", Param shellcmd] [Param "-c", Param shellcmd]
, SuCommand (MayPromptPassword UserPassword) "sudo" , SuCommand (MayPromptPassword UserPassword) "sudo"