Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

286 lines
9.5 KiB

//+----------------------------------------------------------------------------
//
// File: DumpSecInfo.cpp
//
// Module: as required
//
// Synopsis: Functions to help figure out Permissions issues. To fix "NULL DACL"
// security issues, or try and figure out permissions bugs, this module
// may be useful. Entry point is DumpAclInfo.
//
// Copyright (c) 1998-2001 Microsoft Corporation
//
// Author: SumitC Created 18-Dec-2000
//
//+----------------------------------------------------------------------------
#include "winbase.h"
#include "sddl.h"
//
// support for dynamically loading Advapi32 Security functions
//
HMODULE g_hAdvapi32 = NULL;
typedef BOOL (WINAPI *pfnLookupAccountSid) (LPCWSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE);
typedef BOOL (WINAPI *pfnGetUserObjectSecurity) (HANDLE, PSECURITY_INFORMATION, PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
typedef BOOL (WINAPI *pfnConvertSidToStringSid) (PSID, LPWSTR*);
typedef BOOL (WINAPI *pfnGetSecurityDescriptorOwner) (PSECURITY_DESCRIPTOR, PSID *, LPBOOL);
typedef BOOL (WINAPI *pfnGetSecurityDescriptorSacl) (PSECURITY_DESCRIPTOR, LPBOOL, PACL *, LPBOOL);
typedef BOOL (WINAPI *pfnGetSecurityDescriptorDacl) (PSECURITY_DESCRIPTOR, LPBOOL, PACL *, LPBOOL);
typedef BOOL (WINAPI *pfnGetAce) (PACL, DWORD, LPVOID *);
pfnLookupAccountSid g_pfnLookupAccountSid = NULL;
pfnGetUserObjectSecurity g_pfnGetUserObjectSecurity = NULL;
pfnConvertSidToStringSid g_pfnConvertSidToStringSid = NULL;
pfnGetSecurityDescriptorOwner g_pfnGetSecurityDescriptorOwner = NULL;
pfnGetSecurityDescriptorSacl g_pfnGetSecurityDescriptorSacl = NULL;
pfnGetSecurityDescriptorDacl g_pfnGetSecurityDescriptorDacl = NULL;
pfnGetAce g_pfnGetAce = NULL;
//+----------------------------------------------------------------------------
//
// Function: GetSidType
//
// Synopsis: Returns the string corresponding to a given SID type
//
// Arguments: [i] -- index representing the SID
//
// Returns: LPTSTR - static string containing a displayable Sid type
//
// Notes:
//
//-----------------------------------------------------------------------------
LPTSTR GetSidType(int i)
{
static LPTSTR szMap[] =
{
TEXT("User"),
TEXT("Group"),
TEXT("Domain"),
TEXT("Alias"),
TEXT("WellKnownGroup"),
TEXT("DeletedAccount"),
TEXT("Invalid"),
TEXT("Unknown"),
TEXT("Computer")
};
if (i >= 1 && i <= 9)
{
return szMap[i - 1];
}
else
{
return TEXT("");
}
}
//+----------------------------------------------------------------------------
//
// Function: DumpSid
//
// Synopsis: returns information for a give SID
//
// Arguments: [psid] -- ptr to SecurityID
// [pszBuffer] -- where to return SID string (caller must free)
//
// Returns: LPTSTR - ptr to pszBuffer if success, NULL if failure
//
// Notes:
//
//-----------------------------------------------------------------------------
LPTSTR DumpSid(PSID psid, LPTSTR pszBuffer)
{
LPTSTR pszSID = NULL;
TCHAR szName[MAX_PATH + 1];
DWORD cbName = MAX_PATH;
TCHAR szDomain[MAX_PATH + 1];
DWORD cbDomain = MAX_PATH;
SID_NAME_USE snu;
BOOL fDone = FALSE;
CMASSERTMSG(pszBuffer, TEXT("DumpSid - pszBuffer must be allocated by caller"));
if (g_pfnConvertSidToStringSid(psid, &pszSID) &&
g_pfnLookupAccountSid(NULL, psid, szName, &cbName, szDomain, &cbDomain, &snu))
{
wsprintf(pszBuffer, TEXT("%s\\%s %s %s"), szDomain, szName, GetSidType(snu), pszSID);
// looks like NTDEV\sumitc User xxxx-xxx-xxx-xxx
fDone = TRUE;
}
if (pszSID)
{
LocalFree(pszSID);
}
return fDone ? pszBuffer : NULL;
}
//+----------------------------------------------------------------------------
//
// Function: DumpAclInfo
//
// Synopsis: Dumps out all ACL info for a given object
//
// Arguments: [h] -- handle to object about which info is needed
//
// Returns: (void)
//
// Notes:
//
//-----------------------------------------------------------------------------
void DumpAclInfo(HANDLE h)
{
if (!OS_NT)
{
CMTRACE(TEXT("DumpAclInfo will not work on 9x systems"));
return;
}
TCHAR szBuf[MAX_PATH];
SECURITY_INFORMATION si = 0;
//
// dynamically pick up the DLLs we need
//
g_hAdvapi32 = LoadLibrary(TEXT("ADVAPI32.DLL"));
if (NULL == g_hAdvapi32)
{
CMTRACE(TEXT("DumpAclInfo: failed to load advapi32.dll"));
return;
}
g_pfnLookupAccountSid = (pfnLookupAccountSid) GetProcAddress(g_hAdvapi32, "LookupAccountSidW");
g_pfnGetUserObjectSecurity = (pfnGetUserObjectSecurity) GetProcAddress(g_hAdvapi32, "GetUserObjectSecurity");
g_pfnConvertSidToStringSid = (pfnConvertSidToStringSid) GetProcAddress(g_hAdvapi32, "ConvertSidToStringSidW");
g_pfnGetSecurityDescriptorOwner = (pfnGetSecurityDescriptorOwner) GetProcAddress(g_hAdvapi32, "GetSecurityDescriptorOwner");
g_pfnGetSecurityDescriptorSacl = (pfnGetSecurityDescriptorSacl) GetProcAddress(g_hAdvapi32, "GetSecurityDescriptorSacl");
g_pfnGetSecurityDescriptorDacl = (pfnGetSecurityDescriptorDacl) GetProcAddress(g_hAdvapi32, "GetSecurityDescriptorDacl");
g_pfnGetAce = (pfnGetAce) GetProcAddress(g_hAdvapi32, "GetAce");
if (!(g_pfnLookupAccountSid && g_pfnGetUserObjectSecurity &&
g_pfnConvertSidToStringSid && g_pfnGetSecurityDescriptorOwner &&
g_pfnGetSecurityDescriptorSacl && g_pfnGetSecurityDescriptorDacl &&
g_pfnGetAce))
{
CMTRACE(TEXT("DumpAclInfo: failed to load required functions in advapi32.dll"));
goto Cleanup;
}
//
// dump information on the ACL
//
DWORD dw;
si |= OWNER_SECURITY_INFORMATION;
si |= DACL_SECURITY_INFORMATION;
if (!g_pfnGetUserObjectSecurity(h, &si, NULL, 0, &dw) &&
ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
PSECURITY_DESCRIPTOR pSD = NULL;
pSD = (PSECURITY_DESCRIPTOR) CmMalloc(dw);
if (g_pfnGetUserObjectSecurity(h, &si, pSD, dw, &dw))
{
// get the owner
PSID psidOwner;
BOOL fDefaulted;
if (g_pfnGetSecurityDescriptorOwner(pSD, &psidOwner, &fDefaulted))
{
CMTRACE1(TEXT("SIDINFO: Owner is: %s"), DumpSid(psidOwner, szBuf));
}
PACL pacl;
BOOL fPresent;
int i;
g_pfnGetSecurityDescriptorSacl(pSD, &fPresent, &pacl, &fDefaulted);
CMTRACE1(TEXT("sacl gle=%d"), GetLastError());
if (fPresent)
{
CMTRACE(TEXT("SIDINFO: found a SACL"));
// has a SACL
void * pv;
for (i = 0 ; i < 15; ++i)
{
if (g_pfnGetAce(pacl, i, &pv))
{
// try access allowed ace
//
ACCESS_ALLOWED_ACE * pACE = (ACCESS_ALLOWED_ACE *)pv;
if (pACE->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
{
CMTRACE1(TEXT("SIDINFO: allowed is: %s"), DumpSid(&(pACE->SidStart), szBuf));
}
else
{
ACCESS_DENIED_ACE * pACE = (ACCESS_DENIED_ACE *)pv;
if (pACE->Header.AceType == ACCESS_DENIED_ACE_TYPE)
{
CMTRACE1(TEXT("SIDINFO: denied is: %s"), DumpSid(&(pACE->SidStart), szBuf));
}
}
}
}
}
g_pfnGetSecurityDescriptorDacl(pSD, &fPresent, &pacl, &fDefaulted);
CMTRACE1(TEXT("dacl gle=%d"), GetLastError());
if (fPresent)
{
CMTRACE(TEXT("SIDINFO: found a DACL"));
// has a DACL
void * pv;
for (i = 0 ; i < 15; ++i)
{
if (g_pfnGetAce(pacl, i, &pv))
{
// try access allowed ace
//
ACCESS_ALLOWED_ACE * pACE = (ACCESS_ALLOWED_ACE *)pv;
if (pACE->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
{
CMTRACE1(TEXT("SIDINFO: allowed is: %s"), DumpSid(&(pACE->SidStart), szBuf));
}
else
{
ACCESS_DENIED_ACE * pACE = (ACCESS_DENIED_ACE *)pv;
if (pACE->Header.AceType == ACCESS_DENIED_ACE_TYPE)
{
CMTRACE1(TEXT("SIDINFO: denied is: %s"), DumpSid(&(pACE->SidStart), szBuf));
}
}
}
}
}
}
CmFree(pSD);
}
Cleanup:
if (g_hAdvapi32)
{
FreeLibrary(g_hAdvapi32);
g_hAdvapi32 = NULL;
g_pfnLookupAccountSid = NULL;
g_pfnGetUserObjectSecurity = NULL;
g_pfnConvertSidToStringSid = NULL;
g_pfnGetSecurityDescriptorOwner = NULL;
g_pfnGetSecurityDescriptorSacl = NULL;
g_pfnGetSecurityDescriptorDacl = NULL;
g_pfnGetAce = NULL;
}
}