在Windows上,是否可以作为不同的用户运行单个goroutine?

时间:2014-09-30 14:23:21

标签: windows go goroutine

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

背景: - 我想切换运行goroutine的用户,这样我就可以在使用go-oci8时更改在数据库连接期间传递给Oracle的操作系统用户(请参阅我的其他{ {3}})。我需要连接到数据库,它使用登录用户(OS用户)作为安全性的一部分。在java中,我可以在连接设置期间更改环境变量(如果仅为单个用户连接,则轻弹用户名环境变量)。

我有用户数据库用户名(这与操作系统用户名匹配),我获得了数据库用户密码。我没有用户的Windows登录密码。我希望能够以运行管理员的主要go程序将运行goroutine委托给所需的Windows用户,其方式类似于我强调的Linux端口绑定示例。将Oracle登录更改为不使用操作系统用户不是一个选项,因此如果我无法解决问题,它将返回Java :-(。

2 个答案:

答案 0 :(得分:5)

理论上,不,这是不可能的,因为在Linux和Windows上,用户身份的概念仅存在于操作系统级别的线程中,而goroutine是而不是操作系统线程 - 相反,它们非常轻-jay实体,由Go调度程序(内置于可执行文件中的Go运行时的一部分)映射到实际OS线程,并且在其生命周期内,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上),因此如果您计划生成一个许多锁定到OS线程的goroutine都准备好处理增加的OS资源使用情况。

更新: a working example使用Go 1.2.1 / i386在Windows XP Pro SP3 32位上进行了测试。

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

net user foo * /ADD

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

答案 1 :(得分:0)

Goroutines是绿色线程,可以随意映射到各种操作系统线程。因此,您最初的假设(您可以使用Linux上的简单syscall.Setuid()执行此操作)也可能是错误的。您需要在一个完全独立的过程中运行,我认为可以获得您想要的权限限制。