在Windows上,是否有可能作为一个不同的用户运行一个goroutine?

你如何委托goroutine运行到另一个非pipe理员帐户在Windows上? 我看到你可以在Linux上使用syscall.Setuid()来做到这一点。 我无法看到如何使用Windows系统调用包在Windows上执行此操作。 我希望能够在程序运行时设置goroutine运行的帐户。 这可能吗?

背景位: –我想切换运行goroutine的用户,这样我就可以在使用go-oci8时(参见我的其他问题 )更改在数据库连接期间传递给Oracle的OS用户。 我需要连接到数据库,并使用login用户(OS用户)作为安全性的一部分。 在java中,我可以在连接build立期间更改环境variables(或者如果仅连接一个用户,则可以轻弹username环境variables)。

我有用户数据库用户名(这与操作系统的用户名相匹配),我得到的数据库用户密码。 我没有用户的Windowslogin密码。 我希望能够以运行pipe理员身份的主要go程序将运行goroutine委托给所需的windows用户,与我突出显示的Linux端口绑定示例类似。 将Oraclelogin更改为不使用OS用户不是一个选项,所以如果我不能解决这个问题,它将返回到Java :-(。

理论上,不行,这是不可能的,因为在Linux和Windows上,用户身份的概念只存在于操作系统级别的线程,而例程不是操作系统线程 – 相反,它们是非常轻量级的实体,映射到真正的操作系统线程通过Go调度程序(Go运行时的一部分内置到可执行文件中),并且在其生命周期中,goroutine可能会在不同的时间在不同的OS线程上执行。

但是,对于您最初设计用于帮助调用C代码的情况,存在一种“退出孵化器”: runtime.LockOSThread() 。 一旦一个goroutine调用这个函数,它会被卡住到当前正在运行的线程上,不会被调度到另一个线程上,直到goroutine退出或调用runtime.UnlockOSThread()

你可以像这样使用它:

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

这个虚构的impersonate()函数的实现不在这个问题的范围之内; 您可以使用syscall包调用任何Win32 API函数 – 请参阅标准的Go库以获取示例。


请注意,调用runtime.LockOSThread()在现实世界中的结果是将整个操作系统线程专用于一个goroutine(而通常它们中的大部分只运行在一个goroutine上),所以如果你打算产生很多这样的锁定到操作系统线程的goroutines准备处理增加的操作系统资源使用情况。

更新:使用Go 1.2.1 / i386在Windows XP Pro SP3 32位上进行测试的一个工作示例 。

它对由密码“foo”标识的用户“foo”进行硬编码。 要在Windows上快速创建用户,请执行

 net user foo * /ADD 

并在提示时输入两次密码。

Goroutines是绿色的线程,可以随意映射到各种操作系统线程。 所以你原来的假设(你可以在Linux上用一个简单的syscall.Setuid()来做到这一点)也可能是错误的。 你需要运行一个完全独立的进程,我想要得到你想要的权限限制。