Correctly set UID/GID on all created folders (#4)

This commit is contained in:
Michael Snoyman 2012-12-27 11:52:55 +02:00
parent 54dbe11845
commit 2fd2919640
2 changed files with 29 additions and 7 deletions

View File

@ -23,6 +23,7 @@ import qualified Codec.Archive.Tar.Check as Tar
import qualified Codec.Archive.Tar.Entry as Tar import qualified Codec.Archive.Tar.Entry as Tar
import Codec.Compression.GZip (decompress) import Codec.Compression.GZip (decompress)
import qualified Filesystem.Path.CurrentOS as F import qualified Filesystem.Path.CurrentOS as F
import qualified Filesystem as F
import Data.Yaml import Data.Yaml
import Control.Applicative ((<$>), (<*>)) import Control.Applicative ((<$>), (<*>))
import qualified Network import qualified Network
@ -40,6 +41,7 @@ import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.Text.Encoding (encodeUtf8) import Data.Text.Encoding (encodeUtf8)
import System.Posix.Types (UserID, GroupID) import System.Posix.Types (UserID, GroupID)
import System.Posix.Files.ByteString (setOwnerAndGroup, setFdOwnerAndGroup) import System.Posix.Files.ByteString (setOwnerAndGroup, setFdOwnerAndGroup)
import Control.Monad (unless)
data Config = Config data Config = Config
{ configExec :: F.FilePath { configExec :: F.FilePath
@ -101,7 +103,7 @@ unpackBundle tf muid bundle appname = do
case elbs of case elbs of
Left e -> return $ Left e Left e -> return $ Left e
Right lbs -> do Right lbs -> do
edir <- getFolder tf appname edir <- getFolder muid tf appname
case edir of case edir of
Left e -> return $ Left e Left e -> return $ Left e
Right dir -> do Right dir -> do
@ -133,6 +135,19 @@ fixStaticHost dir sh =
fp0 = shRoot sh fp0 = shRoot sh
fp = F.collapse $ dir F.</> "config" F.</> fp0 fp = F.collapse $ dir F.</> "config" F.</> fp0
-- | Create a directory tree, setting the uid and gid of all newly created
-- folders.
createTreeUID :: UserID -> GroupID -> FilePath -> IO ()
createTreeUID uid gid =
go
where
go fp = do
exists <- F.isDirectory fp
unless exists $ do
go $ F.parent fp
F.createDirectory False fp
setOwnerAndGroup (F.encode fp) uid gid
unpackTar :: Maybe (UserID, GroupID) unpackTar :: Maybe (UserID, GroupID)
-> FilePath -> Tar.Entries Tar.FormatError -> IO () -> FilePath -> Tar.Entries Tar.FormatError -> IO ()
unpackTar muid dir = unpackTar muid dir =
@ -146,10 +161,9 @@ unpackTar muid dir =
let fp = dir </> decodeString (Tar.entryPath e) let fp = dir </> decodeString (Tar.entryPath e)
case Tar.entryContent e of case Tar.entryContent e of
Tar.NormalFile lbs _ -> do Tar.NormalFile lbs _ -> do
createTree $ F.directory fp
case muid of case muid of
Nothing -> return () Nothing -> createTree $ F.directory fp
Just (uid, gid) -> setOwnerAndGroup (F.encode $ F.directory fp) uid gid Just (uid, gid) -> createTreeUID uid gid $ F.directory fp
let write fd bs = unsafeUseAsCStringLen bs $ \(ptr, len) -> do let write fd bs = unsafeUseAsCStringLen bs $ \(ptr, len) -> do
_ <- fdWriteBuf fd (castPtr ptr) (fromIntegral len) _ <- fdWriteBuf fd (castPtr ptr) (fromIntegral len)
return () return ()

View File

@ -12,6 +12,9 @@ import Keter.Prelude
import Data.Word (Word) import Data.Word (Word)
import Keter.Postgres (Appname) import Keter.Postgres (Appname)
import qualified Data.IORef as I import qualified Data.IORef as I
import System.Posix.Files.ByteString (setOwnerAndGroup)
import System.Posix.Types (UserID, GroupID)
import qualified Filesystem.Path.CurrentOS as F
data TempFolder = TempFolder data TempFolder = TempFolder
{ tfRoot :: FilePath { tfRoot :: FilePath
@ -26,8 +29,13 @@ setup fp = liftIO $ do
c <- I.newIORef minBound c <- I.newIORef minBound
return $ TempFolder fp c return $ TempFolder fp c
getFolder :: TempFolder -> Appname -> KIO (Either SomeException FilePath) getFolder :: Maybe (UserID, GroupID) -> TempFolder -> Appname -> KIO (Either SomeException FilePath)
getFolder TempFolder {..} appname = do getFolder muid TempFolder {..} appname = do
!i <- atomicModifyIORef tfCounter $ \i -> (succ i, i) !i <- atomicModifyIORef tfCounter $ \i -> (succ i, i)
let fp = tfRoot </> fromText (appname ++ "-" ++ show i) let fp = tfRoot </> fromText (appname ++ "-" ++ show i)
liftIO (createTree fp >> return fp) liftIO $ do
createTree fp
case muid of
Nothing -> return ()
Just (uid, gid) -> setOwnerAndGroup (F.encode fp) uid gid
return fp