path: root/src/Propellor/Property/Sudo.hs
diff options
authorJoey Hess2018-08-20 18:00:13 -0400
committerJoey Hess2018-08-20 18:00:19 -0400
commit8690c09cc914da6ac3a6ba46ab3ba7690a344cf9 (patch)
tree07923e54f82c7e82f0106764f5ade20e6525ba28 /src/Propellor/Property/Sudo.hs
parent4be2ad75fc22080a11ac3a0988bfc8113345fcaa (diff)
Sudo.enabledFor: Write to /etc/sudoers.d/000users rather than to /etc/sudoers
(Any old lines it wrote to /etc/sudoers will be removed.) This fixes a potential ordering problem; the property used to append the line to /etc/sudoers, but that would override more specific lines in the include directory. By putting it in a file that is included first, it'll come before all includes, without needing to parse the sudoers file in order to put it before the includedir line. Note that, if there is a more specific line for the user in /etc/sudoers before the includedir, it will be overridden by the line in /etc/sudoers.d/000users. But, this is not a behavior change from before, when the line was appended to the end. This commit was sponsored by Jeff Goeke-Smith on Patreon.
Diffstat (limited to 'src/Propellor/Property/Sudo.hs')
1 files changed, 21 insertions, 8 deletions
diff --git a/src/Propellor/Property/Sudo.hs b/src/Propellor/Property/Sudo.hs
index c2f0ac4e..12660aa9 100644
--- a/src/Propellor/Property/Sudo.hs
+++ b/src/Propellor/Property/Sudo.hs
@@ -7,34 +7,47 @@ 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
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
desc = u ++ " is sudoer"
cleanup :: Property DebianLike
- cleanup = tightenTargets $
- fileProperty desc (filter notuserline) sudoers
+ cleanup = tightenTargets $ combineProperties desc $ props
+ & removeconflicting sudoers
+ & removeconflicting dfile
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
- -- TODO: Full sudoers file format parse..
| notuserline l = True
| "NOPASSWD" `isInfixOf` l = locked
| otherwise = True