From bb98331555a177f0e1256cebcfbc8a7b454bccd2 Mon Sep 17 00:00:00 2001 From: Paul Querna Date: Wed, 1 Nov 2017 15:11:52 -0700 Subject: syscall: add Token to Windows SysProcAttr Fixes #21105 Change-Id: Ia2dea9b82a356795f581ce75616198b46e97abb6 Reviewed-on: https://go-review.googlesource.com/75253 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor Reviewed-by: Alex Brainman --- src/syscall/exec_windows.go | 7 ++++++- src/syscall/syscall_windows.go | 1 + src/syscall/zsyscall_windows.go | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'src/syscall') diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go index cafce1eff6..d5b4a013ef 100644 --- a/src/syscall/exec_windows.go +++ b/src/syscall/exec_windows.go @@ -222,6 +222,7 @@ type SysProcAttr struct { HideWindow bool CmdLine string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess CreationFlags uint32 + Token Handle // if set, runs new process in the security context represented by the token } var zeroProcAttr ProcAttr @@ -321,7 +322,11 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle pi := new(ProcessInformation) flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT - err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi) + if sys.Token != 0 { + err = CreateProcessAsUser(sys.Token, argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi) + } else { + err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi) + } if err != nil { return 0, 0, err } diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go index cf27de30f5..84d5528e20 100644 --- a/src/syscall/syscall_windows.go +++ b/src/syscall/syscall_windows.go @@ -169,6 +169,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CancelIo(s Handle) (err error) //sys CancelIoEx(s Handle, o *Overlapped) (err error) //sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW +//sys CreateProcessAsUser(token Handle, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW //sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) //sys TerminateProcess(handle Handle, exitcode uint32) (err error) //sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go index 2283c79236..2c13b68cb2 100644 --- a/src/syscall/zsyscall_windows.go +++ b/src/syscall/zsyscall_windows.go @@ -80,6 +80,7 @@ var ( procCancelIo = modkernel32.NewProc("CancelIo") procCancelIoEx = modkernel32.NewProc("CancelIoEx") procCreateProcessW = modkernel32.NewProc("CreateProcessW") + procCreateProcessAsUserW = modadvapi32.NewProc("CreateProcessAsUserW") procOpenProcess = modkernel32.NewProc("OpenProcess") procTerminateProcess = modkernel32.NewProc("TerminateProcess") procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess") @@ -616,6 +617,24 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA return } +func CreateProcessAsUser(token Handle, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) { + var _p0 uint32 + if inheritHandles { + _p0 = 1 + } else { + _p0 = 0 + } + r1, _, e1 := Syscall12(procCreateProcessAsUserW.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = EINVAL + } + } + return +} + func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) { var _p0 uint32 if inheritHandle { -- cgit v1.3