summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremyShaw <>2012-03-05 15:10:35 (GMT)
committerhdiff <hdiff@luite.com>2012-03-05 15:10:35 (GMT)
commitfb9a0358158f7a7ac63d71505358af13644f0752 (patch)
tree344843f652bd57ac76ff732092f9feac527f79b6
version 1.0.0HEAD1.0.0master
-rw-r--r--COPYING31
-rw-r--r--Setup.hs3
-rw-r--r--System/Unix/Shadow.hsc108
-rw-r--r--Unixutils-shadow.cabal20
4 files changed, 162 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..85cd8ba
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,31 @@
+Copyright Jeremy Shaw, David Fox 2007-2012
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the name of the copyright holder nor the names of other
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
index 0000000..14db136
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+import Distribution.Simple
+main = defaultMainWithHooks simpleUserHooks
diff --git a/System/Unix/Shadow.hsc b/System/Unix/Shadow.hsc
new file mode 100644
index 0000000..d3aa66c
--- /dev/null
+++ b/System/Unix/Shadow.hsc
@@ -0,0 +1,108 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module : System.Unix.Shadow
+-- Copyright : (c) 2010 Jeremy Shaw, The University of Glasgow
+-- License : BSD3
+--
+-- Maintainer : jeremy@seereason.com
+-- Stability : provisional
+-- Portability : non-portable (requires POSIX)
+--
+-- support for /etc/shadow
+--
+-- TODO: This module is modelled after System.Posix.User but lacks many
+-- of the #ifdefs. Those are probably important.
+-----------------------------------------------------------------------------
+module System.Unix.Shadow
+ ( SUserEntry(..)
+ , getSUserEntryForName
+ ) where
+
+import Control.Exception
+import Control.Monad
+import Foreign
+import Foreign.C
+import System.Posix.Types
+import System.IO.Error
+
+#include "shadow.h"
+
+type CSpwd = ()
+
+-- | Entry returned by 'getSUserEntryForName'
+--
+-- TODO: add other fields
+data SUserEntry =
+ SUserEntry {
+ sUserName :: String, -- ^ Textual name of this user (pw_name)
+ sUserPassword :: String -- ^ Password -- may be empty or fake if shadow is in use (pw_passwd)
+ } deriving (Show, Read, Eq)
+
+
+
+-- | @getSUserEntryForName name@ calls @getspnam@ to obtain
+-- the @SUserEntry@ information associated with the user login
+-- @name@.p
+getSUserEntryForName :: String -> IO SUserEntry
+-- #if HAVE_GETPWNAM_R
+getSUserEntryForName name = do
+ allocaBytes (#const sizeof(struct spwd)) $ \ppw ->
+ alloca $ \ pppw ->
+ withCString name $ \ pstr -> do
+ throwErrorIfNonZero_ "getsUserEntryForName" $
+ doubleAllocWhile isERANGE pwBufSize $ \s b ->
+ c_getspnam_r pstr ppw b (fromIntegral s) pppw
+ r <- peekElemOff pppw 0
+ when (r == nullPtr) $
+ ioError $ flip ioeSetErrorString "no user name"
+ $ mkIOError doesNotExistErrorType
+ "getUserEntryForName"
+ Nothing
+ (Just name)
+ unpackSUserEntry ppw
+
+foreign import ccall unsafe "getspnam_r"
+ c_getspnam_r :: CString -> Ptr CSpwd
+ -> CString -> CSize -> Ptr (Ptr CSpwd) -> IO CInt
+{-
+#elif HAVE_GETPWNAM
+getUserEntryForName name = do
+ withCString name $ \ pstr -> do
+ withMVar lock $ \_ -> do
+ ppw <- throwErrnoIfNull "getUserEntryForName" $ c_getpwnam pstr
+ unpackUserEntry ppw
+
+foreign import ccall unsafe "getpwnam"
+ c_getpwnam :: CString -> IO (Ptr CPasswd)
+#else
+getUserEntryForName = error "System.Posix.User.getUserEntryForName: not supported"
+#endif
+-}
+
+unpackSUserEntry :: Ptr CSpwd -> IO SUserEntry
+unpackSUserEntry ptr = do
+ name <- (#peek struct spwd, sp_namp) ptr >>= peekCString
+ passwd <- (#peek struct spwd, sp_pwdp) ptr >>= peekCString
+ return (SUserEntry name passwd)
+
+isERANGE :: Integral a => a -> Bool
+isERANGE = (== eRANGE) . Errno . fromIntegral
+
+doubleAllocWhile :: (a -> Bool) -> Int -> (Int -> Ptr b -> IO a) -> IO a
+doubleAllocWhile p s m = do
+ r <- allocaBytes s (m s)
+ if p r then doubleAllocWhile p (2 * s) m else return r
+
+
+pwBufSize :: Int
+pwBufSize = 1024
+
+-- Used when calling re-entrant system calls that signal their 'errno'
+-- directly through the return value.
+throwErrorIfNonZero_ :: String -> IO CInt -> IO ()
+throwErrorIfNonZero_ loc act = do
+ rc <- act
+ if (rc == 0)
+ then return ()
+ else ioError (errnoToIOError loc (Errno (fromIntegral rc)) Nothing Nothing)
diff --git a/Unixutils-shadow.cabal b/Unixutils-shadow.cabal
new file mode 100644
index 0000000..d9df3f0
--- /dev/null
+++ b/Unixutils-shadow.cabal
@@ -0,0 +1,20 @@
+Name: Unixutils-shadow
+Version: 1.0.0
+License: BSD3
+License-File: COPYING
+Author: Jeremy Shaw, David Fox
+Homepage: http://src.seereason.com/haskell-unixutils-shadow
+Category: System
+Synopsis: A simple interface to shadow passwords (aka, shadow.h)
+Maintainer: jeremy@n-heptane.com
+Description:
+ Provides the ability to read a user entry from the shadow password database
+Build-type: Simple
+Cabal-Version: >= 1.2
+
+Library
+ Build-Depends: base >= 4 && <5,
+ unix
+ ghc-options: -O2
+ Exposed-modules:
+ System.Unix.Shadow