Я неправильно использую 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, поэтому я думаю, что он должен работать. Что именно я делаю не так?
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);
в списке расширенных разрешений на вкладке "Безопасность" в файле при указанном выше вызове только следующие помечаются как "запрещенные" для группы "администраторы":
"Создание файлов / запись данных", "создание папок / добавление данных", "Запись атрибутов", "Запись расширенных атрибутов"
Обладая этими знаниями, вы сможете выбрать именно тот набор флагов, который вам нужен.
Я думаю set_DACL_for_object
звонки должны указывать FILE_ALL_ACCESS
а также FILE_GENERIC_WRITE
не GENERIC_ALL
а также GENERIC_WRITE
, я скомпилировал ваш фрагмент кода с этими изменениями, и он работал как вы ожидаете.
Как примечание стороны, LPTSTR
Метод cast запрещает компилятору определить, что этот код является Ansi, если вам когда-либо придется скомпилировать его как Unicode, поэтому в этом случае код не будет работать во время выполнения.
Вы должны использовать _T("ADMINISTRATORS")
вместо.