@@ -28,6 +28,28 @@ import (
2828 "github.com/pkg/errors"
2929)
3030
31+ // Apply the given permission bits and ownership to path in a cross-platform way.
32+ // - On Windows it runs “icacls path /grant username:F”
33+ // - On Linux/macOS it does os.Chmod(path, perm) then os.Chown(path, uid, gid)
34+ func SetOwnershipAndPermissions (path string , perm os.FileMode , user User ) error {
35+ if runtime .GOOS == "windows" {
36+ cmd := exec .Command ("icacls" , path , "/grant" , user .Username + ":F" )
37+ if out , err := cmd .CombinedOutput (); err != nil {
38+ return errors .Wrapf (err , "unable to modify ACLs on %q: %s" , path , string (out ))
39+ }
40+ return nil
41+ }
42+
43+ // Assume macOS or Linux
44+ if err := os .Chmod (path , perm ); err != nil {
45+ return errors .Wrapf (err , "unable to chmod %q to %v" , path , perm )
46+ }
47+ if err := os .Chown (path , user .Uid , user .Gid ); err != nil {
48+ return errors .Wrapf (err , "unable to chown %q to %d:%d" , path , user .Uid , user .Gid )
49+ }
50+ return nil
51+ }
52+
3153// This is the pelican version of `MkdirAll`; ensures that any created directory
3254// is owned by a given uid/gid. This allows the created directory to be owned by
3355// the xrootd user.
@@ -76,26 +98,29 @@ func MkdirAll(path string, perm os.FileMode, uid int, gid int) error {
7698 }
7799
78100 // Set ownership on the directory that we just created.
79- if runtime .GOOS == "windows" {
80- username , err := GetDaemonUser () // FIXME (brianaydemir): This is not the correct user.
81- if err != nil {
82- return err
83- }
84- cmd := exec .Command ("icacls" , path , "/grant" , username + ":F" )
85- output , err := cmd .CombinedOutput ()
86- if err != nil {
87- return errors .Wrapf (err , "unable to modify discretionary ACLs on directory %v: %s" , path , string (output ))
101+ user , err := GetPelicanUser ()
102+ if err != nil {
103+ return errors .Wrap (err , "failed to get pelican user" )
104+ }
105+ if err = SetOwnershipAndPermissions (path , perm , User {Uid : uid , Gid : gid , Username : user .Username }); err != nil {
106+ return errors .Wrapf (err , "failed to set ownership and permissions for %s" , path )
107+ }
108+ return nil
109+ }
110+
111+ // Set the permissions on the targeted file only if it exists. Doesn't care about its parent or siblings
112+ func setFilePerms (paths []string , perm os.FileMode , uid int , gid int ) error {
113+ for _ , path := range paths {
114+ // Skip the file if it doesn't exist
115+ if _ , err := os .Stat (path ); os .IsNotExist (err ) {
116+ continue
88117 }
89- } else { // Assume macOS or Linux.
90- // Any default system umask may prevent previous application of the permissions
91- // from taking effect. To override this, set the permissions explicitly
92- // after creation.
93- if err = os .Chmod (path , perm ); err != nil {
94- return errors .Wrapf (err , "unable to chmod on directory %v to %v" , path , perm )
118+ // Set the permissions on the file
119+ if err := os .Chmod (path , perm ); err != nil {
120+ return errors .Wrapf (err , "failed to set permissions on file %v" , path )
95121 }
96-
97- if err = os .Chown (path , uid , gid ); err != nil {
98- return errors .Wrapf (err , "unable to chown on directory %v to %v:%v" , path , uid , gid )
122+ if err := os .Chown (path , uid , gid ); err != nil {
123+ return errors .Wrapf (err , "failed to chown file %v" , path )
99124 }
100125 }
101126 return nil
0 commit comments