2009-09-21 7 views
2

Je suppose qu'une fois qu'un sémaphore est créé par un processus, il sera accessible à tout processus/utilisateur.Définition des autorisations d'accès sur le sémaphore?

Est-il possible de mettre des restrictions d'accès sur un sémaphore particulier afin qu'il ne soit accessible que par certains processus/utilisateurs ou que certains processus seulement puissent libérer le sémaphore.
Je vois des problèmes si on rend un sémaphore accessible par tous les processus. Exemple: un processus fictif peut lire le sémaphore et relâcher le verrou à souhait en faisant un faux signal au processus réel qui attend réellement le verrou du sémaphore.

Toutes ces questions se posent que je reçois de sortie très bizarre avec l'extrait de code suivant:

use Win32::Semaphore; 

$sem = Win32::Semaphore->new(0, 1,"reliance2692") 
    or print "Can't create semaphore\n"; 

$sem = Win32::Semaphore->open("reliance2692") 
    or print "Can't open semaphore\n"; 

print "Semaphore:" . $sem . "\n"; 

En exécutant le programme ci-dessus, je reçois la sortie suivante

 
Can't create semaphore 
Can't open semaphore 

La sortie montre qu'il a échoué à créer un sémaphore et a même échoué à ouvrir le sémaphore. la création d'un sémaphore peut avoir échoué si un sémaphore existe déjà avec le nom donné. Je ne comprends pas pourquoi l'ouverture d'un sémaphore a échoué. Peut-on clarifier le scénario où échoue le sémaphore à la création du sémaphore &?

+0

Voulez-vous définir ou pensez-vous que les restrictions d'accès sont le problème? –

+0

Ici, les restrictions d'accès sont le problème. Comme le sémaphore a été créé plus tôt par un autre processus et je veux libérer le sémaphore en utilisant Win32 :: Semaphore –

Répondre

1

De Win32::Semaphore pod

$semaphore = Win32::Semaphore->new($initial, $maximum, [$name])

Constructeur pour un nouvel objet de sémaphores. $ initial est le nombre initial, et $ maximum est le nombre maximum pour le sémaphore. Si $ name est omis ou undef, crée un objet sémaphore sans nom.

Si $ nom signifie un objet sémaphore existant, alors $ initial et $ maximum sont ignorés et l'objet est ouvert. Si cela se produit, $^E sera défini sur 183 (ERROR_ALREADY_EXISTS).

Si je lis correctement, si votre appel à Win32::Semaphore->new fait référence à un sémaphore existant, l'appel new ouvrira la sémaphores ainsi, et l'appel open ultérieur sera redondant (ce n'est pas clair pour moi à partir du pod, que se passe-t-il si vous ouvrez un sempahore déjà ouvert).

Vous pourriez peut-être parcourir le code, en vérifiant la valeur de $sem ainsi que $! et $^E à chaque étape.

Réponse complémentaire: le Windows API a des méthodes de réglage du contrôle d'accès des sémaphores, mais

  1. ils ne semblent pas être exposé dans le contrôle d'accès Module
  2. Perl Win32::Semaphore ne peut pas être définir à moins qu'il ne soit déjà autorisé par l'autre processus qui a créé le sémaphore

Je ne sais pas si vous avez de bonnes options pour ce problème. Pouvez-vous modifier le processus qui crée le sémaphore pour assouplir les restrictions d'accès? Demandez à l'auteur Win32::Semaphore de mettre à jour son module? Essayez de résoudre vous-même Win32::Semaphore?

+0

Salut, Merci pour la réponse. $^E est défini sur "Accès refusé" pour les deux cas, je veux dire créer le sémaphore et ouvrir le sémaphore. sémaphore existe déjà comme créé par un autre processus avant d'exécuter cet extrait. Est-il possible de définir des permissions de sémaphore lors de la création en utilisant Win32 :: Semaphore afin qu'il soit accessible par tous les processus. –

3

Win32::Semaphore->new appelle la fonction API Windows CreateSemaphore et obtient sécurité par défaut du processus descripteur, ce qui signifie généralement que les processus en cours d'exécution avec le même utilisateur que votre script peut avoir un accès complet alors que les processus en cours d'autres comptes seront pas accès. Donc, pour commencer, votre hypothèse est fausse. Le nom que vous choisissez dans votre code Perl est transmis directement à la fonction API. Il est donc soumis au même namespace rules que tous les autres objets du noyau Win32. Win32 :: Semaphore ne fournit aucune interface pour spécifier les restrictions d'accès.

Même si cela s'est produit, Windows ne fournit pas d'autorisations par processus. Les autorisations sont attachées à l'utilisateur , pas le processus. Si vous obtenez "accès refusé" de , alors cela suggère qu'un autre programme est en cours d'exécution qui a choisi d'utiliser le même nom pour autre chose - peut-être un autre sémaphore, ou peut-être autre chose, comme un événement ou un mutex - et ce processus s'exécute en tant qu'utilisateur différent. Si vous obtenez "accès refusé" de open, alors, en plus des possibilités pour new, il se peut qu'un autre processus ait déjà ouvert un sémaphore avec le même nom mais n'a pas accordé d'autorisations complètes aux autres utilisateurs . Win32::Semaphore->open demande SEMAPHORE_ALL_ACCESS permission.

Si le sémaphore a déjà été ouvert par un processus s'exécutant sous le même utilisateur, vous ne devriez pas avoir "accès refusé". Ni new ni open ne devraient échouer dans ce cas, bien que $^E puisse de toute façon contenir 183 (ERROR_ALREADY_EXISTS).

2

Pour la petite histoire, je suis l'auteur de Win32::Semaphore. Comme mobrule et Rob l'ont expliqué, la sécurité de Windows est basée sur l'utilisateur/le groupe. Il n'est pas possible d'avoir un sémaphore auquel seuls certains processus peuvent accéder. Si un processus appartenant à un utilisateur peut accéder à un sémaphore, alors tout processus de cet utilisateur peut accéder à ce sémaphore.

Normalement, l'accès par défaut permet uniquement à l'utilisateur actuel d'accéder au sémaphore. Personne n'a jamais demandé à Win32 :: Semaphore de spécifier un descripteur de sécurité autre que celui par défaut, et l'API associée est non triviale. Si quelqu'un a créé un module pour gérer une structure SECURITY_ATTRIBUTES, je serais heureux d'ajouter le support pour cela à Win32 :: Semaphore et aux modules IPC associés. Win32-Security ne semble pas être ce module, bien qu'il puisse être un début.

Si vous avez besoin d'un sémaphore pour travailler sur plusieurs utilisateurs, votre seule solution consiste à créer le sémaphore en dehors de Win32 :: Semaphore, en passant un pointeur SECURITY_ATTRIBUTES approprié. Vous pouvez le faire avec un petit programme d'aide écrit en C, ou en utilisant Inline::C. (Rappelez-vous qu'une fois créé, un sémaphore existe aussi longtemps que n'importe quel processus a un handle ouvert, donc votre programme d'assistance doit garder le handle de sémaphore ouvert jusqu'à ce que vous l'appeliez Win32::Semaphore->open.)

+0

6 ans plus tard .. Je n'ai besoin de rien d'extraordinaire, juste la possibilité pour "Tout le monde" d'utiliser un sémaphore (lecture/écriture) dont le nom commence par "Global \". Où est le meilleur endroit pour demander cela? – Terris