@@ -72,6 +72,7 @@ import System.IO (stderr,stdin,stdout,hIsTerminalDevice)
7272import System.IO.Error (isDoesNotExistError )
7373import System.IO.Unsafe (unsafePerformIO )
7474import qualified System.PosixCompat.User as User
75+ import qualified System.PosixCompat.Files as Files
7576import System.Process.PagerEditor (editByteString )
7677import System.Process.Read
7778import System.Process.Run
@@ -82,6 +83,7 @@ import Text.Printf (printf)
8283import Control.Concurrent (threadDelay )
8384import Control.Monad.Trans.Control (liftBaseWith )
8485import System.Posix.Signals
86+ import qualified System.Posix.User as PosixUser
8587#endif
8688
8789-- | If Docker is enabled, re-runs the currently running OS command in a Docker container.
@@ -104,10 +106,16 @@ reexecWithOptionalContainer mprojectRoot =
104106 where
105107 getCmdArgs docker envOverride imageInfo isRemoteDocker = do
106108 config <- asks getConfig
107- deUidGid <-
109+ deUser <-
108110 if fromMaybe (not isRemoteDocker) (dockerSetUser docker)
109- then liftIO $ Just <$>
110- ((,) <$> User. getEffectiveUserID <*> User. getEffectiveGroupID)
111+ then liftIO $ do
112+ duUid <- User. getEffectiveUserID
113+ duGid <- User. getEffectiveGroupID
114+ duGroups <- User. getGroups
115+ duUmask <- Files. setFileCreationMask 0o022
116+ -- Only way to get old umask seems to be to change it, so set it back afterward
117+ _ <- Files. setFileCreationMask duUmask
118+ return (Just DockerUser {.. })
111119 else return Nothing
112120 args <-
113121 fmap
@@ -713,10 +721,10 @@ entrypoint config@Config{..} DockerEntrypoint{..} =
713721 estackUserEntry0 <- liftIO $ tryJust (guard . isDoesNotExistError) $
714722 User. getUserEntryForName stackUserName
715723 -- Switch UID/GID if needed, and update user's home directory
716- case deUidGid of
724+ case deUser of
717725 Nothing -> return ()
718- Just (0 , _) -> return ()
719- Just (uid,gid) -> updateOrCreateStackUser envOverride estackUserEntry0 homeDir uid gid
726+ Just (DockerUser 0 _ _ _) -> return ()
727+ Just du -> updateOrCreateStackUser envOverride estackUserEntry0 homeDir du
720728 case estackUserEntry0 of
721729 Left _ -> return ()
722730 Right ue -> do
@@ -751,35 +759,45 @@ entrypoint config@Config{..} DockerEntrypoint{..} =
751759 copyFile srcIndex destIndex
752760 return True
753761 where
754- updateOrCreateStackUser envOverride estackUserEntry homeDir uid gid = do
762+ updateOrCreateStackUser envOverride estackUserEntry homeDir DockerUser { .. } = do
755763 case estackUserEntry of
756764 Left _ -> do
757765 -- If no 'stack' user in image, create one with correct UID/GID and home directory
758766 readProcessNull Nothing envOverride " groupadd"
759767 [" -o"
760- ," --gid" ,show gid
768+ ," --gid" ,show duGid
761769 ,stackUserName]
762770 readProcessNull Nothing envOverride " useradd"
763771 [" -oN"
764- ," --uid" ,show uid
765- ," --gid" ,show gid
772+ ," --uid" ,show duUid
773+ ," --gid" ,show duGid
766774 ," --home" ,toFilePathNoTrailingSep homeDir
767775 ,stackUserName]
768776 Right _ -> do
769- -- If there is already a 'stack' user in thr image, adjust its UID/GID and home directory
777+ -- If there is already a 'stack' user in the image, adjust its UID/GID and home directory
770778 readProcessNull Nothing envOverride " usermod"
771779 [" -o"
772- ," --uid" ,show uid
780+ ," --uid" ,show duUid
773781 ," --home" ,toFilePathNoTrailingSep homeDir
774782 ,stackUserName]
775783 readProcessNull Nothing envOverride " groupmod"
776784 [" -o"
777- ," --gid" ,show gid
785+ ," --gid" ,show duGid
778786 ,stackUserName]
787+ forM_ duGroups $ \ gid -> do
788+ readProcessNull Nothing envOverride " groupadd"
789+ [" -o"
790+ ," --gid" ,show gid
791+ ," group" ++ show gid]
779792 -- 'setuid' to the wanted UID and GID
780793 liftIO $ do
781- User. setGroupID gid
782- User. setUserID uid
794+ User. setGroupID duGid
795+ #ifndef WINDOWS
796+ PosixUser. setGroups duGroups
797+ #endif
798+ User. setUserID duUid
799+ _ <- Files. setFileCreationMask duUmask
800+ return ()
783801 stackUserName = " stack" :: String
784802
785803-- | MVar used to ensure the Docker entrypoint is performed exactly once
0 commit comments