aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/manager/service.go
diff options
context:
space:
mode:
Diffstat (limited to 'manager/service.go')
-rw-r--r--manager/service.go57
1 files changed, 40 insertions, 17 deletions
diff --git a/manager/service.go b/manager/service.go
index 6c3b039b..48ecd129 100644
--- a/manager/service.go
+++ b/manager/service.go
@@ -90,6 +90,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
aliveSessions := make(map[uint32]bool)
procsLock := sync.Mutex{}
stoppingManager := false
+ operatorGroupSid, _ := windows.CreateWellKnownSid(windows.WinBuiltinNetworkConfigurationOperatorsSid)
startProcess := func(session uint32) {
defer func() {
@@ -104,7 +105,24 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
if err != nil {
return
}
- if !elevate.TokenIsElevatedOrElevatable(userToken) {
+ isAdmin := elevate.TokenIsElevatedOrElevatable(userToken)
+ isOperator := false
+ if !isAdmin && conf.AdminBool("LimitedOperatorUI") && operatorGroupSid != nil {
+ linkedToken, err := userToken.GetLinkedToken()
+ var impersonationToken windows.Token
+ if err == nil {
+ err = windows.DuplicateTokenEx(linkedToken, windows.TOKEN_QUERY, nil, windows.SecurityImpersonation, windows.TokenImpersonation, &impersonationToken)
+ linkedToken.Close()
+ } else {
+ err = windows.DuplicateTokenEx(userToken, windows.TOKEN_QUERY, nil, windows.SecurityImpersonation, windows.TokenImpersonation, &impersonationToken)
+ }
+ if err == nil {
+ isOperator, err = impersonationToken.IsMember(operatorGroupSid)
+ isOperator = isOperator && err == nil
+ impersonationToken.Close()
+ }
+ }
+ if !isAdmin && !isOperator {
userToken.Close()
return
}
@@ -125,23 +143,28 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
return
}
userProfileDirectory, _ := userToken.GetUserProfileDirectory()
- var elevatedToken windows.Token
- if userToken.IsElevated() {
- elevatedToken = userToken
- } else {
- elevatedToken, err = userToken.GetLinkedToken()
- userToken.Close()
- if err != nil {
- log.Printf("Unable to elevate token: %v", err)
- return
- }
- if !elevatedToken.IsElevated() {
- elevatedToken.Close()
- log.Println("Linked token is not elevated")
- return
+ var elevatedToken, runToken windows.Token
+ if isAdmin {
+ if userToken.IsElevated() {
+ elevatedToken = userToken
+ } else {
+ elevatedToken, err = userToken.GetLinkedToken()
+ userToken.Close()
+ if err != nil {
+ log.Printf("Unable to elevate token: %v", err)
+ return
+ }
+ if !elevatedToken.IsElevated() {
+ elevatedToken.Close()
+ log.Println("Linked token is not elevated")
+ return
+ }
}
+ runToken = elevatedToken
+ } else {
+ runToken = userToken
}
- defer elevatedToken.Close()
+ defer runToken.Close()
userToken = 0
first := true
for {
@@ -186,7 +209,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
log.Printf("Starting UI process for user ā€˜%s@%sā€™ for session %d", username, domain, session)
attr := &os.ProcAttr{
Sys: &syscall.SysProcAttr{
- Token: syscall.Token(elevatedToken),
+ Token: syscall.Token(runToken),
},
Files: []*os.File{devNull, devNull, devNull},
Dir: userProfileDirectory,