|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1997.
//
// File: sec2var.cxx
//
// Contents:
//
// Functions:
//
// History: 25-Apr-97 KrishnaG Created.
//
//----------------------------------------------------------------------------
#include "iis.hxx"
#pragma hdrstop
HRESULT ConvertSidToString( PSID pSid, LPWSTR String );
HRESULT ConvertSecDescriptorToVariant( PSECURITY_DESCRIPTOR pSecurityDescriptor, VARIANT * pVarSec ) { IADsSecurityDescriptor * pSecDes = NULL; IDispatch * pDispatch = NULL; LPWSTR pszGroup = NULL; LPWSTR pszOwner = NULL;
BOOL fOwnerDefaulted = 0; BOOL fGroupDefaulted = 0; BOOL fDaclDefaulted = 0; BOOL fSaclDefaulted = 0;
BOOL fSaclPresent = 0; BOOL fDaclPresent = 0;
LPBYTE pOwnerSidAddress = NULL; LPBYTE pGroupSidAddress = NULL; LPBYTE pDACLAddress = NULL; LPBYTE pSACLAddress = NULL;
DWORD dwRet = 0;
VARIANT varDACL; VARIANT varSACL;
HRESULT hr = S_OK;
DWORD dwRevision = 0; WORD wControl = 0;
VariantInit(pVarSec); memset(&varSACL, 0, sizeof(VARIANT)); memset(&varDACL, 0, sizeof(VARIANT));
if (!pSecurityDescriptor) { RRETURN(E_FAIL); }
dwRet = GetSecurityDescriptorControl( pSecurityDescriptor, &wControl, &dwRevision ); if (!dwRet){ hr = HRESULT_FROM_WIN32(GetLastError()); BAIL_ON_FAILURE(hr); }
dwRet = GetSecurityDescriptorOwner( pSecurityDescriptor, (PSID *)&pOwnerSidAddress, &fOwnerDefaulted ); if (!dwRet){ hr = HRESULT_FROM_WIN32(GetLastError()); BAIL_ON_FAILURE(hr); }
hr = ConvertSidToFriendlyName( pOwnerSidAddress, &pszOwner ); BAIL_ON_FAILURE(hr);
dwRet = GetSecurityDescriptorGroup( pSecurityDescriptor, (PSID *)&pGroupSidAddress, &fGroupDefaulted );
if (!dwRet){ hr = HRESULT_FROM_WIN32(GetLastError()); BAIL_ON_FAILURE(hr); }
hr = ConvertSidToFriendlyName( pGroupSidAddress, &pszGroup ); BAIL_ON_FAILURE(hr);
dwRet = GetSecurityDescriptorDacl( pSecurityDescriptor, &fDaclPresent, (PACL*)&pDACLAddress, &fDaclDefaulted );
if (pDACLAddress) { hr = ConvertACLToVariant( (PACL)pDACLAddress, &varDACL ); BAIL_ON_FAILURE(hr); }
dwRet = GetSecurityDescriptorSacl( pSecurityDescriptor, &fSaclPresent, (PACL *)&pSACLAddress, &fSaclDefaulted );
if (!dwRet){ hr = HRESULT_FROM_WIN32(GetLastError()); BAIL_ON_FAILURE(hr); }
if (pSACLAddress) { hr = ConvertACLToVariant( (PACL)pSACLAddress, &varSACL ); BAIL_ON_FAILURE(hr); }
hr = CoCreateInstance( CLSID_SecurityDescriptor, NULL, CLSCTX_INPROC_SERVER, IID_IADsSecurityDescriptor, (void **)&pSecDes ); BAIL_ON_FAILURE(hr);
hr = pSecDes->put_Owner(pszOwner);
hr = pSecDes->put_Group(pszGroup);
hr = pSecDes->put_Revision(dwRevision);
hr = pSecDes->put_Control((DWORD)wControl);
hr = pSecDes->put_DiscretionaryAcl(V_DISPATCH(&varDACL));
hr = pSecDes->put_SystemAcl(V_DISPATCH(&varSACL));
hr = pSecDes->QueryInterface(IID_IDispatch, (void**)&pDispatch); BAIL_ON_FAILURE(hr);
V_VT(pVarSec) = VT_DISPATCH; V_DISPATCH(pVarSec) = pDispatch;
error:
VariantClear(&varSACL); VariantClear(&varDACL);
if (pszOwner) { FreeADsStr(pszOwner); }
if (pszGroup) { FreeADsStr(pszGroup); }
if (pSecDes) { pSecDes->Release(); }
RRETURN(hr); }
HRESULT ConvertSidToFriendlyName( PSID pSid, LPWSTR * ppszAccountName ) { HRESULT hr = S_OK; SID_NAME_USE eUse; WCHAR szAccountName[MAX_PATH]; WCHAR szDomainName[MAX_PATH]; DWORD dwLen = 0; DWORD dwRet = 0;
LPWSTR pszAccountName = NULL;
DWORD dwAcctLen = 0; DWORD dwDomainLen = 0;
dwAcctLen = sizeof(szAccountName); dwDomainLen = sizeof(szDomainName);
dwRet = LookupAccountSid( NULL, pSid, szAccountName, &dwAcctLen, szDomainName, &dwDomainLen, (PSID_NAME_USE)&eUse ); if (!dwRet) { hr = HRESULT_FROM_WIN32(GetLastError()); }else {
dwLen = (DWORD)(wcslen(szAccountName) + wcslen(szDomainName)) + 1 + 1;
pszAccountName = (LPWSTR)AllocADsMem(dwLen * sizeof(WCHAR)); if (!pszAccountName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
if (szDomainName[0] && szAccountName[0]) { wsprintf(pszAccountName,L"%s\\%s",szDomainName, szAccountName); }else if (szAccountName[0]) {
if (wcslen(szAccountName)>=MAX_PATH) { hr = E_ADS_BAD_PARAMETER; BAIL_ON_FAILURE(hr); } wcscpy(pszAccountName, szAccountName); } }
if (FAILED(hr)) {
hr = ConvertSidToString( pSid, szAccountName ); BAIL_ON_FAILURE(hr);
pszAccountName = AllocADsStr(szAccountName); if (!pszAccountName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } }
*ppszAccountName = pszAccountName;
error:
RRETURN(hr); }
HRESULT ConvertACLToVariant( PACL pACL, PVARIANT pvarACL ) { IADsAccessControlList * pAccessControlList = NULL; IDispatch * pDispatch = NULL;
VARIANT varAce; DWORD dwAclSize = 0; DWORD dwAclRevision = 0; DWORD dwAceCount = 0;
ACL_SIZE_INFORMATION AclSize; ACL_REVISION_INFORMATION AclRevision; DWORD dwStatus = 0;
DWORD i = 0; DWORD dwNewAceCount = 0;
HRESULT hr = S_OK; LPBYTE pAceAddress = NULL;
memset(&AclSize, 0, sizeof(ACL_SIZE_INFORMATION)); memset(&AclRevision, 0, sizeof(ACL_REVISION_INFORMATION));
dwStatus = GetAclInformation( pACL, &AclSize, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation );
dwStatus = GetAclInformation( pACL, &AclRevision, sizeof(ACL_REVISION_INFORMATION), AclRevisionInformation );
dwAceCount = AclSize.AceCount; dwAclRevision = AclRevision.AclRevision;
VariantInit(pvarACL);
hr = CoCreateInstance( CLSID_AccessControlList, NULL, CLSCTX_INPROC_SERVER, IID_IADsAccessControlList, (void **)&pAccessControlList ); BAIL_ON_FAILURE(hr);
for (i = 0; i < dwAceCount; i++) {
dwStatus = GetAce(pACL, i, (void **)&pAceAddress);
hr = ConvertAceToVariant( pAceAddress, (PVARIANT)&varAce );
hr = pAccessControlList->AddAce(V_DISPATCH(&varAce)); if (SUCCEEDED(hr)) { dwNewAceCount++; }
VariantClear(&varAce); }
pAccessControlList->put_AclRevision(dwAclRevision);
pAccessControlList->put_AceCount(dwNewAceCount);
hr = pAccessControlList->QueryInterface( IID_IDispatch, (void **)&pDispatch ); V_VT(pvarACL) = VT_DISPATCH; V_DISPATCH(pvarACL) = pDispatch;
error:
if (pAccessControlList) {
pAccessControlList->Release(); }
RRETURN(hr); }
/* INTRINSA suppress=null_pointers, uninitialized */ HRESULT ConvertAceToVariant( PBYTE pAce, PVARIANT pvarAce ) { IADsAccessControlEntry * pAccessControlEntry = NULL; IDispatch * pDispatch = NULL;
DWORD dwAceType = 0; DWORD dwAceFlags = 0; DWORD dwAccessMask = 0; LPWSTR pszAccountName = NULL; PACE_HEADER pAceHeader = NULL; LPBYTE pSidAddress = NULL; LPBYTE pOffset = NULL; DWORD dwFlags = 0;
GUID ObjectGUID; GUID InheritedObjectGUID; WCHAR szObjectGUID[MAX_PATH]; WCHAR szInheritedObjectGUID[MAX_PATH];
HRESULT hr = S_OK;
szObjectGUID[0] = L'\0'; szInheritedObjectGUID[0] = L'\0';
VariantInit(pvarAce);
hr = CoCreateInstance( CLSID_AccessControlEntry, NULL, CLSCTX_INPROC_SERVER, IID_IADsAccessControlEntry, (void **)&pAccessControlEntry ); BAIL_ON_FAILURE(hr);
pAceHeader = (ACE_HEADER *)pAce;
dwAceType = pAceHeader->AceType; dwAceFlags = pAceHeader->AceFlags; dwAccessMask = *(PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
switch (dwAceType) {
case ACCESS_ALLOWED_ACE_TYPE: case ACCESS_DENIED_ACE_TYPE: case SYSTEM_AUDIT_ACE_TYPE: case SYSTEM_ALARM_ACE_TYPE: pSidAddress = (LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK); break;
case ACCESS_ALLOWED_OBJECT_ACE_TYPE: case ACCESS_DENIED_OBJECT_ACE_TYPE: case SYSTEM_AUDIT_OBJECT_ACE_TYPE: case SYSTEM_ALARM_OBJECT_ACE_TYPE: pOffset = (LPBYTE)((LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK)); dwFlags = (DWORD)(*(PDWORD)pOffset);
//
// Now advance by the size of the flags
//
pOffset += sizeof(ULONG);
if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
memcpy(&ObjectGUID, pOffset, sizeof(GUID));
StringFromGUID2(ObjectGUID, szObjectGUID, MAX_PATH);
pOffset += sizeof (GUID);
}
if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { memcpy(&InheritedObjectGUID, pOffset, sizeof(GUID));
StringFromGUID2(InheritedObjectGUID, szInheritedObjectGUID, MAX_PATH);
pOffset += sizeof (GUID);
}
pSidAddress = pOffset; break;
default: break;
}
hr = ConvertSidToFriendlyName( pSidAddress, &pszAccountName );
if (FAILED(hr)){ pszAccountName = AllocADsStr(L"Unknown Trustee"); }
//
// Now set all the information in the Access Control Entry
//
hr = pAccessControlEntry->put_AccessMask(dwAccessMask); hr = pAccessControlEntry->put_AceFlags(dwAceFlags); hr = pAccessControlEntry->put_AceType(dwAceType);
//
// Extended ACE information
//
hr = pAccessControlEntry->put_Flags(dwFlags);
if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
//
// Add in the Object Type GUID
//
hr = pAccessControlEntry->put_ObjectType(szObjectGUID);
}
if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
//
// Add in the Inherited Object Type GUID
//
hr = pAccessControlEntry->put_InheritedObjectType(szInheritedObjectGUID);
}
hr = pAccessControlEntry->put_Trustee(pszAccountName);
hr = pAccessControlEntry->QueryInterface( IID_IDispatch, (void **)&pDispatch ); BAIL_ON_FAILURE(hr);
V_DISPATCH(pvarAce) = pDispatch; V_VT(pvarAce) = VT_DISPATCH;
cleanup:
if (pszAccountName) {
FreeADsStr(pszAccountName); }
if (pAccessControlEntry) {
pAccessControlEntry->Release(); }
RRETURN(hr);
error:
if (pDispatch) {
pDispatch->Release();
}
goto cleanup; }
HRESULT ConvertSidToString( PSID pSid, LPWSTR String )
/*++
Routine Description:
This function generates a printable unicode string representation of a SID.
The resulting string will take one of two forms. If the IdentifierAuthority value is not greater than 2^32, then the SID will be in the form:
S-1-281736-12-72-9-110 ^ ^^ ^^ ^ ^^^ | | | | | +-----+--+-+--+---- Decimal
Otherwise it will take the form:
S-1-0x173495281736-12-72-9-110 ^^^^^^^^^^^^^^ ^^ ^^ ^ ^^^ Hexidecimal | | | | +--+-+--+---- Decimal
Arguments:
pSid - opaque pointer that supplies the SID that is to be converted to Unicode.
Return Value:
If the Sid is successfully converted to a Unicode string, a pointer to the Unicode string is returned, else NULL is returned.
--*/
{ WCHAR Buffer[256]; UCHAR i; ULONG Tmp; HRESULT hr = S_OK;
SID_IDENTIFIER_AUTHORITY *pSidIdentifierAuthority; PUCHAR pSidSubAuthorityCount;
if (!IsValidSid( pSid )) { *String= L'\0'; hr = HRESULT_FROM_WIN32(ERROR_INVALID_SID); RRETURN(hr); }
wsprintf(Buffer, L"S-%u-", (USHORT)(((PISID)pSid)->Revision )); wcscpy(String, Buffer);
pSidIdentifierAuthority = GetSidIdentifierAuthority(pSid);
if ( (pSidIdentifierAuthority->Value[0] != 0) || (pSidIdentifierAuthority->Value[1] != 0) ){ wsprintf(Buffer, L"0x%02hx%02hx%02hx%02hx%02hx%02hx", (USHORT)pSidIdentifierAuthority->Value[0], (USHORT)pSidIdentifierAuthority->Value[1], (USHORT)pSidIdentifierAuthority->Value[2], (USHORT)pSidIdentifierAuthority->Value[3], (USHORT)pSidIdentifierAuthority->Value[4], (USHORT)pSidIdentifierAuthority->Value[5] ); wcscat(String, Buffer);
} else {
Tmp = (ULONG)pSidIdentifierAuthority->Value[5] + (ULONG)(pSidIdentifierAuthority->Value[4] << 8) + (ULONG)(pSidIdentifierAuthority->Value[3] << 16) + (ULONG)(pSidIdentifierAuthority->Value[2] << 24); wsprintf(Buffer, L"%lu", Tmp); wcscat(String, Buffer); }
pSidSubAuthorityCount = GetSidSubAuthorityCount(pSid);
for (i=0;i< *(pSidSubAuthorityCount);i++ ) { wsprintf(Buffer, L"-%lu", *(GetSidSubAuthority(pSid, i))); wcscat(String, Buffer); }
RRETURN(S_OK);
}
|