packages feed

ldapply 0.1.0 → 0.2.0

raw patch · 4 files changed

+54/−6 lines, 4 filesdep ~LDAP

Dependency ranges changed: LDAP

Files

ChangeLog.md view
@@ -1,3 +1,11 @@+0.2.0+=====++  * Require [LDAP](https://hackage.haskell.org/package/LDAP) > 0.6.0 for `ldapExternalSaslBind`.+  * Support simple bind. Added options `-x`, `-D`, `-w`, `-y` similar to `ldapmodify`.+  * `changetype: delete` works if entry to be deleted does not exist.++ 0.1.0 ===== 
README.md view
@@ -33,9 +33,16 @@     Options:       -H <ldapuri>       LDAP URL to connect to [default: ldapi:///] +      -x                 Use simple bind instead of default SASL External+      -D <binddn>        Use <binddn> for the distinguished name or authorization identity+      -w <passwd>        Use <passwd> as the password for simple bind+      -y <passwdfile>    Read password from <passwdfile>, only the first line is read+       -h, --help         Show this message +    If option -w is given, -y is ignored. + LDIF example ============ @@ -73,5 +80,10 @@ changetype: modify replace: description description: foo++# This will be deleted if exists:+dn: cn=reader,dc=nodomain+changetype: delete+ ``` 
ldapply.cabal view
@@ -1,5 +1,5 @@ name: ldapply-version: 0.1.0+version: 0.2.0 synopsis: LDIF idempotent apply tool license: MIT license-file: LICENSE@@ -11,6 +11,10 @@ cabal-version: >=1.20 extra-source-files: README.md ChangeLog.md +source-repository head+  type: git+  location: https://github.com/ip1981/ldapply.git+ executable ldapply   hs-source-dirs: src   main-is: Main.hs@@ -22,7 +26,7 @@     , bytestring     , docopt     , interpolatedstring-perl6-    , LDAP >= 0.7.0+    , LDAP > 0.6.10     , ldif     , unordered-containers 
src/Main.hs view
@@ -6,15 +6,16 @@ import Data.ByteString.Char8 (unpack) import Data.Char (toLower) import Data.HashMap.Strict (fromListWith, toList)-import Data.Maybe (fromJust)+import Data.Maybe (fromJust, fromMaybe) import Data.Version (showVersion)-import LDAP.Init (ldapSimpleExternalSaslBind, ldapInitialize)+import LDAP.Init (ldapSimpleBind, ldapExternalSaslBind, ldapInitialize) import LDAP.Modify (LDAPMod(..), LDAPModOp(..), ldapAdd, ldapDelete, ldapModify, list2ldm) import LDAP.Search (LDAPScope(LdapScopeBase), SearchAttributes(LDAPAllUserAttrs), LDAPEntry(..), ldapSearch) import LDAP.Types (LDAP) import Paths_ldapply (version) -- from cabal import System.Environment (getArgs) import System.Exit (die)+import System.IO (IOMode(ReadMode), hGetLine, hIsEOF, withFile) import Text.InterpolatedString.Perl6 (qc) import Text.LDIF.Parser (defaulLDIFConf, parseLDIFFile) import Text.LDIF.Printer (dn2str)@@ -24,7 +25,6 @@ {--  TODO:     1. Streaming from stdin (good for large amount of LDIF data)-    2. Simple bind with DN and password --}  usage :: String@@ -38,7 +38,14 @@ Options:   -H <ldapuri>       LDAP URL to connect to [default: ldapi:///] +  -x                 Use simple bind instead of default SASL External+  -D <binddn>        Use <binddn> for the distinguished name or authorization identity+  -w <passwd>        Use <passwd> as the password for simple bind+  -y <passwdfile>    Read password from <passwdfile>, only the first line is read+   -h, --help         Show this message++If option -w is given, -y is ignored. |]  @@ -52,11 +59,26 @@     let       ldifs = O.getAllArgs args $ O.argument "LDIF"       ldapUrl = fromJust $ O.getArg args $ O.shortOption 'H'+      simple = O.isPresent args $ O.shortOption 'x'+      binddn = fromMaybe "" $ O.getArg args $ O.shortOption 'D'+      passwd = O.getArg args $ O.shortOption 'w'+      passwdfile = O.getArg args $ O.shortOption 'y'     ldap <- ldapInitialize ldapUrl-    ldapSimpleExternalSaslBind ldap+    if simple then simpleBind ldap binddn passwd passwdfile+              else ldapExternalSaslBind ldap binddn     mapM_ (processLDIF ldap) ldifs  +simpleBind :: LDAP -> String -> Maybe String -> Maybe FilePath -> IO ()+simpleBind ldap bdn (Just pwd)  _    = ldapSimpleBind ldap bdn pwd+simpleBind ldap bdn Nothing Nothing  = ldapSimpleBind ldap bdn ""+simpleBind ldap bdn Nothing (Just f) = do+  pwd <- withFile f ReadMode $ \h -> do+    empty <- hIsEOF h+    if empty then return "" else hGetLine h+  ldapSimpleBind ldap bdn pwd++ processLDIF :: LDAP -> FilePath -> IO () processLDIF ldap f = do   p <- parseLDIFFile defaulLDIFConf f@@ -81,6 +103,8 @@   update :: LDAP -> Maybe LDAPEntry -> LDIFRecord -> IO ()+update _ Nothing (ChangeRecord _ ChangeDelete) = return ()+ update _ Nothing rec@(ChangeRecord _ _) =   die $ "cannot update non-existing entry " ++ show (dn rec)