|
|
#include "winnt.hxx"
#pragma hdrstop
WINNT_GROUP WinNTGroup;
//
// This assumes that addr is an LPBYTE type.
//
#define WORD_ALIGN_DOWN(addr) \
addr = ((LPBYTE)((DWORD_PTR)addr & ~1))
DWORD WinNTGroupStrings[]=
{ FIELD_OFFSET(WINNT_GROUP, Parent), FIELD_OFFSET(WINNT_GROUP, Computer), FIELD_OFFSET(WINNT_GROUP, Domain), FIELD_OFFSET(WINNT_GROUP, Name), 0xFFFFFFFF };
BOOL WinNTComputerOpen( LPWSTR szDomainName, LPWSTR szComputerName, ULONG uGroupParent, PHANDLE phComputer ) { WCHAR szTempBuffer[MAX_PATH]; PINICOMPUTER pIniComputer; HRESULT hr;
if (!phComputer || (szComputerName == NULL) ) { return(FALSE); }
pIniComputer = (PINICOMPUTER)AllocADsMem( sizeof(INICOMPUTER) ); if (!pIniComputer) { return(FALSE); }
hr = MakeUncName( szComputerName, szTempBuffer ); BAIL_ON_FAILURE(hr);
if (!(pIniComputer->szUncCompName = AllocADsStr(szTempBuffer))){ goto error; }
if (szDomainName != NULL) { if (!(pIniComputer->szDomainName = AllocADsStr(szDomainName))) { goto error; } }
if (!(pIniComputer->szComputerName = AllocADsStr(szComputerName))){ goto error; }
pIniComputer->uGroupParent = uGroupParent;
*phComputer = (HANDLE)pIniComputer;
return(TRUE);
error: if (pIniComputer) { FreeIniComputer(pIniComputer); }
*phComputer = NULL;
return(FALSE);
}
BOOL WinNTEnumGlobalGroups( HANDLE hComputer, DWORD dwRequested, LPBYTE * ppBuffer, PDWORD pdwReturned ) {
LPWINNT_GROUP * ppGroup = NULL; DWORD i = 0; BOOL dwRet = FALSE; DWORD dwReturned = 0; DWORD dwSize = 0; LPWINNT_GROUP pBuffer = NULL; LPBYTE pEnd = NULL; BOOL retVal = FALSE;
ppGroup = (LPWINNT_GROUP *)AllocADsMem( sizeof(LPWINNT_GROUP)* dwRequested ); if (!ppGroup) { return(FALSE); }
for (i = 0; i < dwRequested; i++) {
dwRet = WinNTComputerGetGlobalGroup( hComputer, &ppGroup[i] ); if (!dwRet) { break; }
}
dwReturned = i;
dwRet = ComputeWinNTGroupDataSize( ppGroup, dwReturned, &dwSize );
pBuffer = (LPWINNT_GROUP)AllocADsMem( dwSize ); if (pBuffer) {
retVal = TRUE;
pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
for (i = 0; i < dwReturned; i++) {
pEnd = CopyIniWinNTGroupToWinNTGroup( ppGroup[i], (LPBYTE)(pBuffer + i), pEnd ); } }
for (i = 0; i < dwReturned; i++ ) { FreeIntWinNTGroup(*(ppGroup + i)); }
FreeADsMem(ppGroup);
//
// Will assign to NULL correctly if alloc failed.
//
*ppBuffer = (LPBYTE)pBuffer; *pdwReturned = retVal ? dwReturned : 0;
if (!retVal) { return(FALSE); }
if (dwReturned == dwRequested){ return(TRUE); }else { return(FALSE); } }
BOOL WinNTComputerGetGlobalGroup( HANDLE hComputer, LPWINNT_GROUP * ppGroup ) { BOOL dwRet = FALSE; PINICOMPUTER pIniComp = (PINICOMPUTER)hComputer; NET_API_STATUS nasStatus = 0; GROUP_INFO_2 *pGroupInfo2 = NULL; LPSERVER_INFO_101 lpServerInfo =NULL; HRESULT hr = S_OK;
if ((!pIniComp->_pBuffer) || (pIniComp->_dwCurrentObject == pIniComp->_dwObjectReturned)) {
if (pIniComp->_bNoMore) {
//
// No more objects to return
//
return(FALSE); }
if (pIniComp->_pBuffer) { NetApiBufferFree(pIniComp->_pBuffer); pIniComp->_pBuffer = NULL; }
pIniComp->_dwObjectReturned = 0; pIniComp->_dwCurrentObject = 0; pIniComp->_dwTotalObjects = 0;
nasStatus = NetGroupEnum( pIniComp->szUncCompName, 2, &pIniComp->_pBuffer, MAX_PREFERRED_LENGTH, &pIniComp->_dwObjectReturned, &pIniComp->_dwTotalObjects, &pIniComp->_dwResumeHandle ); if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){ SetLastError(nasStatus); return(FALSE); }
if (nasStatus != ERROR_MORE_DATA) { pIniComp->_bNoMore = TRUE; }
pGroupInfo2 = (PGROUP_INFO_2) pIniComp->_pBuffer;
if ( (!pIniComp->_dwObjectReturned)) {
//
// We get success code (ERROR_SUCCESS) but the buffer was NULL:
// -> no global group was enumerated from the svr
//
return(FALSE);
} else if ( (1 == pIniComp->_dwTotalObjects) && (DOMAIN_GROUP_RID_USERS == pGroupInfo2->grpi2_group_id) ) { // check if this is the none group. Only returned by non-DCs.
nasStatus = NetServerGetInfo( pIniComp->szUncCompName, 101, (LPBYTE *)&lpServerInfo ); hr = HRESULT_FROM_WIN32(nasStatus); BAIL_ON_FAILURE(hr);
if(!( (lpServerInfo->sv101_type & SV_TYPE_DOMAIN_CTRL) || (lpServerInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) ) ) {
NetApiBufferFree(lpServerInfo); (pIniComp->_dwCurrentObject)++; return (FALSE); } else // it is a DC. Fall through.
; } }
dwRet = BuildWinNTGroupFromGlobalGroup( hComputer, (LPBYTE)((PGROUP_INFO_2) pIniComp->_pBuffer + pIniComp->_dwCurrentObject), ppGroup ); if (!dwRet) { goto error; }
pIniComp->_dwCurrentObject++;
if(lpServerInfo) NetApiBufferFree(lpServerInfo);
return(TRUE);
error:
if(lpServerInfo) NetApiBufferFree(lpServerInfo);
return(FALSE); }
BOOL WinNTEnumLocalGroups( HANDLE hComputer, DWORD dwRequested, LPBYTE * ppBuffer, PDWORD pdwReturned ) {
LPWINNT_GROUP * ppGroup = NULL; DWORD i = 0; BOOL dwRet = FALSE; DWORD dwReturned = 0; DWORD dwSize = 0; LPWINNT_GROUP pBuffer = NULL; LPBYTE pEnd = NULL; BOOL fretVal = FALSE;
ppGroup = (LPWINNT_GROUP *)AllocADsMem( sizeof(LPWINNT_GROUP)* dwRequested ); if (!ppGroup) { return(FALSE); }
for (i = 0; i < dwRequested; i++) {
dwRet = WinNTComputerGetLocalGroup( hComputer, &ppGroup[i] ); if (!dwRet) { break; }
}
dwReturned = i;
dwRet = ComputeWinNTGroupDataSize( ppGroup, dwReturned, &dwSize );
pBuffer = (LPWINNT_GROUP)AllocADsMem( dwSize );
if (pBuffer) {
fretVal = TRUE; pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
for (i = 0; i < dwReturned; i++) {
pEnd = CopyIniWinNTGroupToWinNTGroup( ppGroup[i], (LPBYTE)(pBuffer + i), pEnd ); } }
for (i = 0; i < dwReturned; i++ ) { FreeIntWinNTGroup(*(ppGroup + i)); }
FreeADsMem(ppGroup);
//
// Will correctly assign to NULL if alloc failed.
//
*ppBuffer = (LPBYTE)pBuffer; *pdwReturned = fretVal ? dwReturned : 0;
if (!fretVal) { return(FALSE); }
if (dwReturned == dwRequested){ return(TRUE); }else { return(FALSE); } }
BOOL WinNTComputerGetLocalGroup( HANDLE hComputer, LPWINNT_GROUP * ppGroup ) { BOOL dwRet = FALSE; PINICOMPUTER pIniComp = (PINICOMPUTER)hComputer; NET_API_STATUS nasStatus = 0; LPGROUP_INFO_0 pGroupInfo0 = NULL;
if ((!pIniComp->_pBuffer) || (pIniComp->_dwCurrentObject == pIniComp->_dwObjectReturned)) {
if (pIniComp->_bNoMore) {
//
// No more objects to return
//
return(FALSE); }
if (pIniComp->_pBuffer) { NetApiBufferFree(pIniComp->_pBuffer); pIniComp->_pBuffer = NULL; }
pIniComp->_dwObjectReturned = 0; pIniComp->_dwCurrentObject = 0; pIniComp->_dwTotalObjects = 0;
nasStatus = NetLocalGroupEnum( pIniComp->szUncCompName, 0, &pIniComp->_pBuffer, MAX_PREFERRED_LENGTH, &pIniComp->_dwObjectReturned, &pIniComp->_dwTotalObjects, &pIniComp->_dwResumeHandle ); if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){ SetLastError(nasStatus); return(FALSE); }
if (nasStatus != ERROR_MORE_DATA) { pIniComp->_bNoMore = TRUE; }
pGroupInfo0 = (LPGROUP_INFO_0) pIniComp->_pBuffer;
if ( (!pIniComp->_dwObjectReturned)) {
//
// We get success code (ERROR_SUCCESS) but the buffer was NULL:
// -> no global group was enumerated from the svr
//
return(FALSE); }
// we will never get none group as a local group
}
dwRet = BuildWinNTGroupFromLocalGroup( hComputer, (LPBYTE)((LPLOCALGROUP_INFO_0)pIniComp->_pBuffer + pIniComp->_dwCurrentObject), ppGroup ); if (!dwRet) { goto error; }
pIniComp->_dwCurrentObject++;
return(TRUE);
error:
return(FALSE); }
LPBYTE CopyIniWinNTGroupToWinNTGroup( LPWINNT_GROUP pIntGrp, LPBYTE pExtGrp, LPBYTE pEnd ) { LPWSTR SourceStrings[sizeof(WINNT_GROUP)/sizeof(LPWSTR)]; LPWSTR *pSourceStrings=SourceStrings; LPWINNT_GROUP pWinNTGrp = (LPWINNT_GROUP)pExtGrp;
memset(SourceStrings, 0, sizeof(WINNT_GROUP)); *pSourceStrings++ = pIntGrp->Parent; *pSourceStrings++ = pIntGrp->Computer; *pSourceStrings++ = pIntGrp->Domain; *pSourceStrings++ = pIntGrp->Name;
pEnd = PackStrings( SourceStrings, pExtGrp, WinNTGroupStrings, pEnd );
pWinNTGrp->Type = pIntGrp->Type;
return pEnd; }
BOOL BuildWinNTGroupFromGlobalGroup( HANDLE hComputer, LPBYTE lpBuffer, LPWINNT_GROUP * ppGroup ) { LPINICOMPUTER pComputer = (LPINICOMPUTER)hComputer; LPWINNT_GROUP pGroup = NULL; PGROUP_INFO_2 pGrp = (PGROUP_INFO_2)lpBuffer; WCHAR szADsParent[MAX_PATH]; LPWSTR pMemberName = NULL; DWORD cblen = 0;
pGroup = (LPWINNT_GROUP)AllocADsMem( sizeof(WINNT_GROUP) ); if (!pGroup) { return(FALSE); }
//
// Begin Global Group -> WinNT Group Mapping
//
pGroup->Name = AllocADsStr(pGrp->grpi2_name); pGroup->Computer = AllocADsStr(pComputer->szComputerName); pGroup->Domain = AllocADsStr(pComputer->szDomainName);
if (pComputer->uGroupParent == WINNT_DOMAIN_ID) { wsprintf( szADsParent, L"%s://%s", szProviderName, pComputer->szDomainName );
}else { wsprintf( szADsParent, L"%s://%s/%s", szProviderName, pComputer->szDomainName, pComputer->szComputerName ); } pGroup->Parent = AllocADsStr(szADsParent); pGroup->Type = WINNT_GROUP_GLOBAL;
//
// End Global Group -> WinNT Group Mapping
//
*ppGroup = pGroup; return(TRUE);
// error:
return(FALSE);
}
BOOL BuildWinNTGroupFromLocalGroup( HANDLE hComputer, LPBYTE lpBuffer, LPWINNT_GROUP * ppGroup ) { LPINICOMPUTER pComputer = (LPINICOMPUTER)hComputer; LPWINNT_GROUP pGroup = NULL; LPLOCALGROUP_INFO_0 pGrp = (LPLOCALGROUP_INFO_0)lpBuffer; WCHAR szADsParent[MAX_PATH]; LPWSTR pMemberName = NULL; DWORD cblen = 0;
pGroup = (LPWINNT_GROUP)AllocADsMem( sizeof(WINNT_GROUP) ); if (!pGroup) { return(FALSE); }
//
// Begin Local Group -> WinNT Group Mapping
//
pGroup->Name = AllocADsStr(pGrp->lgrpi0_name); pGroup->Computer = AllocADsStr(pComputer->szComputerName); pGroup->Domain = AllocADsStr(pComputer->szDomainName);
if (pComputer->uGroupParent == WINNT_DOMAIN_ID) { wsprintf( szADsParent, L"%s://%s", szProviderName, pComputer->szDomainName );
}else { if (pComputer->szDomainName !=NULL) {
wsprintf( szADsParent, L"%s://%s/%s", szProviderName, pComputer->szDomainName, pComputer->szComputerName ); } else { // This is a case where domain is null, the
// workstation service has not been started
wsprintf( szADsParent, L"%s://%s", szProviderName, pComputer->szComputerName ); } } pGroup->Parent = AllocADsStr(szADsParent); pGroup->Type = WINNT_GROUP_LOCAL;
//
// End Local Group -> WinNT Group Mapping
//
*ppGroup = pGroup; return(TRUE);
// error:
return(FALSE);
}
BOOL ComputeWinNTGroupDataSize( LPWINNT_GROUP * ppGroups, DWORD dwReturned, PDWORD pdwSize ) {
DWORD i = 0; DWORD cb = 0; LPWINNT_GROUP pGroup = NULL;
for (i = 0; i < dwReturned; i++) {
pGroup = *(ppGroups + i);
cb += sizeof(WINNT_GROUP);
if (pGroup->Parent) { cb += wcslen(pGroup->Parent)*sizeof(WCHAR) + sizeof(WCHAR); }
if (pGroup->Computer) { cb += wcslen(pGroup->Computer)*sizeof(WCHAR) + sizeof(WCHAR); }
if (pGroup->Domain) { cb += wcslen(pGroup->Domain)*sizeof(WCHAR) + sizeof(WCHAR); }
if (pGroup->Name) { cb += wcslen(pGroup->Name)*sizeof(WCHAR) + sizeof(WCHAR); } }
*pdwSize = cb; return(TRUE); }
BOOL WinNTCloseComputer( HANDLE hComputer ) { PINICOMPUTER pIniComputer = (PINICOMPUTER)hComputer;
if (pIniComputer) { FreeIniComputer(pIniComputer); } return(TRUE); }
void FreeIniComputer( PINICOMPUTER pIniComputer ) {
if (pIniComputer->szDomainName) {
FreeADsStr(pIniComputer->szDomainName); }
if (pIniComputer->szDomainName) {
FreeADsStr(pIniComputer->szComputerName); }
if (pIniComputer->szUncCompName) {
FreeADsStr(pIniComputer->szUncCompName); }
if (pIniComputer->_pBuffer) { NetApiBufferFree(pIniComputer->_pBuffer); }
FreeADsMem(pIniComputer);
return; }
void FreeIntWinNTGroup( LPWINNT_GROUP pGroup ) { if (pGroup->Parent) {
FreeADsStr(pGroup->Parent); }
if (pGroup->Computer) {
FreeADsStr(pGroup->Computer); }
if (pGroup->Domain) {
FreeADsStr(pGroup->Domain); }
if (pGroup->Name) {
FreeADsStr(pGroup->Name); }
if (pGroup) {
FreeADsMem(pGroup); }
return; }
|