Can I run a separate goroutine in windows as a different user?

How do you delegate running goroutine to another non-administrator account on Windows? I see you can do this on Linux with syscall.Setuid()

. I can't see how to do this on Windows using the syscall windows package. I would like to be able to set up a goroutine account while it is running. Is it possible?

Background bit: - I want to switch the user that runs the goroutine so that I can change the OS user passed to Oracle during the database connection when I use go-oci8 (see my other question ). I need to connect to a database and it uses the logged in user (OS user) as part of the security. In java, I can change the environment variable while setting up the connection (or click the username environment variable if only the connection is for one user).

I have a user database username (this matches the OS username) and I get the password of the database user. I don't have a Windows login password. I was hoping that I could be able to delegate the goroutine to the desired Windows user from the main go program running as admin, similar to the Linux port binding example I have highlighted. Changing the Oracle username to use the OS user is not an option, so it will fall back to Java if I can't handle it :-(.


source to share

2 answers

In theory, no, this is not possible, because in both Linux and Windows, the concept of user identification only exists for OS-level threads, and goroutines are not OS OS threads, so they are very lightweight objects that map to real OS threads with using the Go scheduler (part of the Go runtime built into your executable), and during its lifetime, goroutine can run on different OS threads at different times.

But there is some kind of "exit shading" for your situation, originally designed to call the code C

: runtime.LockOSThread()

Once goroutine calls this function, it gets stuck in the thread that is currently running and will not be assigned to be called any other, no matter before which will goroutine or cause runtime.UnlockOSThread()


You can use it like this:

go func() {
  defer runtime.UnlockOSThread()
  impersonate() // acquires and assumes some other credentials


The implementation of this imaginary function impersonate()

is beyond the scope of this question; you can call any Win32 API function using syscall

package - see the Go standard library for examples.

Note that a call runtime.LockOSThread()

in real-world scenarios results in the whole OS branch referring to only one goroutine (while usually many of them only work on one), so if you plan on creating many such goroutines blocked for OS threads must be prepared for increased use of OS resources.

Update: Working example tested on Windows XP Pro SP3 32-bit with Go 1.2.1 / i386.

It hardcodes the user "foo" identified by the password "foo". To quickly create a user on Windows, run

net user foo * /ADD


and enter its password twice when prompted.



Goroutines are green threads and can be tied to different operating system threads at will. So your initial assumption (that you can do it with a simple one syscall.Setuid()

on linux) is also probably wrong. You will need to go through a completely separate process, I think, to get the privilege restrictions you want.



All Articles