Джонсон Харт - Системное программирование в среде Windows
- Название:Системное программирование в среде Windows
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2005
- Город:Москва • Санкт-Петербург • Киев
- ISBN:5-8459-0879-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джонсон Харт - Системное программирование в среде Windows краткое содержание
Эта книга посвящена вопросам разработки приложений с использованием интерфейса прикладного программирования операционных систем компании Microsoft (Windows 9х, Windows XP, Windows 2000 и Windows Server 2003). Основное внимание уделяется базовым системным службам, включая управление файловой системой, процессами и потоками, взаимодействие между процессами, сетевое программирование и синхронизацию. Рассматривается методика переноса приложений, написанных в среде Win32, в среду Win64. Подробно описываются все аспекты системы безопасности Windows и ее практического применения. Изобилие реальных примеров, доступных также и на Web-сайте книги, существенно упрощает усвоение материала.
Книга ориентирована на разработчиков и программистов, как высокой квалификации, так и начинающих, а также будет полезна для студентов соответствующих специальностей.
Системное программирование в среде Windows - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
pGrpNms[0] = UsrNam;
pGrpNms[1] = GrpNam;
for (iSid = 0; iSid < 3; iSid++) {
pSidTable[iSid] = HeapAlloc(SAHeap, 0, SID_SIZE);
LookupAccountName(NULL, pGrpNms[iSid], pSidTable[iSid], &SidCnt[iSid], RefDomain[iSid], &RefDomCnt[iSid], &sNamUse[iSid]);
}
SetSecurityDescriptorOwner(pSD, pSidTable[0], FALSE);
SetSecurityDescriptorGroup(pSD, pSidTable[1], FALSE);
pAcl = HeapAlloc(ProcHeap, HEAP_GENERATE_EXCEPTIONS, ACL_SIZE);
InitializeAcl(pAcl, ACL_SIZE, ACL_REVISION);
/* Добавить все элементы АСЕ, разрешающие и запрещающие доступ. */
for (iBit = 0; iBit < 9; iBit++) {
if ((UnixPerms >> (8 – iBit) & 0x1) != 0 && AceMasks[iBit%3] != 0) AddAccessAllowedAce(pAcl, ACL_REVISION, AceMasks [iBit%3], pSidTable [iBit/3]);
else if (AceMasks[iBit%3] != 0) AddAccessDeniedAce(pAcl, ACL_REVISION, AceMasks [iBit%3], pSidTable [iBit/3]);
}
/* Добавить запрет доступа для всех АСЕ категории "Прочие". */
Success = Success && AddAccessDeniedAce(pAcl, ACL_REVISION, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, pSidTable[2]);
/* Связать ACL с атрибутом защиты. */
SetSecurityDescriptorDacl(pSD, TRUE, pAcl, FALSE);
return pSA;
} /* Конец блока try-except. */
__except(EXCEPTION_EXECUTE_HANDLER) { /* Освободить все ресурсы. */
if (SAHeap != NULL) HeapDestroy(SAHeap);
pSA = NULL;
}
return pSA;
}
Комментарии к программе 15.3
Хотя структура программы 15.3 и может показаться несложной, выполняемую ею операцию вряд ли можно назвать простой. Кроме того, программа иллюстрирует целый ряд моментов, заслуживающих внимания, которые касаются использования средств безопасности Windows.
• Необходимо распределить в памяти несколько областей, предназначенных для хранения нужной информации, например, идентификаторов SID. Эти области создаются в специально выделенной для этих целей куче, которая по завершении работы должна быть уничтожена вызывающей программой.
• В данном примере структура атрибутов безопасности относится к файлам, но она также может использоваться с другими объектами, например именованными каналами (глава 11). В программе 15.4 показано, как встроить такую структуру при работе с файлами.
• Для эмуляции поведения UNIX существенное значение имеет порядок следования элементов АСЕ. Обратите внимание на то, что АСЕ, разрешающие и запрещающие доступ, добавляются в ACL по мере обработки битов, кодирующих полномочия, в направлении слева (Owner/Read) направо (Everyone/Execute). Благодаря этому биты полномочий, заданные, например, кодом защиты 460 (в восьмеричном представлении), будут запрещать пользователю доступ по записи даже в том случае, если он входит в состав группы.
• Права доступа описываются в АСЕ такими значениями, как FILE_GENERIC_READ или FILE_GENERIC_WRITE, которые аналогичны флагам, используемым в функции CreateFile, хотя добавляются и другие флаги доступа, например SYNCHRONIZE. Эти права указываются в вызывающей программе (в данном случае в программе 15.1), чтобы обеспечить их соответствие объекту.
• Значение, определенное для константы ACL_SIZE, выбрано достаточно большим, чтобы выделенных для него разрядов хватило для хранения девяти элементов АСЕ. После того как мы рассмотрим программу 15.5, способ определения требуемого размера элемента данных станет для вас очевидным.
• В функции используются три SID, по одному для каждой из следующих категорий пользователей: User (Пользователь), Group (Группа) и Everyone (Прочие). Для получения имени, используемого в качестве аргумента при вызове функции LookupAccountName, используются три различные методики. Имя обычного пользователя поступает из функции GetUserName. Именем пользователя, относящегося к категории прочих пользователей, является Everyone в SidTypeWellknownGroup. Групповое имя должно предоставляться в виде аргумента командной строки и отыскиваться как SidTypeGroup. Для нахождения групп, которым принадлежит пользователь, требуются определенные сведения о дескрипторах процесса, и решить эту задачу вам предлагается в упражнении 15.12.
• В версии программы, находящейся на Web-сайте книги, в отличие от той, которая представлена здесь, большое внимание уделено проверке ошибок. В ней даже предусмотрена проверка действительности сгенерированных структур с помощью функций IsValidSecurityDescriptor, IsValidSid и IsValidAcl, названия которых говорят сами за себя. Указанное тестирование ошибок оказалось чрезвычайно полезным на стадии отладки.
Чтение и изменение дескрипторов безопасности
После того как дескриптор безопасности связан с файлом, следующим шагом является определение кода защиты существующего файла и его возможное изменение. Для получения и установления кода защиты файла в терминах дескрипторов безопасности используются следующие функции:
BOOL GetFileSecurity(LPCTSTR lpFileName, SECURITY_INFORMATION secInfo, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD cbSd, LPDWORD lpcbLengthNeeded)
BOOL SetFileSecurity(LPCTSTR lpFileName, SECURITY_INFORMATION secInfo, PSECURITY_DESCRIPTOR pSecurityDescriptor)
Переменная secInfo имеет тип перечисления и принимает значения:
OWNER_SECURITY_INFORMATION
GROUP_SECURITY_INFORMATION
DACL_SECURITY_INFORMATION
SACL_SECURITY_INFORMATION
которые позволяют указать, какую часть дескриптора безопасности необходимо получить или установить. Эти значения могут объединяться при помощи поразрядной операции "или".
Наилучшим способом определения необходимого размера возвращаемого буфера для функции GetFileSecurity является двукратный вызов этой функции. Во время первого вызова значение параметра cbSd может быть задано равным 0. После того как буфер выделен, вызовите эту функцию второй раз. Этот принцип применяется в программе 15.4.
Вряд ли следует подчеркивать тот факт, что для выполнения этих операций требуются соответствующие полномочия. Так, для успешного выполнения функции SetFileSecurity необходимо либо иметь полномочия на уровне WRITE_DAC, либо быть владельцем объекта.
Функции GetSecurityDescriptorOwner и GetSecurityDescriptorGroup позволяют извлекать идентификаторы SID из дескриптора безопасности, полученного при помощи функции GetFileSecurity. Для получения ACL следует воспользоваться функцией GetSecurityDescriptorDacl.
BOOL GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, LPBOOL lpbDaclPresent, PACL *pAcl, LPBOOL lpbDaclDefaulted)
Параметры этой функции почти полностью совпадают с параметрами функции GetSecurityDescriptorDacl за исключением того, что возвращаются флаги,указывающие на то, действительно ли представлен разграничительный ACL и был ли он установлен по умолчанию или пользователем.
Чтобы иметь возможность интерпретировать список ACL, необходимо выяснить, сколько элементов АСЕ в нем содержится.
BOOL GetAclInformation(PACL pAcl, LPVOID pAclInformation, DWORD cbAclInfo, ACL INFORMATION CLASS dwAclInfoClass)
В большинстве случае параметр информационного класса ACL, dwAclInfoClass, равен AclSizeInformation, а параметр pAclInformation представляет собой структуру типа ACL_SIZE_INFORMATION. Другим возможным значением параметра класса является AclRevisionInformation.
В структуру ACL_SIZE_INFORMATION входят три элемента, наиболее важным из которых является AceCount, который указывает, сколько элементов содержится в списке. Чтобы выяснить, достаточно ли велик размер ACL, проверьте значения элементов AclBytesInUse и AclBytesFree структуры ACL_SIZE_INFORMATION.
Читать дальшеИнтервал:
Закладка: