一尘不染

在Windows上,是否可以以其他用户身份运行单个goroutine?

go

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

背景知识:- 我想切换运行goroutine的用户,以便当我使用go-oci8时,可以更改在数据库连接期间传递给Oracle的OSUser)。我需要连接到数据库,它使用登录用户(OS用户)作为安全性的一部分。在Java中,我可以在建立连接的过程中更改环境变量(如果仅连接一个用户,则可以轻击用户名环境变量)。

我有用户数据库用户名(与操作系统用户名匹配),并且得到了数据库用户密码。我没有用户的Windows登录密码。我希望能够以类似于我突出显示的Linux端口绑定示例的方式,从以管理员身份运行的主go程序中,将goroutine委托给所需的Windows用户。不能将Oracle登录名更改为不使用OS
User,因此,如果无法解决,它将返回Java状态:-(。


阅读 203

收藏
2020-07-02

共1个答案

一尘不染

从理论上讲,这是不可能的,因为在Linux和Windows上,用户身份的概念仅存在于OS级别的线程中,goroutines 不是 OS线程-
而是轻量级实体,它们映射到真实的OS线程由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()在实际场景中调用会导致将整个OS线程专用于单个goroutine(而通常它们中的很多都只能在一个goroutine上运行),因此,如果您计划生成许多此类锁在OS线程中的goroutine,准备应对增加的OS资源使用情况。

更新: 一个工作示例,该示例在带有Go
1.2.1 / i386的Windows XP Pro SP3 32位上进行了测试。

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

net user foo * /ADD

并在出现提示时键入两次密码。

2020-07-02