summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/Sudo.hs
diff options
context:
space:
mode:
authorJoey Hess2018-08-26 10:44:25 -0400
committerJoey Hess2018-08-26 10:44:25 -0400
commite4ce2792bbd7ab7495ea86fd4228ad3595d8b48a (patch)
tree51d2083f9456cc86c28976d0dd069faaf0531d03 /src/Propellor/Property/Sudo.hs
parentd595fdfa25eab311d2407f86efbb85f6d52c5603 (diff)
parent2a499012b680db73df20b6b5b0bc4959ab65006d (diff)
Merge branch 'joeyconfig'
Diffstat (limited to 'src/Propellor/Property/Sudo.hs')
-rw-r--r--src/Propellor/Property/Sudo.hs41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/Propellor/Property/Sudo.hs b/src/Propellor/Property/Sudo.hs
index 1614801d..12660aa9 100644
--- a/src/Propellor/Property/Sudo.hs
+++ b/src/Propellor/Property/Sudo.hs
@@ -7,37 +7,62 @@ import Propellor.Property.File
import qualified Propellor.Property.Apt as Apt
import Propellor.Property.User
--- | Allows a user to sudo. If the user has a password, sudo is configured
--- to require it. If not, NOPASSWORD is enabled for the user.
+-- | Allows a user to run any command with sudo.
+-- If the user has a password, sudo is configured to require it.
+-- If not, NOPASSWORD is enabled for the user.
+--
+-- Writes to the file /etc/sudoers.d/000users rather than the main sudoers
+-- file. This file should come before other include files that may eg,
+-- allow running more specific commands without a password, since sudo
+-- uses the last matching configuration line.
+--
+-- If the main sudoers file contains a conflicting line for
+-- the user for ALL commands, the line will be removed.
enabledFor :: User -> RevertableProperty DebianLike DebianLike
enabledFor user@(User u) = setup `requires` Apt.installed ["sudo"] <!> cleanup
where
setup :: Property UnixLike
setup = property' desc $ \w -> do
locked <- liftIO $ isLockedPassword user
- ensureProperty w $
- fileProperty desc
+ ensureProperty w $ combineProperties desc $ props
+ & fileProperty desc
(modify locked . filter (wanted locked))
- sudoers
+ dfile
+ & removeconflicting sudoers
where
desc = u ++ " is sudoer"
cleanup :: Property DebianLike
- cleanup = tightenTargets $
- fileProperty desc (filter notuserline) sudoers
+ cleanup = tightenTargets $ combineProperties desc $ props
+ & removeconflicting sudoers
+ & removeconflicting dfile
where
desc = u ++ " is not sudoer"
+ removeconflicting = fileProperty "remove conflicting" (filter notuserline)
+
sudoers = "/etc/sudoers"
+ dfile = "/etc/sudoers.d/000users"
sudobaseline = u ++ " ALL=(ALL:ALL)"
notuserline l = not (sudobaseline `isPrefixOf` l)
sudoline True = sudobaseline ++ " NOPASSWD:ALL"
sudoline False = sudobaseline ++ " ALL"
wanted locked l
- -- TOOD: Full sudoers file format parse..
| notuserline l = True
| "NOPASSWD" `isInfixOf` l = locked
| otherwise = True
modify locked ls
| sudoline locked `elem` ls = ls
| otherwise = ls ++ [sudoline locked]
+
+-- | Sets up a file in /etc/sudoers.d/, which /etc/sudoers includes,
+-- with the specified content.
+--
+-- The FilePath can be relative to that directory.
+sudoersDFile :: FilePath -> [Line] -> RevertableProperty DebianLike Linux
+sudoersDFile dfile content = setup `requires` Apt.installed ["sudo"] <!> cleanup
+ where
+ f = "/etc/sudoers.d" </> dfile
+ -- sudoers.d files should not be world readable
+ setup = hasContentProtected f content
+ cleanup = tightenTargets $ notPresent f