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

550 lines
13 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: usrutils.cxx
//
// Contents: NetWare compatible UserCollection Enumeration Code
//
// History: 22-Mar-96 t-ptam (PatrickT) migrated from KrishnaG for NetWare
//----------------------------------------------------------------------------
#include "nwcompat.hxx"
#pragma hdrstop
USER_GROUP_ENTRY UserGroupEntry;
//
// This assumes that addr is an LPBYTE type.
//
#define WORD_ALIGN_DOWN(addr) \
addr = ((LPBYTE)((DWORD)addr & ~1))
DWORD UserGrpEntryStrings[]=
{
FIELD_OFFSET(USER_GROUP_ENTRY, Parent),
FIELD_OFFSET(USER_GROUP_ENTRY, Computer),
FIELD_OFFSET(USER_GROUP_ENTRY, Name),
0xFFFFFFFF
};
DECLARE_INFOLEVEL(UsrUt)
DECLARE_DEBUG(UsrUt)
#define UsrUtDebugOut(x) UsrUtInlineDebugOut x
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerUserOpen
//
// Synopsis: This function opens a handle to a INI_COMP_USER structure.
//
//----------------------------------------------------------------------------
BOOL
NWCOMPATComputerUserOpen(
LPWSTR szComputerName,
LPWSTR szGroupName,
CCredentials &Credentials,
PHANDLE phUser
)
{
WCHAR szTempBuffer[MAX_PATH];
PINI_COMP_USER pIniCompUsr;
HRESULT hr = S_OK;
if (!phUser) {
return(FALSE);
}
pIniCompUsr = (PINI_COMP_USER)AllocADsMem(
sizeof(INI_COMP_USER)
);
if (!pIniCompUsr) {
return(FALSE);
}
//
// Fill structure's fields.
//
if (!(pIniCompUsr->szComputerName = AllocADsStr(szComputerName))){
goto error;
}
if (!(pIniCompUsr->szGroupName = AllocADsStr(szGroupName))){
goto error;
}
hr = NWApiGetBinderyHandle(
&pIniCompUsr->_hConn,
szComputerName,
Credentials
);
BAIL_ON_FAILURE(hr);
//
// Return
//
*phUser = (HANDLE)pIniCompUsr;
return(TRUE);
error:
if (pIniCompUsr) {
FreeIniCompUser(pIniCompUsr);
}
*phUser = NULL;
return(FALSE);
}
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerUserEnum
//
// Synopsis: This function returns a buffer which contains all the binding
// informations for the requested number of objects without any
// references.
// It returns TRUE iff dwReturned = dwRequested.
//
//----------------------------------------------------------------------------
BOOL
NWCOMPATComputerUserEnum(
HANDLE hUser,
DWORD dwRequested,
LPBYTE * ppBuffer,
PDWORD pdwReturned
)
{
LPUSER_GROUP_ENTRY * ppUserMembers = NULL;
DWORD i = 0;
BOOL dwRet = FALSE;
DWORD dwReturned = 0;
DWORD dwSize = 0;
LPUSER_GROUP_ENTRY pBuffer = NULL;
LPBYTE pEnd = NULL;
//
// Allocate buffer for the number of requested members.
//
ppUserMembers = (LPUSER_GROUP_ENTRY *)AllocADsMem(
sizeof(LPUSER_GROUP_ENTRY)* dwRequested
);
if (!ppUserMembers) {
return(FALSE);
}
//
// Fill in ppUserMembers one by one.
//
for (i = 0; i < dwRequested; i++) {
dwRet = NWCOMPATComputerUserGetObject(
hUser,
&ppUserMembers[i]
);
if (!dwRet) {
break;
}
}
dwReturned = i;
if (!dwRet) {
goto error;
}
else {
//
// Determine actual size of ppUserMembers[], ie. since each string in
// USER_GROUP_ENTRY have a different length, a buffer that is going
// to contain all the data without any references is unknown.
//
dwRet = ComputeComputerUserDataSize(
ppUserMembers,
dwReturned,
&dwSize
);
pBuffer = (LPUSER_GROUP_ENTRY)AllocADsMem(
dwSize
);
if (!pBuffer) {
goto error;
}
pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
//
// Put data into pBuffer, starting from the end.
//
for (i = 0; i < dwReturned; i++) {
pEnd = CopyIniCompUserToCompUser(
ppUserMembers[i],
(LPBYTE)(pBuffer + i),
pEnd
);
}
//
// Clean up.
//
for (i = 0; i < dwReturned; i++ ) {
FreeIntCompUser(*(ppUserMembers + i));
}
//
// Return values.
//
*ppBuffer = (LPBYTE)pBuffer;
*pdwReturned = dwReturned;
}
FreeADsMem(ppUserMembers);
if (dwReturned == dwRequested){
return(TRUE);
}else {
return(FALSE);
}
error:
for (i = 0; i < dwReturned; i++ ) {
FreeIntCompUser(*(ppUserMembers + i));
}
FreeADsMem(ppUserMembers);
return(FALSE);
}
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerUserGetObject
//
// Synopsis: This function returns binding information of a user (group member)
// object one by one. In its first call, it builds a buffer that
// contains all the UserID of the group members. Then, and in
// subsequent calls, this UserID is translated into a user name.
//
//----------------------------------------------------------------------------
BOOL
NWCOMPATComputerUserGetObject(
HANDLE hUser,
LPUSER_GROUP_ENTRY * ppUserMember
)
{
BOOL dwRet = FALSE;
DWORD dwGroupId = 0;
HRESULT hr = S_OK;
PINI_COMP_USER pIniCompUsr = (PINI_COMP_USER)hUser;
//
// Fill buffer with User ID. NetWare returns all UserID in one call.
//
if (!pIniCompUsr->_pBuffer) {
pIniCompUsr->_dwCurrentObject = 0;
hr = NWApiUserGetGroups(
pIniCompUsr->_hConn,
pIniCompUsr->szGroupName,
&(pIniCompUsr->_pBuffer)
);
BAIL_ON_FAILURE(hr);
}
//
// Build one group member.
//
dwGroupId = *((LPDWORD)pIniCompUsr->_pBuffer + pIniCompUsr->_dwCurrentObject);
if (dwGroupId != 0x0000) {
dwRet = BuildComputerUserMember(
hUser,
dwGroupId,
ppUserMember
);
if (!dwRet) {
goto error;
}
pIniCompUsr->_dwCurrentObject++;
return(TRUE);
}
error:
return(FALSE);
}
//----------------------------------------------------------------------------
//
// Function: NWCOMPATComputerUserClose
//
// Synopsis: Wrapper of FreeIniCompUser.
//
//----------------------------------------------------------------------------
BOOL
NWCOMPATComputerUserClose(
HANDLE hUser
)
{
PINI_COMP_USER pIniCompUsr = (PINI_COMP_USER)hUser;
if (pIniCompUsr) {
FreeIniCompUser(pIniCompUsr);
}
return(TRUE);
}
//----------------------------------------------------------------------------
//
// Function: FreeIniCompUser
//
// Synopsis: Free an INI_COMP_USER structure.
//
//----------------------------------------------------------------------------
void
FreeIniCompUser(
PINI_COMP_USER pIniCompUsr
)
{
HRESULT hr = S_OK;
if (pIniCompUsr) {
if (pIniCompUsr->szComputerName) {
FreeADsStr(pIniCompUsr->szComputerName);
}
if (pIniCompUsr->szGroupName) {
FreeADsStr(pIniCompUsr->szGroupName);
}
if (pIniCompUsr->_pBuffer) {
FreeADsMem(pIniCompUsr->_pBuffer);
}
if (pIniCompUsr->_hConn) {
hr = NWApiReleaseBinderyHandle(pIniCompUsr->_hConn);
}
FreeADsMem(pIniCompUsr);
}
return;
}
//----------------------------------------------------------------------------
//
// Function: FreeIntCompUser
//
// Synopsis: Free a USER_GROUP_ENTRY structure.
//
//----------------------------------------------------------------------------
void
FreeIntCompUser(
LPUSER_GROUP_ENTRY pCompUserMember
)
{
if (pCompUserMember) {
if (pCompUserMember->Parent) {
FreeADsStr(pCompUserMember->Parent);
}
if (pCompUserMember->Computer) {
FreeADsStr(pCompUserMember->Computer);
}
if (pCompUserMember->Name) {
FreeADsStr(pCompUserMember->Name);
}
FreeADsMem(pCompUserMember);
}
return;
}
//----------------------------------------------------------------------------
//
// Function: ComputeComputerUserDataSize
//
// Synopsis: Calculate the size of a buffer that is going to store the data in
// ppUserMembers without any references.
//
//----------------------------------------------------------------------------
BOOL
ComputeComputerUserDataSize(
LPUSER_GROUP_ENTRY * ppUserMembers,
DWORD dwReturned,
PDWORD pdwSize
)
{
DWORD i = 0;
DWORD cb = 0;
LPUSER_GROUP_ENTRY pMember = NULL;
for (i = 0; i < dwReturned; i++) {
pMember = *(ppUserMembers + i);
cb += sizeof(USER_GROUP_ENTRY);
if (pMember->Parent) {
cb += wcslen(pMember->Parent)*sizeof(WCHAR) + sizeof(WCHAR);
}
if (pMember->Computer) {
cb += wcslen(pMember->Computer)*sizeof(WCHAR) + sizeof(WCHAR);
}
if (pMember->Name) {
cb += wcslen(pMember->Name)*sizeof(WCHAR) + sizeof(WCHAR);
}
}
*pdwSize = cb;
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: CopyIniCompUserToCompUser
//
// Synopsis: Pack referenced data (string) into a buffer without any reference.
//
//------------------------------------------------------------------------------
LPBYTE
CopyIniCompUserToCompUser(
LPUSER_GROUP_ENTRY pIntCompGrp,
LPBYTE pExtCompGrp,
LPBYTE pEnd
)
{
LPWSTR SourceStrings[sizeof(USER_GROUP_ENTRY)/sizeof(LPWSTR)];
LPWSTR *pSourceStrings = SourceStrings;
LPUSER_GROUP_ENTRY pCompGrpMember = (LPUSER_GROUP_ENTRY)pExtCompGrp;
memset(SourceStrings, 0, sizeof(USER_GROUP_ENTRY));
*pSourceStrings++ = pIntCompGrp->Parent;
*pSourceStrings++ = pIntCompGrp->Computer;
*pSourceStrings++ = pIntCompGrp->Name;
pEnd = PackStrings(
SourceStrings,
pExtCompGrp,
UserGrpEntryStrings,
pEnd
);
pCompGrpMember->Type = pIntCompGrp->Type;
return pEnd;
}
//----------------------------------------------------------------------------
//
// Function: BuildComputerUserMember
//
// Synopsis: Put binding information of a group member into ppUserMember.
//
//----------------------------------------------------------------------------
BOOL
BuildComputerUserMember(
HANDLE hUser,
DWORD dwGroupId,
LPUSER_GROUP_ENTRY * ppUserMember
)
{
DWORD dwTempUserId = dwGroupId;
HRESULT hr = S_OK;
LPUSER_GROUP_ENTRY pUserMember = NULL;
LPINI_COMP_USER pUser = (LPINI_COMP_USER)hUser;
WCHAR szADsParent[MAX_PATH];
//
// Allocate one USER_GROUP_ENTRY.
//
pUserMember = (LPUSER_GROUP_ENTRY)AllocADsMem(
sizeof(USER_GROUP_ENTRY)
);
if (!pUserMember) {
return(FALSE);
}
//
// Fill structure's fields.
//
pUserMember->Parent = NULL;
pUserMember->Computer = NULL;
pUserMember->Type = NWCOMPAT_USER_ID;
wsprintf(
szADsParent,
L"%s://%s",
szProviderName,
pUser->szComputerName
);
pUserMember->Parent = AllocADsStr(szADsParent);
if (!pUserMember->Parent) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
pUserMember->Computer = AllocADsStr(pUser->szComputerName);
if (!pUserMember->Computer) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = NWApiGetObjectName(
pUser->_hConn,
dwTempUserId,
&pUserMember->Name
);
BAIL_ON_FAILURE(hr);
//
// Return.
//
*ppUserMember = pUserMember;
return(TRUE);
error:
if (pUserMember) {
if (pUserMember->Parent)
FreeADsStr(pUserMember->Parent);
if (pUserMember->Computer)
FreeADsStr(pUserMember->Computer);
FreeADsMem(pUserMember);
}
return(FALSE);
}