Установка прав доступа на семафор? - PullRequest
2 голосов
/ 21 сентября 2009

Я предполагаю, что как только процесс создан семафором, он будет доступен любому процессу / пользователю.

Можно ли наложить ограничения на доступ к определенному семафору, чтобы он мог быть доступен только определенным процессам / пользователям, или только определенные процессы могут освободить семафор.
Я вижу некоторые проблемы, если мы сделаем семафор доступным для всех процессов. Например: фиктивный процесс может прочитать семафор и снять блокировку по желанию, подав ложный сигнал фактическому процессу, который действительно ожидает блокировки семафора.

Все эти вопросы возникают, поскольку я получаю очень странный вывод со следующим фрагментом кода:

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

Вывод показывает, что не удалось создать семафор и даже не удалось открыть семафор. создание семафора может быть неудачным, если семафор уже существует с заданным именем. Я не понимаю, почему открыть семафор не удалось.

Может ли кто-нибудь прояснить сценарий, когда создание семафора и открытие семафора не удаются.

Ответы [ 3 ]

3 голосов
/ 22 сентября 2009

Win32::Semaphore->new вызывает функцию Windows API CreateSemaphore и получает дескриптор безопасности процесса по умолчанию , что обычно означает, что процессы, работающие от имени того же пользователя, что и ваш скрипт, могут иметь полный доступ, тогда как процессы, запущенные как другие учетные записи, не получают доступа Итак, для начала, ваше предположение неверно.

Имя, которое вы выбираете в своем коде Perl, передается непосредственно в функцию API, поэтому оно подчиняется тем же правилам пространства имен , что и все другие объекты ядра Win32.

Win32 :: Semaphore не предоставляет интерфейса для указания ограничений доступа. Даже если это так, Windows не предоставляет разрешения для каждого процесса. Разрешения привязаны к пользователю , а не к процессу .

Если вы получаете «отказано в доступе» из new, то это говорит о том, что запущена другая программа, которая решила использовать то же имя для чего-то другого - может быть, другой семафор или, возможно, что-то еще, например событие или мьютекс - и этот процесс выполняется от имени другого пользователя.

Если вы получаете «отказано в доступе» из open, то, в дополнение к возможностям для new, может быть, что другой процесс уже открыл семафор с тем же именем, но не предоставил полные разрешения другим пользователям. Win32::Semaphore->open запросы SEMAPHORE_ALL_ACCESS разрешение .

Если семафор уже открыт процессом, выполняющимся от имени того же пользователя, вы не должны получать «доступ запрещен». В этом случае ни new, ни open не должны завершиться ошибкой, хотя $^E может в любом случае содержать 183 (ERROR_ALREADY_EXISTS).

2 голосов
/ 22 сентября 2009

Для записи, я автор Win32 :: Semaphore . Как объяснили Мобруле и Роб, безопасность Windows основана на пользователях / группах. Невозможно иметь семафор, к которому могут обращаться только определенные процессы. Если какой-либо процесс, принадлежащий пользователю, может получить доступ к семафору, то любой процесс этого пользователя может получить доступ к этому семафору.

Обычно доступ по умолчанию разрешает только текущему пользователю доступ к семафору. Никто никогда не запрашивал возможность, чтобы Win32 :: Semaphore определял дескриптор безопасности не по умолчанию, а связанный API-интерфейс нетривиален. Если бы кто-нибудь создал модуль для управления структурой SECURITY_ATTRIBUTES, я был бы рад добавить поддержку этого в Win32 :: Semaphore и связанные с ним модули IPC. Win32-Security не является этим модулем, хотя это может быть началом.

Если вам нужен семафор для работы нескольких пользователей, ваше единственное решение сейчас - создать семафор вне Win32 :: Semaphore, передав соответствующий указатель SECURITY_ATTRIBUTES. Вы можете сделать это с помощью небольшой вспомогательной программы, написанной на C, или используя Inline :: C . (Помните, что после создания семафор существует до тех пор, пока любой процесс имеет открытый дескриптор, поэтому вашей вспомогательной программе нужно держать дескриптор семафора открытым, пока вы не вызовете Win32::Semaphore->open.)

1 голос
/ 22 сентября 2009

С Win32 :: Семафор pod

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

Конструктор для нового семафорного объекта. $ initial - начальный счет, а $ Maximum - максимальное количество для семафора. Если $ name отсутствует или undef, создает неназванный объект семафора.

Если $ name обозначает существующий объект семафора, то $ initial и $ Maximum игнорируются и объект открывается. Если это произойдет, $^E будет установлен в 183 (ERROR_ALREADY_EXISTS).

Если я правильно читаю, если ваш вызов Win32::Semaphore->new относится к существующему семафору, то вызов new также откроет семафор, и последующий вызов open будет избыточным (это не очистите меня от капсулы, что должно произойти, если вы откроете уже открытый семпафор).

Возможно, вы могли бы пройтись по коду, проверяя значение $sem, а также $! и $^E на каждом шаге.

Дополнительный ответ: Windows API имеет методы для настройки контроля доступа семафоров, но

  1. они не отображаются в модуле Perl Win32::Semaphore
  2. управление доступом не может быть установлено, если оно не было разрешено другим процессом, создавшим семафор

Я не знаю, есть ли у вас хорошие варианты решения этой проблемы. Можете ли вы изменить процесс создания семафора, чтобы ослабить ограничения доступа? Попросить автора Win32::Semaphore обновить его модуль? Попробуйте починить Win32::Semaphore самостоятельно?

...