Я неправильно использую SetNamedSecurityInfo? ACL моего файла, похоже, не модифицируется должным образом

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

 void set_DACL_for_object(const char *object, SE_OBJECT_TYPE object_type,
                          int access_perms, int access_mode) {

      PACL pDACL = NULL, pOldDACL = NULL;
      PSECURITY_DESCRIPTOR pSD = NULL;
      EXPLICIT_ACCESS ea;

      GetNamedSecurityInfo((LPTSTR)object, object_type,
                            DACL_SECURITY_INFORMATION, NULL, NULL,
                            &pOldDACL, NULL, &pSD);

      ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));

      ea.grfAccessPermissions = access_perms;
      ea.grfAccessMode = access_mode;
      ea.grfInheritance = NO_INHERITANCE;
      ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
      ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
      ea.Trustee.ptstrName = _T("ADMINISTRATORS");

      SetEntriesInAcl(1, &ea, pOldDACL, &pDACL);

      SetNamedSecurityInfo((LPTSTR)object, object_type,
                            DACL_SECURITY_INFORMATION, NULL, NULL, pDACL, NULL);
 }

Итак, сначала я создаю файл с помощью fopen(), создаю ACL для предоставления полного доступа группе администраторов, а затем запрещаю группе администраторов доступ на запись:

 set_DACL_for_object("C:\\file.txt", SE_FILE_OBJECT, GENERIC_ALL, SET_ACCESS);
 set_DACL_for_object("C:\\file.txt", SE_FILE_OBJECT, GENERIC_WRITE, DENY_ACCESS);

Однако после этих звонков у меня нет доступа для чтения к файлу. Если я не звоню, у меня есть доступ для чтения/записи (как и следовало ожидать).

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

Я перепробовал множество различных комбинаций вызовов set_DACL_for_object(), например, заменил DENY_ACCESS на REVOKE_ACCESS, SET_ACCESS на GRANT_ACCESS, не делал никаких вызовов SET_ACCESS и т. д. и т. д., но, похоже, ничего не работает.

Должен отметить, что большая часть кода была взята из этого Пример MSDN, поэтому я думаю, что он должен работать. Что именно я делаю неправильно?


person ZZZzzz    schedule 08.07.2009    source источник


Ответы (2)


открыть и прочитать в какой программе? ACL был настроен так, как я ожидал, но FILE_GENERIC_WRITE может быть слишком общим для ваших целей; похоже, что это также устанавливает «специальное» разрешение, которое влияет на атрибуты чтения.

из winnt.h:

#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\
                                   FILE_WRITE_DATA          |\
                                   FILE_WRITE_ATTRIBUTES    |\
                                   FILE_WRITE_EA            |\
                                   FILE_APPEND_DATA         |\
                                   SYNCHRONIZE)

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

DWORD dwCustomWrite = FILE_WRITE_DATA       | 
                      FILE_WRITE_ATTRIBUTES | 
                      FILE_WRITE_EA         | 
                      FILE_APPEND_DATA;
set_DACL_for_object(..., SE_FILE_OBJECT, dwCustomWrite, DENY_ACCESS);

в списке расширенных разрешений на вкладке безопасности в файле с указанным выше вызовом только следующие помечены как «запретить» для группы «администраторы»:

«Создание файлов/запись данных», «Создание папок/дополнение данных», «Запись атрибутов», «Запись расширенных атрибутов»

Обладая этими знаниями, вы сможете выбрать именно тот набор флагов, который вам нужен.

person Community    schedule 08.07.2009
comment
Спасибо! Это сделало это. После того, как я ответил на ваш первый ответ, я загрузился в безопасном режиме и проверил информацию о безопасности в файле, для которого я создавал и изменял ACL. Я заметил, что доступ на запись действительно был запрещен, а доступ на чтение разрешен... но также были запрещены некоторые специальные разрешения. Спасибо, что указали мне правильное направление, теперь это работает. - person ZZZzzz; 08.07.2009

я думаю, что вызовы set_DACL_for_object должны указывать FILE_ALL_ACCESS и FILE_GENERIC_WRITE, а не GENERIC_ALL и GENERIC_WRITE. Я скомпилировал ваш фрагмент кода с этими изменениями, и он работал так, как вы ожидаете.

В качестве примечания, приведение LPTSTR не позволяет компилятору определить, что этот код является Ansi, если вы когда-либо скомпилируете его как Unicode, поэтому в этом случае код завершится ошибкой во время выполнения.

Вместо этого вы должны использовать _T("ADMINISTRATORS").

person Community    schedule 08.07.2009
comment
Спасибо; Я попробовал это, и он все еще дает те же результаты для меня (не могу прочитать файл). В вашей системе вызов обеих этих функций — SET_ACCESS для FILE_ALL_ACCESS и DENY_ACCESS для FILE_GENERIC_WRITE — позволяет открыть файл и прочитать его, но не записать? - person ZZZzzz; 08.07.2009