aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/elevate
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-08-28 21:50:19 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2019-08-30 08:47:21 -0600
commitff17660af8c4632271c2cac52c11887d08730d31 (patch)
tree7319c6c027134682e8c474bf9375a70d3aca8dde /elevate
parentmanager: fix nits in adapter cleanup logic and also handle ā€˜%sā€™ uniformly (diff)
downloadwireguard-windows-ff17660af8c4632271c2cac52c11887d08730d31.tar.xz
wireguard-windows-ff17660af8c4632271c2cac52c11887d08730d31.zip
elevate: use more strict check for admin group
Diffstat (limited to 'elevate')
-rw-r--r--elevate/membership.go33
-rw-r--r--elevate/shellexecute.go2
2 files changed, 22 insertions, 13 deletions
diff --git a/elevate/membership.go b/elevate/membership.go
index baa4d71b..ccd0b60e 100644
--- a/elevate/membership.go
+++ b/elevate/membership.go
@@ -6,23 +6,32 @@
package elevate
import (
- "runtime"
-
"golang.org/x/sys/windows"
)
-func TokenIsMemberOfBuiltInAdministrator(token windows.Token) bool {
- gs, err := token.GetTokenGroups()
+func isAdmin(token windows.Token) bool {
+ builtinAdminsGroup, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
if err != nil {
return false
}
- isAdmin := false
- for _, g := range gs.AllGroups() {
- if (g.Attributes&windows.SE_GROUP_USE_FOR_DENY_ONLY != 0 || g.Attributes&windows.SE_GROUP_ENABLED != 0) && g.Sid.IsWellKnown(windows.WinBuiltinAdministratorsSid) {
- isAdmin = true
- break
- }
+ var checkableToken windows.Token
+ err = windows.DuplicateTokenEx(token, windows.TOKEN_QUERY | windows.TOKEN_IMPERSONATE, nil, windows.SecurityIdentification, windows.TokenImpersonation, &checkableToken)
+ if err != nil {
+ return false
+ }
+ defer checkableToken.Close()
+ isAdmin, err := checkableToken.IsMember(builtinAdminsGroup)
+ return isAdmin && err == nil
+}
+
+func TokenIsElevatedOrElevatable(token windows.Token) bool {
+ if token.IsElevated() && isAdmin(token) {
+ return true
+ }
+ linked, err := token.GetLinkedToken()
+ if err != nil {
+ return false
}
- runtime.KeepAlive(gs)
- return isAdmin
+ defer linked.Close()
+ return linked.IsElevated() && isAdmin(linked)
}
diff --git a/elevate/shellexecute.go b/elevate/shellexecute.go
index 6933c8f5..2c4190e0 100644
--- a/elevate/shellexecute.go
+++ b/elevate/shellexecute.go
@@ -54,7 +54,7 @@ func ShellExecute(program string, arguments string, directory string, show int32
err = windows.ERROR_SUCCESS
return
}
- if !TokenIsMemberOfBuiltInAdministrator(processToken) {
+ if !TokenIsElevatedOrElevatable(processToken) {
err = windows.ERROR_ACCESS_DENIED
return
}