summaryrefslogtreecommitdiff
path: root/src/Propellor/Property/User.hs
diff options
context:
space:
mode:
authorJoey Hess2014-12-14 15:24:10 -0400
committerJoey Hess2014-12-14 15:24:10 -0400
commit71723ca09f369ccf96462cef1e0200e1615677d1 (patch)
tree9519e6a0e1f2a2353df4ef836118bbf3bf96eef4 /src/Propellor/Property/User.hs
parent2e2438ae66490a2a00972be16e95f0d9cda2f9ea (diff)
support for crypted passwords in privdata
* Added CryptPassword to PrivDataField, for password hashes as produced by crypt(3). * User.hasPassword and User.hasSomePassword will now use either a CryptPassword or a Password from privdata, depending on which is set.
Diffstat (limited to 'src/Propellor/Property/User.hs')
-rw-r--r--src/Propellor/Property/User.hs29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/Propellor/Property/User.hs b/src/Propellor/Property/User.hs
index 69794d84..549aa07f 100644
--- a/src/Propellor/Property/User.hs
+++ b/src/Propellor/Property/User.hs
@@ -23,7 +23,7 @@ nuked user _ = check (isJust <$> catchMaybeIO (homedir user)) $ cmdProperty "use
`describe` ("nuked user " ++ user)
-- | Only ensures that the user has some password set. It may or may
--- not be the password from the PrivData.
+-- not be a password from the PrivData.
hasSomePassword :: UserName -> Property
hasSomePassword user = hasSomePassword' user hostContext
@@ -34,22 +34,31 @@ hasSomePassword' :: IsContext c => UserName -> c -> Property
hasSomePassword' user context = check ((/= HasPassword) <$> getPasswordStatus user) $
hasPassword' user context
--- | Ensures that a user's password is set to the password from the PrivData.
+-- | Ensures that a user's password is set to a password from the PrivData.
-- (Will change any existing password.)
+--
+-- A user's password can be stored in the PrivData in either of two forms;
+-- the full cleartext <Password> or a <CryptPassword> hash. The latter
+-- is obviously more secure.
hasPassword :: UserName -> Property
hasPassword user = hasPassword' user hostContext
hasPassword' :: IsContext c => UserName -> c -> Property
hasPassword' user context = go `requires` shadowConfig True
where
- go = withPrivData (Password user) context $
- property (user ++ " has password") . setPassword user
-
-setPassword :: UserName -> ((PrivData -> Propellor Result) -> Propellor Result) -> Propellor Result
-setPassword user getpassword = getpassword $ \password -> makeChange $
- withHandle StdinHandle createProcessSuccess
- (proc "chpasswd" []) $ \h -> do
- hPutStrLn h $ user ++ ":" ++ password
+ go = withSomePrivData [CryptPassword user, Password user] context $
+ property (user ++ " has password") . setPassword
+
+setPassword :: (((PrivDataField, PrivData) -> Propellor Result) -> Propellor Result) -> Propellor Result
+setPassword getpassword = getpassword $ go
+ where
+ go (Password user, password) = set user password []
+ go (CryptPassword user, hash) = set user hash ["--encrypted"]
+ go (f, _) = error $ "Unexpected type of privdata: " ++ show f
+
+ set user v ps = makeChange $ withHandle StdinHandle createProcessSuccess
+ (proc "chpasswd" ps) $ \h -> do
+ hPutStrLn h $ user ++ ":" ++ v
hClose h
lockedPassword :: UserName -> Property