Книга: Системное программирование в среде Windows

Пример: использование разрешений на доступ в стиле UNIX к файлам NTFS

Пример: использование разрешений на доступ в стиле UNIX к файлам NTFS

Система разрешений на доступ к файлам, принятая в UNIX, предоставляет удобную возможность проиллюстрировать работу системы безопасности Windows, хотя последняя по своему характеру является гораздо более общей, чем стандартные средства защиты UNIX. В приведенной ниже реализации создается девять АСЕ, предоставляющих или запрещающих доступ по чтению, записи или запуску файлов на выполнение владельцу (owner), группе (group) и прочим пользователям (everyone). Предусмотрены две команды. 

1. chmodW — имитирует UNIX-команду chmod. В данной реализации возможности команды расширены за счет того, что в случае отсутствия указанного файла он будет создан, а также за счет того, что пользователю предоставляется возможность указывать имя группы.

2. lsFP — расширенный вариант команды lsW (программа 3.2). Если запрошен вывод подробной информации, то отображается имя пользователя-владельца файла, а также результат интерпретации существующих ACL, которые могли быть установлены командой chmodW.

Указанные две команды представлены программами 15.1 и 15.2. В программах 15.3, 15.4 и 15.5 реализованы три вспомогательные функции.

1. InitializeUnixSA, которая создает действительную структуру атрибутов безопасности, соответствующих набору разрешений доступа UNIX. Эта функция обладает достаточной общностью, чтобы ее можно было применять по отношению к таким объектам, отличным от файлов, как процессы (глава 6), именованные каналы (глава 11) и объекты синхронизации (глава 8).

2. ReadFilePermissions.

3. ChangeFilePermissions.

Примечание

Приведенные ниже программы являются упрощенными вариантами программ, представленных на Web-сайте книги. В полных вариантах программ используются отдельные массивы AllowedAceMasks и DeniedAceMasks, в то время как в листингах ниже задействован только один массив.

Использование отдельного массива DeniedAceMasks обеспечивает невозможность запрета прав доступа SYNCHRONIZE, поскольку флаг SYNCHRONIZE устанавливается во всех трех макросах FILE_GENERIC_READ, FILE_GENERIC_WRITE и FILE_GENERIC_EXECUTE, которые являются комбинациями нескольких флагов (см. заголовочный файл WINNT.H). Дополнительные разъяснения предоставляются в полном варианте программы, доступном на Web-сайте. Кроме того, в полном варианте программы проверяется, не указано ли в командной строке групповое имя; ниже мы будем везде предполагать, что указывается имя пользователя.

Программа 15.1. chmodW: изменение разрешений на доступ к файлу 

/* Глава 15. Команда chmodW. */
/* chmodW [опции] режим файл [ИмяГруппы].
   Изменение режима доступа к именованному файлу.
   Опции:
    -f Принудительный режим — не выводить предупреждающие сообщения в случае невозможности изменения режима.
    –с Создать файл, если он не существует. Необязательное имя группы указывается после имени файла. */
/* Требуются NTFS и Windows NT (под управлением Windows 9x программа работать не будет). */
#include "EvryThng.h" 
int _tmain(int argc, LPTSTR argv[]) {
 HANDLE hFile, hSecHeap;
 BOOL Force, CreateNew, Change, Exists;
 DWORD Mode, DecMode, UsrCnt = ACCT_NAME_SIZE;
 TCHAR UsrNam[ACCT_NAME_SIZE];
 int FileIndex, GrpIndex, ModeIndex;
 /* Массив прав доступа к файлу, следующих в том порядке, который принят в UNIX. */
 /* Эти права будут различными для объектов различного типа. */
 /*ПРИМЕЧАНИЕ: в полном варианте программы, находящемся на Web-сайте, */
 /*используются отдельные массивы масок разрешения и запрещения доступа.*/
 DWORD AceMasks[] = {
  FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE
 };
 LPSECURITY_ATTRIBUTES pSa = NULL;
 ModeIndex = Options(argc, argv, _T("fc"), &Force, &CreateNew, NULL);
 GrpIndex = ModeIndex + 2;
 FileIndex = ModeIndex + 1;
 DecMode = _ttoi(argv[ModeIndex]);
 /* Режим защиты представляет собой восьмеричное число. */
 Mode = ((DecMode / 100) % 10) * 64 /*Преобразовать в десятичное число.*/
      + ((DecMode / 10) % 10) * 8 + (DecMode % 10);
 Exists = (_taccess(argv[FileIndex], 0) == 0);
 if (!Exists && CreateNew) {
  /* Файл не существует; создать новый файл. */
  GetUserName(UsrNam, &UsrCnt);
  pSa = InitializeUnixSA(Mode, UsrNam, argv[GrpIndex], AceMasks, &hSecHeap);
  hFile = CreateFile(argv[FileIndex], 0, 0, pSa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  CloseHandle(hFile);
  HeapDestroy(hSecHeap); /* Освободить память, занимаемую структурами безопасности. */
 }
 else if (Exists) { /* Файл существует; изменить разрешения доступа. */
  Change = ChangeFilePermissions(Mode, argv[FileIndex], AceMasks);
 }
 return 0;
}
 

В программе 15.2 представлена соответствующая часть команды lsFP, а именно, функция Process Item. 

Программа 15.2. lsFP: перечисление разрешений на доступ к файлу 

static BOOL ProcessItem(LPWIN32_FIND_DATA pFileData, DWORD NumFlags, LPBOOL Flags)
/* Вывести список атрибутов с указанием разрешений доступа и владельца. */
/* Требуются NTFS и Windows NT (под управлением Windows 9x программа работать не будет). */
{
 DWORD FType = FileType(pFileData), Mode, i;
 BOOL Long = Flags[1];
 TCHAR GrpNam[ACCT_NAME_SIZE], UsrNam[ACCT_NAME_SIZE];
 SYSTEMTIME LastWrite;
 TCHAR PermString[] = _T("---------");
 const TCHAR RWX[] = {'r','w','x'}, FileTypeChar[] = {' ', 'd'};
 if (FType != TYPE_FILE && FType != TYPE_DIR) return FALSE;
 _tprintf(_T("n"));
 if (Long) {
  Mode = ReadFilePermissions(pFileData->cFileName, UsrNam, GrpNam);
  if (Mode == 0xFFFFFFFF) Mode = 0;
  for (i = 0; i < 9; i++) {
   if (Mode >> (8 – i) & 0x1) PermString[i] = RWX[i % 3];
  }
  _tprintf(_T("%c%s 18.7s %8.7s%10d"), FileTypeChar[FType – 1], PermString, UsrNam, GrpNam, pFileData->nFileSizeLow);
  FileTimeToSystemTime(&(pFileData->ftLastWriteTime), &LastWrite);
  _tprintf(_T(" %02d/%02d/%04d %02d:%02d:%02d"), LastWrite.wMonth, LastWrite.wDay, LastWrite.wYear, LastWrite.wHour, LastWrite.wMinute, LastWrite.wSecond);
 }
 _tprintf(_T(" %s"), pFileData->cFileName);
 return TRUE;
}
 

Далее мы рассмотрим реализацию вспомогательных функций.

Оглавление книги


Генерация: 1.374. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз