windows-nt/Source/XPSP1/NT/ds/adsi/winnt/grput3.cxx
2020-09-26 16:20:57 +08:00

755 lines
16 KiB
C++

#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;
}