| Platform SDK: Active Directory, ADSI, and Directory Services |
The following code fragment is a function that checks whether the currently logged-on user has permissions for an extended right on the specified object:
// Define the Generic Mapping structure.
// generic read
#define GENERIC_READ_MAPPING ((STANDARD_RIGHTS_READ) | \
(ADS_RIGHT_ACTRL_DS_LIST) | \
(ADS_RIGHT_DS_READ_PROP) | \
(ADS_RIGHT_DS_LIST_OBJECT))
// generic execute
#define GENERIC_EXECUTE_MAPPING ((STANDARD_RIGHTS_EXECUTE) | \
(ADS_RIGHT_ACTRL_DS_LIST))
// generic right
#define GENERIC_WRITE_MAPPING ((STANDARD_RIGHTS_WRITE) | \
(ADS_RIGHT_DS_SELF) | \
(ADS_RIGHT_DS_WRITE_PROP))
// generic all
#define GENERIC_ALL_MAPPING ((STANDARD_RIGHTS_REQUIRED) | \
(ADS_RIGHT_DS_CREATE_CHILD) | \
(ADS_RIGHT_DS_DELETE_CHILD) | \
(ADS_RIGHT_DS_DELETE_TREE) | \
(ADS_RIGHT_DS_READ_PROP) | \
(ADS_RIGHT_DS_WRITE_PROP) | \
(ADS_RIGHT_ACTRL_DS_LIST) | \
(ADS_RIGHT_DS_LIST_OBJECT) | \
(ADS_RIGHT_DS_CONTROL_ACCESS) | \
(ADS_RIGHT_DS_SELF))
// Standard DS generic access rights mapping
#define DS_GENERIC_MAPPING {GENERIC_READ_MAPPING, \
GENERIC_WRITE_MAPPING, \
GENERIC_EXECUTE_MAPPING, \
GENERIC_ALL_MAPPING}
HRESULT CheckExtendedRight(
HANDLE hToken,
IDirectoryObject *pObject,
LPOLESTR pszRightsGUID,
DWORD *dwAccess
)
{
HRESULT hr = E_FAIL;
*dwAccess = FALSE;
BOOL bSuccess = FALSE;
PADS_ATTR_INFO pAttrInfo = NULL;
DWORD dwReturn= 0;
LPWSTR pAttrNames[]= {L"nTSecurityDescriptor",L"objectSid"};
PSECURITY_DESCRIPTOR pSD = NULL;
DWORD SDSize;
VOID *pAbsoluteSD = NULL;
DWORD AbsoluteSDSize = 0;
VOID *pDacl = NULL;
DWORD DaclSize = 0;
VOID *pSacl = NULL;
DWORD SaclSize = 0;
VOID *pOwner = NULL;
DWORD OwnerSize = 0;
VOID *pGroup = NULL;
DWORD GroupSize = 0;
PSID pSID = NULL;
// Get attributes for security descriptor and SID
hr = pObject->GetObjectAttributes( pAttrNames,
2,
&pAttrInfo,
&dwReturn );
if ( (SUCCEEDED(hr)) && (dwReturn>0) )
{
for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ )
{
//Check the attribute name
if ( _wcsicmp(pAttrInfo->pszAttrName,L"nTSecurityDescriptor") == 0 )
{
//Check the attribute type.
if (pAttrInfo->dwADsType==ADSTYPE_NT_SECURITY_DESCRIPTOR)
{
pSD = (PSECURITY_DESCRIPTOR)(pAttrInfo->pADsValues->SecurityDescriptor.lpValue);
SDSize = (pAttrInfo->pADsValues->SecurityDescriptor.dwLength);
}
}
if ( _wcsicmp(pAttrInfo->pszAttrName,L"objectSID") == 0 )
{
//Check the attribute type.
if (pAttrInfo->dwADsType==ADSTYPE_OCTET_STRING)
{
pSID = (PSID)(pAttrInfo->pADsValues->OctetString.lpValue);
}
}
}
OBJECT_TYPE_LIST sObjectList;
sObjectList.Level = ACCESS_OBJECT_GUID;
sObjectList.Sbz = 0;
CLSID pclsid;
//Make the rightsGUID string the right format
//for conversion with the COM conversion functions.
LPOLESTR pszGUID = new OLECHAR[MAX_PATH];
wcscpy(pszGUID, L"{");
wcscat(pszGUID, pszRightsGUID);
wcscat(pszGUID, L"}");
hr = CLSIDFromString(
pszGUID, //Pointer to the string representation of the CLSID
&pclsid //Pointer to the CLSID
);
if (SUCCEEDED(hr))
{
sObjectList.ObjectType = (GUID*)&pclsid;
}
else
return E_FAIL;
CHAR PrivilegeSetBuffer[256];
PRIVILEGE_SET *PrivilegeSet = (PRIVILEGE_SET *)PrivilegeSetBuffer;
DWORD dwPrivSetSize = sizeof( PrivilegeSetBuffer );
DWORD GrantedAccess = 0;
ZeroMemory(PrivilegeSetBuffer, 256);
DWORD DesiredAccess = ADS_RIGHT_DS_CONTROL_ACCESS;
// Use the GENERIC_MAPPING structure to convert any
// generic access rights to object-specific access rights.
GENERIC_MAPPING GenericMapping = DS_GENERIC_MAPPING;
// Before calling AccessCheck, a convert must be done
// security descriptor into Absolute form.
if( ! MakeAbsoluteSD(
pSD,
(PSECURITY_DESCRIPTOR)pAbsoluteSD,
&AbsoluteSDSize,
(PACL)pDacl,
&DaclSize,
(PACL)pSacl,
&SaclSize,
(PSID)pOwner,
&OwnerSize,
(PSID)pGroup,
&GroupSize
))
{
pAbsoluteSD = (PSECURITY_DESCRIPTOR)LocalAlloc(0,AbsoluteSDSize);
if(!pAbsoluteSD)
{
// TODO: handle this.
}
pDacl = (PACL)LocalAlloc(0,DaclSize);
if(!pDacl)
{
// TODO: handle this.
}
pSacl = (PACL)LocalAlloc(0,SaclSize);
if(!pSacl)
{
// TODO: handle this.
}
pOwner = (PSID)LocalAlloc(0,OwnerSize);
if(!pOwner)
{
// TODO: handle this.
}
pGroup = (PSID)LocalAlloc(0,GroupSize);
if(!pGroup)
{
// TODO: handle this.
}
if( ! MakeAbsoluteSD(
pSD,
(PSECURITY_DESCRIPTOR)pAbsoluteSD,
&AbsoluteSDSize,
(PACL)pDacl,
&DaclSize,
(PACL)pSacl,
&SaclSize,
(PSID)pOwner,
&OwnerSize,
(PSID)pGroup,
&GroupSize
))
{
//
// TODO: handle this
//
//Clean up and return
if (pAttrInfo)
FreeADsMem( pAttrInfo );
return E_FAIL;
}
}
bSuccess = AccessCheckByTypeResultList(
pSD, // security descriptor
pSID, // SID of object being checked
hToken, // handle to client access token
DesiredAccess, // requested access rights
&sObjectList, // array of object types
1, // number of object type elements
&GenericMapping, // map generic to specific rights
PrivilegeSet, // receives privileges used
&dwPrivSetSize, // size of privilege-set buffer
&GrantedAccess, // retrieves mask of granted rights
dwAccess // retrieves results of access check
);
//Check if access check function call succeeded.
if(bSuccess)
{
hr = S_OK;
}
else
hr = E_FAIL;
}
// Use FreeADsMem for all memory obtained from ADSI call
if (pAttrInfo)
FreeADsMem( pAttrInfo );
return hr;
}