-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathperms.go
More file actions
127 lines (107 loc) · 2.74 KB
/
perms.go
File metadata and controls
127 lines (107 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//go:build windows
package fuji
import (
"fmt"
"github.com/itchio/ox/syscallex"
"github.com/itchio/headway/state"
"github.com/itchio/ox/winox"
)
type SetFilePermissionParams struct {
// The file or folder to apply permissions to
Path string
// Inherit determines whether permissions also apply to all folders and files
// in the container, recursively
Inherit bool
// Rights if one of "read", "write", "execute", "all", or "full"
Rights string
// Trustee is the name of the account permissions are granted to or revoked
Trustee string
// Change is one of "grant" or "revoke"
Change string
}
func SetFilePermissions(consumer *state.Consumer, params *SetFilePermissionParams) error {
entry := &winox.ShareEntry{
Path: params.Path,
}
if params.Inherit {
entry.Inheritance = winox.InheritanceModeFull
} else {
entry.Inheritance = winox.InheritanceModeNone
}
switch params.Rights {
case "read":
entry.Rights = winox.RightsRead
case "write":
entry.Rights = winox.RightsWrite
case "execute":
entry.Rights = winox.RightsExecute
case "all":
entry.Rights = winox.RightsAll
case "full":
entry.Rights = winox.RightsFull
default:
return fmt.Errorf("unknown rights: %s", params.Rights)
}
policy := &winox.SharingPolicy{
Trustee: params.Trustee,
Entries: []*winox.ShareEntry{entry},
}
switch params.Change {
case "grant":
consumer.Opf("Granting %s", policy)
err := policy.Grant(consumer)
if err != nil {
return fmt.Errorf("%w", err)
}
case "revoke":
consumer.Opf("Revoking %s", policy)
err := policy.Revoke(consumer)
if err != nil {
return fmt.Errorf("%w", err)
}
default:
return fmt.Errorf("unknown change: %s", params.Change)
}
consumer.Statf("Policy applied successfully")
return nil
}
type checkAccessSpec struct {
name string
flags uint32
}
var checkAccessSpecs = []checkAccessSpec{
{"read", syscallex.GENERIC_READ},
{"write", syscallex.GENERIC_WRITE},
{"execute", syscallex.GENERIC_EXECUTE},
{"all", syscallex.GENERIC_ALL},
}
type CheckAccessParams struct {
File string
}
func (i *instance) CheckAccess(consumer *state.Consumer, params *CheckAccessParams) error {
creds, err := i.GetCredentials()
if err != nil {
return fmt.Errorf("%w", err)
}
impersonationToken, err := winox.GetImpersonationToken(creds.Username, ".", creds.Password)
if err != nil {
return fmt.Errorf("%w", err)
}
defer winox.SafeRelease(uintptr(impersonationToken))
for _, spec := range checkAccessSpecs {
hasAccess, err := winox.UserHasPermission(
impersonationToken,
spec.flags,
params.File,
)
if err != nil {
return fmt.Errorf("%w", err)
}
if hasAccess {
consumer.Opf("User has %s access", spec.name)
} else {
consumer.Opf("User does not have %s access", spec.name)
}
}
return nil
}