Sur Windows, est-il possible d’exécuter un seul goroutine en tant qu’utilisateur différent?

Comment déléguer l’exécution d’un goroutine à un autre compte non administrateur sur Windows? Je vois que vous pouvez le faire sous Linux en utilisant syscall.Setuid() . Je ne peux pas voir comment faire cela sous Windows en utilisant le paquet Windows syscall. Je voudrais pouvoir définir le compte sous lequel le goroutine s’exécute pendant l’exécution du programme. Est-ce possible?

Bit d’arrière-plan: – Je veux changer l’utilisateur qui exécute la goroutine afin que je puisse changer l’utilisateur du système d’exploitation passé à Oracle lors de la connexion à la firebase database lorsque j’utilise go-oci8 (voir mon autre question ). Je dois me connecter à la firebase database et utiliser l’utilisateur connecté (utilisateur du système d’exploitation) dans le cadre de la sécurité. En Java, je peux modifier la variable d’environnement lors de la configuration de la connexion (ou effacer la variable d’environnement du nom d’utilisateur si la connexion ne concerne qu’un seul utilisateur).

J’ai le nom d’utilisateur de la firebase database des utilisateurs (cela correspond au nom d’utilisateur du système d’exploitation) et j’obtiens le mot de passe de l’utilisateur de la firebase database. Je n’ai pas le mot de passe de connexion utilisateur Windows. J’espérais pouvoir déléguer l’exécution d’un goroutine à l’utilisateur Windows requirejs à partir du programme principal s’exécutant en tant qu’administrateur de la même manière que l’exemple de liaison de port Linux que j’ai mis en évidence. Changer le login Oracle pour ne pas utiliser le système d’exploitation utilisateur n’est pas une option, donc il sera de retour à Java si je ne peux pas le résoudre :-(.

En théorie, non, ce n’est pas possible car sous Linux et Windows, le concept d’identité d’utilisateur n’existe que pour les threads de niveau OS et les goroutines ne sont pas des threads OS. par le planificateur Go (une partie de l’exécution de Go intégrée à votre exécutable), et pendant sa durée de vie, une goroutine peut être exécutée sur différents threads de système d’exploitation à différents moments.

Mais il existe une sorte de “sortie de hachures” pour votre situation conçue à l’origine pour aider à appeler le code C : runtime.LockOSThread() . Une fois qu’un goroutine appelle cette fonction, il est bloqué sur le thread sur lequel il s’exécute et ne sera pas programmé pour être appelé sur un autre, peu importe la sortie ou l’appel de runtime.UnlockOSThread() .

Vous pourriez utiliser ceci comme ceci:

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

L’implémentation de cette fonction imaginaire impersonate() est hors de scope de cette question; vous pouvez appeler n’importe quelle fonction API Win32 en utilisant le paquet syscall – voir la bibliothèque standard Go pour des exemples.


Notez que le fait d’appeler runtime.LockOSThread() dans le monde réel a pour effet de dédier un thread de système d’exploitation entier à un seul goroutine (alors que bon nombre d’entre eux s’exécutent sur un seul). Les goroutines verrouillées sur les threads du système d’exploitation sont préparées pour gérer l’utilisation accrue des ressources du système d’exploitation.

Mise à jour: un exemple de travail testé sur Windows XP Pro SP3 32 bits avec Go 1.2.1 / i386.

Il code dur l’utilisateur “foo” identifié par le mot de passe “foo”. Pour créer rapidement un utilisateur sous Windows, faites

 net user foo * /ADD 

et tapez son mot de passe deux fois lorsque vous y êtes invité.

Les Goroutines sont des fils verts et peuvent être mappés à volonté sur différents threads du système d’exploitation. Donc, votre hypothèse originale (que vous pouvez faire avec un simple syscall.Setuid() sur Linux) est probablement également fausse. Je pense que vous devez exécuter un processus entièrement distinct pour obtenir les ressortingctions de privilège que vous souhaitez.