hectane / go-acl

Go library for manipulating ACLs on Windows
MIT License
120 stars 30 forks source link

Support a couple of different methods for checking file permissions #14

Open zb140 opened 5 years ago

zb140 commented 5 years ago

These values will differ if, for instance, no permissions have been explicitly granted.

zb140 commented 5 years ago

@nathan-osman Do you have any questions or concerns I can address? I'd love to get this merged, because I'm working on some changes for another project that depend on it. Thanks!

capnspacehook commented 5 years ago

I just have to say, thanks so much for this, was exactly what I needed. You're my hero

capnspacehook commented 5 years ago

Hey @zb140 I'm having an issue with the code in this PR, on a Windows 10 box with default file permissions, I'm getting a '0700' file mode from 'C:\Users' when calling acl.GetEffectiveAccessMode. It should be '704', as Everyone has read permissions by default. I verified that the permissions were different by checking with Windows Explorer and icacls.

zb140 commented 5 years ago

@capnspacehook Huh, that's odd. It's supposed to be a pretty transparent pass-through to GetEffectiveRightsFromAclW but there could certainly be bugs. I'm on an airplane right now so I won't have a chance to investigate until at least tomorrow, but I'll see what I can find.

capnspacehook commented 5 years ago

It may not be your code; from some research I did it seems that GetEffectiveRightsFromAcl itself may be unreliable on some situations. Not completely sure though.

zb140 commented 5 years ago

@capnspacehook This actually seems to be working on my system. I put together this simple test program:

package main

import (
    "fmt"
    "os"
    "path/filepath"
    "strconv"

    "github.com/hectane/go-acl"
)

func main() {
    path, err := filepath.Abs(os.Args[1])
    if err != nil {
        panic(err)
    }

    if len(os.Args) == 3 {
        newmode, err := strconv.ParseInt(os.Args[2], 8, 0)

        if err == nil {
            fmt.Printf("Changing mode to %o\n", newmode&0777)
            err = acl.Chmod(path, os.FileMode(newmode&0777))
            if err != nil {
                panic(err)
            }
        }
    }

    mode, err := acl.GetEffectiveAccessMode(path)
    if err != nil {
        panic(err)
    }

    fmt.Printf("effective mode = %v (%04o)\n", mode, uint(mode))

    mode, err = acl.GetExplicitAccessMode(path)
    if err != nil {
        panic(err)
    }

    fmt.Printf("explicit  mode = %v (%04o)\n", mode, uint(mode))
}

and this is what I got on my system:

go run acl.go c:\Users
effective mode = -rwxrwxr-x (0775)                                                                                                                                
explicit  mode = -rwx---r-x (0705)

Can you try this on your system and see if you get something different?

Also, you can read the ACL in Powershell like this:

(get-item c:\Users | get-acl).Access

This returns several results, including (for me):

FileSystemRights  : ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : Everyone
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None
twpayne commented 5 years ago

Can this be merged?