我知道NT标头的所有常量都定义为SE_TAKE_OWNERSHIP_NAME
,因此可以使用函数将它们转换为人类可读形式(Take ownership of files or other objects
)。
我的问题是如何枚举这些名字?对于不同版本的Windows,并非所有SE名称都适用(即特定NT系统上可能无法使用特权)。
虽然Windows7 / 2008确实是最新且适当的标题会列出所有这些 - 并且如果应用程序在较低的平台上运行,那么使用SE名称的函数如果给定给定名称将会失败操作系统不支持(如LsaEnumerateAccountsWithUserRight
会失败)。
但是如何使应用程序未来兼容,以便于列出未来版本的Windows操作系统的所有权限?
答案 0 :(得分:2)
使用LsaEnumeratePrivileges(在ntlsa.h中定义,位于WDK - inc / api中):
NTSTATUS
NTAPI
LsaEnumeratePrivileges(
__in LSA_HANDLE PolicyHandle,
__inout PLSA_ENUMERATION_HANDLE EnumerationContext,
__out PVOID *Buffer,
__in ULONG PreferedMaximumLength,
__out PULONG CountReturned
);
你得到的缓冲区是一个POLICY_PRIVILEGE_DEFINITION结构数组:
typedef struct _POLICY_PRIVILEGE_DEFINITION
{
LSA_UNICODE_STRING Name;
LUID LocalValue;
} POLICY_PRIVILEGE_DEFINITION, *PPOLICY_PRIVILEGE_DEFINITION;
例如:
#include <ntlsa.h>
NTSTATUS status;
LSA_HANDLE policyHandle;
LSA_ENUMERATION_HANDLE enumerationContext = 0;
PPOLICY_PRIVILEGE_DEFINITION buffer;
ULONG countReturned;
ULONG i;
LsaOpenPolicy(..., &policyHandle);
while (TRUE)
{
status = LsaEnumeratePrivileges(policyHandle, &enumerationContext, &buffer, 256, &countReturned);
if (status == STATUS_NO_MORE_ENTRIES)
break; // no more privileges
if (!NT_SUCCESS(status))
break; // error
for (i = 0; i < countReturned; i++)
{
// Privilege definition in buffer[i]
}
LsaFreeMemory(buffer);
}
LsaClose(policyHandle);
答案 1 :(得分:0)
工作代码:
#include <Windows.h>
#include <iostream>
#include <ntstatus.h>
typedef LONG NTSTATUS, *PNTSTATUS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING, *PSTRING;
typedef LARGE_INTEGER OLD_LARGE_INTEGER;
typedef LARGE_INTEGER POLD_LARGE_INTEGER;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#include <ntlsa.h>
LSA_HANDLE GetPolicyHandle() {
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS ntsResult;
LSA_HANDLE lsahPolicyHandle;
// Object attributes are reserved, so initialize to zeros.
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
// Get a handle to the Policy object.
ntsResult = LsaOpenPolicy(NULL, // Name of the target system.
&ObjectAttributes, // Object attributes.
POLICY_ALL_ACCESS, // Desired access permissions.
&lsahPolicyHandle // Receives the policy handle.
);
if (ntsResult != STATUS_SUCCESS) {
// An error occurred. Display it as a win32 error code.
wprintf(L"OpenPolicy returned %lu\n", LsaNtStatusToWinError(ntsResult));
return NULL;
}
return lsahPolicyHandle;
}
void main() {
NTSTATUS status;
LSA_HANDLE policyHandle;
LSA_ENUMERATION_HANDLE enumerationContext = 0;
PPOLICY_PRIVILEGE_DEFINITION buffer;
ULONG countReturned;
ULONG i;
policyHandle = GetPolicyHandle();
while (TRUE) {
status = LsaEnumeratePrivileges(policyHandle, &enumerationContext,
(PVOID *)&buffer, 256, &countReturned);
if (status == STATUS_NO_MORE_ENTRIES)
break; // no more privileges
if (!NT_SUCCESS(status))
break; // error
for (i = 0; i < countReturned; i++) {
// Privilege definition in buffer[i]
std::wcout << L"KEY:" << buffer[i].Name.Buffer << L" HIGH VALUE:"
<< buffer[i].LocalValue.HighPart << L"LOW VALUE:"
<< buffer[i].LocalValue.LowPart << std::endl;
}
LsaFreeMemory(buffer);
}
LsaClose(policyHandle);
}