你如何委托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()
来做到这一点)也可能是错误的。 你需要运行一个完全独立的进程,我想要得到你想要的权限限制。