diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-08-28 21:50:19 -0600 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-08-30 08:47:21 -0600 |
commit | 5aec69c5ba5cebd7b284f5d96e61b2d389a5572d (patch) | |
tree | 7319c6c027134682e8c474bf9375a70d3aca8dde | |
parent | manager: fix nits in adapter cleanup logic and also handle ā%sā uniformly (diff) | |
download | wireguard-windows-5aec69c5ba5cebd7b284f5d96e61b2d389a5572d.tar.xz wireguard-windows-5aec69c5ba5cebd7b284f5d96e61b2d389a5572d.zip |
elevate: use more strict check for admin group
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
-rw-r--r-- | elevate/membership.go | 33 | ||||
-rw-r--r-- | elevate/shellexecute.go | 2 | ||||
-rw-r--r-- | main.go | 2 | ||||
-rw-r--r-- | manager/service.go | 2 |
4 files changed, 24 insertions, 15 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 } @@ -75,7 +75,7 @@ func checkForAdminGroup() { fatal("Unable to open current process token: ", err) } defer processToken.Close() - if !elevate.TokenIsMemberOfBuiltInAdministrator(processToken) { + if !elevate.TokenIsElevatedOrElevatable(processToken) { fatal("WireGuard may only be used by users who are a member of the Builtin Administrators group.") } } diff --git a/manager/service.go b/manager/service.go index 8a525b12..43dd5d4c 100644 --- a/manager/service.go +++ b/manager/service.go @@ -104,7 +104,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest if err != nil { return } - if !elevate.TokenIsMemberOfBuiltInAdministrator(userToken) { + if !elevate.TokenIsElevatedOrElevatable(userToken) { userToken.Close() return } |