2009-09-21 125 views
2

我假设一旦进程创建了一个信号量,任何进程/用户都可以访问它。在Semaphore上设置访问权限?

是否有可能对特定信号量设置访问限制,以便仅可由某些进程/用户访问,或者只有某些进程才能释放信号量。
如果我们使所有进程都可以访问信号量,我会看到一些问题。例如:虚拟进程可以读取信号量并释放锁,以便向真正等待信号锁的实际进程发出虚假信号。

所有这些问题产生的,因为我变得很怪异输出与下面的代码片段:

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"; 

通过运行上面的程序,我得到下面的输出

 
Can't create semaphore 
Can't open semaphore 

输出表明它未能创建信号量,甚至未能打开信号量。如果信号量已经以给定名称存在,则创建信号量可能失败。 我不明白为什么打开信号失败。

有些人可以澄清创建信号量&开放信号失败的场景。

+0

是否要设置访问限制,还是你认为访问限制是问题? – 2009-09-22 17:05:01

+0

这里访问限制是问题。由于信号量是由另一个进程较早创建的,我想使用Win32 :: Semaphore发布信号量 – 2009-09-22 19:31:59

回答

1

Win32::Semaphore

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

构造一个新的信号量对象。 $ initial是初始计数,$最大值是信号量的最大计数值 。如果$ name被省略或undef,则创建一个未命名的信号量对象 。

如果$ name表示现有的信号量对象,则忽略$ initial和$ maximum 并打开该对象。如果发生这种情况,$^E将设置为183 (ERROR_ALREADY_EXISTS)。

如果我正确地读这篇文章,如果您对Win32::Semaphore->new呼叫指的是现有的信号,那么new通话将开启信号,以及,其后open通话将多余的(这不是我清楚如果你打开一个已经打开的sempahore,应该发生什么?)。

也许你可以逐步完成代码,在每一步检查$sem以及$!$^E的值。

附加回复:Windows API确实有设置信号灯的访问控制方法,但

  1. 它们不会出现Perl的Win32::Semaphore模块中暴露
  2. 访问控制不能除非它已经被创建信号量的其他进程所允许

我不知道你是否有任何这个问题的好选择。你能修改创建信号量的过程来放宽访问限制吗?请问Win32::Semaphore作者更新他的模块?试着自己修复Win32::Semaphore

+0

嗨, 感谢您的回复。 $^E设置为“访问被拒绝”的两种情况下,我的意思是创建信号量和打开信号量。 信号量在运行此片段之前已经由另一个进程创建。 有没有什么办法可以在创建使用Win32 :: Semaphore时设置信号量权限,以便它可以被所有进程访问。 – 2009-09-21 20:22:09

3

Win32::Semaphore->new调用Windows API函数CreateSemaphore和获取过程的默认安全描述符,这通常意味着运行相同的用户为你的脚本程序可以完全访问而运行的其它账户的过程获得的访问权限。所以,对于初学者来说,你的假设是错误的。

您在Perl代码中选择的名称直接传递给API函数,因此它受到与所有其他Win32内核对象相同的namespace rules的支配。

Win32 :: Semaphore没有提供指定访问限制的接口。即使这样做,Windows也不会提供每个进程的权限。权限附加到用户,而不是进程

如果您从new获得“访问被拒绝”,那么表明还有另一个程序正在运行,它选择使用同一个名称作为别的东西 - 也许是另一个信号量,或者其他的东西,比如事件或互斥量 - 并且该进程作为不同的用户运行。

如果您收到“拒绝访问”从open,那么,除了为new的可能性,这可能是因为另一个进程已经打开一个信号具有相同的名称,但并没有获得完全的权限给其他用户。 Win32::Semaphore->open请求SEMAPHORE_ALL_ACCESS permission

如果信号量已被作为同一用户运行的进程打开,那么您不应该“拒绝访问”。在这种情况下newopen都不应该失败,尽管$^E可能持有183(ERROR_ALREADY_EXISTS)。

2

对于该记录,我是Win32::Semaphore的作者。正如mobrule和Rob所解释的,Windows安全性是基于用户/组的。不可能有只有某些进程可以访问的信号量。如果属于用户的任何进程可以访问信号量,则该用户的任何进程都可以访问该信号量。

通常情况下,默认访问只允许当前用户访问信号量。没有人要求能够让Win32 :: Semaphore指定一个非默认安全描述符,并且关联的API不是微不足道的。如果有人创建了一个模块来管理SECURITY_ATTRIBUTES结构,我很乐意为Win32 :: Semaphore和相关的IPC模块添加对它的支持。 Win32-Security似乎不是那个模块,尽管它可能是一个开始。

如果你需要一个信号量来处理多个用户,你现在唯一的解决方案就是在Win32 :: Semaphore之外创建信号量,并传递一个适当的SECURITY_ATTRIBUTES指针。你可以用C语言编写的小型帮助程序或Inline::C来做到这一点。 (请记住,一旦创建,信号就存在,只要任何进程有一个开放的句柄,所以你的帮助程序需要保持信号柄处于打开状态,直到你呼叫Win32::Semaphore->open就可以了。)

+0

6年后..我不需要任何花哨的东西,只是“Everyone”能够使用名称以“Global \”开头的信号量(读/写)。请求这个最好的地方在哪里? – Terris 2015-09-17 00:07:57