791 lines
21 KiB
C++
791 lines
21 KiB
C++
//+-------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997 - 1997.
|
|
//
|
|
// File: sidcache.cxx
|
|
//
|
|
// Contents: Implementation of the sid/name lookup cache
|
|
//
|
|
// History: 2-Feb-97 MacM Created
|
|
//
|
|
//--------------------------------------------------------------------
|
|
#include <aclpch.hxx>
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// Global name/sid cache
|
|
//
|
|
PACTRL_NAME_CACHE grgNameCache[ACTRL_NAME_TABLE_SIZE];
|
|
PACTRL_NAME_CACHE grgSidCache[ACTRL_NAME_TABLE_SIZE];
|
|
|
|
//
|
|
// Local function prototypes
|
|
//
|
|
PACTRL_NAME_CACHE AccctrlpLookupNameInCache(PWSTR pwszName);
|
|
|
|
PACTRL_NAME_CACHE AccctrlpLookupSidInCache(PSID pSid);
|
|
|
|
DWORD AccctrlpNewNameSidNode(PWSTR pwszName,
|
|
PSID pSid,
|
|
SID_NAME_USE SidNameUse,
|
|
PACTRL_NAME_CACHE *ppNewNode);
|
|
|
|
VOID AccctrlpInsertNameNode(PACTRL_NAME_CACHE *ppRootNode,
|
|
PACTRL_NAME_CACHE pNewNode);
|
|
|
|
VOID AccctrlpInsertSidNode(PACTRL_NAME_CACHE *ppRootNode,
|
|
PACTRL_NAME_CACHE pNewNode);
|
|
|
|
DWORD AccctrlpConvertUserToCacheName(PWSTR pwszServer,
|
|
PWSTR pwszName,
|
|
PWSTR *ppwszCacheName);
|
|
|
|
VOID AccctrlpFreeUserCacheName(PWSTR pwszName,
|
|
PWSTR pwszCacheName);
|
|
|
|
static RTL_RESOURCE gSidCacheLock;
|
|
BOOL bSidCacheLockInitialized = FALSE;
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: ActrlHashName
|
|
//
|
|
// Synopsis: Determines the hash index for the given name
|
|
//
|
|
// Arguments: pwszName -- Name to hash
|
|
//
|
|
// Returns: Hash index of the string
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
INT
|
|
ActrlHashName(PWSTR pwszName)
|
|
{
|
|
//
|
|
// We'll hash off of just the user name, not the domain name or
|
|
// any other name format
|
|
//
|
|
PWSTR pwszUser = wcschr(pwszName, L'\\');
|
|
if(pwszUser == NULL)
|
|
{
|
|
pwszUser = pwszName;
|
|
}
|
|
else
|
|
{
|
|
pwszUser++;
|
|
}
|
|
|
|
INT Hash = 0;
|
|
if(pwszUser != NULL)
|
|
{
|
|
while(*pwszUser != L'\0')
|
|
{
|
|
Hash = (Hash * 16 + ( *pwszUser++)) % ACTRL_NAME_TABLE_SIZE;
|
|
}
|
|
}
|
|
|
|
acDebugOut((DEB_TRACE_LOOKUP,"Hashing %ws to %lu\n", pwszName, Hash));
|
|
|
|
return(Hash);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: ActrlHashSid
|
|
//
|
|
// Synopsis: Determines the hash index for the given sid
|
|
//
|
|
// Arguments: pSid -- Sid to hash
|
|
//
|
|
// Returns: Hash index of the Sid
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
INT
|
|
ActrlHashSid(PSID pSid)
|
|
{
|
|
DWORD dwTotal = 0;
|
|
|
|
//
|
|
// Just deal with the sub authorities
|
|
//
|
|
for(INT i = 0; i < (INT)(((PISID)pSid)->SubAuthorityCount); i++)
|
|
{
|
|
dwTotal += ((PISID)pSid)->SubAuthority[i];
|
|
}
|
|
|
|
#if DBG
|
|
|
|
UNICODE_STRING SidString;
|
|
|
|
memset(&SidString, 0, sizeof(UNICODE_STRING));
|
|
|
|
if(pSid != NULL)
|
|
{
|
|
NTSTATUS Status = RtlConvertSidToUnicodeString(&SidString,
|
|
pSid,
|
|
TRUE);
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
acDebugOut((DEB_ERROR, "Can't convert sid to string: 0x%lx\n", Status));
|
|
}
|
|
else
|
|
{
|
|
acDebugOut((DEB_TRACE_LOOKUP,"Hashing %wZ (Total %lu) to %lu\n", &SidString,
|
|
dwTotal, dwTotal % ACTRL_NAME_TABLE_SIZE));
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|
|
return(dwTotal % ACTRL_NAME_TABLE_SIZE);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlInitializeSidNameCache
|
|
//
|
|
// Synopsis: Initialize the name/sid lookup cache
|
|
//
|
|
// Arguments: VOID
|
|
//
|
|
// Returns: ERROR_SUCCESS -- Success
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD AccctrlInitializeSidNameCache(VOID)
|
|
{
|
|
DWORD dwErr;
|
|
|
|
if (TRUE == bSidCacheLockInitialized)
|
|
{
|
|
//
|
|
// Just a precautionary measure to make sure that we do not initialize
|
|
// multiple times.
|
|
//
|
|
|
|
ASSERT(FALSE);
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
memset(grgNameCache, 0, sizeof(PACTRL_NAME_CACHE) * ACTRL_NAME_TABLE_SIZE);
|
|
memset(grgSidCache, 0, sizeof(PACTRL_NAME_CACHE) * ACTRL_NAME_TABLE_SIZE);
|
|
|
|
__try
|
|
{
|
|
RtlInitializeResource(&gSidCacheLock);
|
|
dwErr = ERROR_SUCCESS;
|
|
bSidCacheLockInitialized = TRUE;
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
dwErr = RtlNtStatusToDosError(GetExceptionCode());
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlFreeSidNameCache
|
|
//
|
|
// Synopsis: Frees any memory allocated for the name/sid cache
|
|
//
|
|
// Arguments: VOID
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID AccctrlFreeSidNameCache(VOID)
|
|
{
|
|
INT i;
|
|
PACTRL_NAME_CACHE pNode, pNext;
|
|
|
|
if (FALSE == bSidCacheLockInitialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(i = 0; i < ACTRL_NAME_TABLE_SIZE; i++)
|
|
{
|
|
//
|
|
// Nodes are only inserted into the name cache, so that is the only
|
|
// place we delete them from
|
|
//
|
|
pNode = grgNameCache[i];
|
|
while(pNode != NULL)
|
|
{
|
|
pNext = pNode->pNextName;
|
|
AccFree(pNode->pwszName);
|
|
AccFree(pNode->pSid);
|
|
AccFree(pNode);
|
|
pNode = pNext;
|
|
}
|
|
}
|
|
|
|
RtlDeleteResource(&gSidCacheLock);
|
|
|
|
bSidCacheLockInitialized = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpLookupNameInCache
|
|
//
|
|
// Synopsis: Determines if the given name exists in the cache or not
|
|
//
|
|
// Arguments: [pwszName] -- Name to be looked up
|
|
//
|
|
// Returns: Matching node if found, NULL if not
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
PACTRL_NAME_CACHE AccctrlpLookupNameInCache(PWSTR pwszName)
|
|
{
|
|
PACTRL_NAME_CACHE pNode = NULL;
|
|
|
|
pNode = grgNameCache[ActrlHashName(pwszName)];
|
|
|
|
while(pNode != NULL)
|
|
{
|
|
if(_wcsicmp(pwszName, pNode->pwszName) == 0)
|
|
{
|
|
break;
|
|
}
|
|
pNode = pNode->pNextName;
|
|
}
|
|
|
|
return(pNode);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpLookupSidInCache
|
|
//
|
|
// Synopsis: Determines if the given sid exists in the cache or not
|
|
//
|
|
// Arguments: [pSid] -- Sid to be looked up
|
|
//
|
|
// Returns: Matching node if found, NULL if not
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
PACTRL_NAME_CACHE AccctrlpLookupSidInCache(PSID pSid)
|
|
{
|
|
PACTRL_NAME_CACHE pNode = grgSidCache[ActrlHashSid(pSid)];
|
|
|
|
while(pNode != NULL)
|
|
{
|
|
if(RtlEqualSid(pSid, pNode->pSid) == TRUE)
|
|
{
|
|
break;
|
|
}
|
|
pNode = pNode->pNextSid;
|
|
}
|
|
|
|
return(pNode);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpNewNameSidNode
|
|
//
|
|
// Synopsis: Allocates a new node and inserts them into the caches
|
|
//
|
|
// Arguments: [pwszName] -- Name to insert
|
|
// [pSid] -- Sid to insert
|
|
// [SidNameUse] -- Name use
|
|
// [pNewNode] -- Newly added node
|
|
//
|
|
// Returns: ERROR_SUCCESS -- Success
|
|
// ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD AccctrlpNewNameSidNode(PWSTR pwszName,
|
|
PSID pSid,
|
|
SID_NAME_USE SidNameUse,
|
|
PACTRL_NAME_CACHE *ppNewNode)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
PACTRL_NAME_CACHE pNewNode = (PACTRL_NAME_CACHE)AccAlloc(
|
|
sizeof(ACTRL_NAME_CACHE));
|
|
if(pNewNode == NULL)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
pNewNode->pwszName = pwszName;
|
|
pNewNode->pSid = pSid;
|
|
pNewNode->SidUse = SidNameUse;
|
|
pNewNode->pNextName= NULL;
|
|
pNewNode->pNextSid = NULL;
|
|
|
|
AccctrlpInsertNameNode(&(grgNameCache[ActrlHashName(pwszName)]),
|
|
pNewNode);
|
|
|
|
AccctrlpInsertSidNode(&(grgSidCache[ActrlHashSid(pSid)]),
|
|
pNewNode);
|
|
|
|
*ppNewNode = pNewNode;
|
|
|
|
}
|
|
return(dwErr);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpInsertNameNode
|
|
//
|
|
// Synopsis: Inserts the specified new node into the caches
|
|
//
|
|
// Arguments: [ppRootNode] -- Root node in the name cache
|
|
// [pNewNode] -- Node to insert
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID AccctrlpInsertNameNode(PACTRL_NAME_CACHE *ppRootNode,
|
|
PACTRL_NAME_CACHE pNewNode)
|
|
{
|
|
PACTRL_NAME_CACHE pNext = NULL;
|
|
|
|
if(*ppRootNode == NULL)
|
|
{
|
|
*ppRootNode = pNewNode;
|
|
}
|
|
else
|
|
{
|
|
acDebugOut((DEB_TRACE_LOOKUP, "Collision inserting %ws with:\n", pNewNode->pwszName));
|
|
|
|
pNext = *ppRootNode;
|
|
acDebugOut((DEB_TRACE_LOOKUP, "\t%ws\n", pNext->pwszName));
|
|
while(pNext->pNextName != NULL)
|
|
{
|
|
#if DBG
|
|
if(_wcsicmp(pNewNode->pwszName, pNext->pwszName) == 0)
|
|
{
|
|
acDebugOut((DEB_ERROR, "Name %ws already in list: 0x%lx\n",
|
|
pNewNode->pwszName,
|
|
*ppRootNode));
|
|
// ASSERT(FALSE);
|
|
}
|
|
#endif
|
|
|
|
pNext = pNext->pNextName;
|
|
acDebugOut((DEB_TRACE_LOOKUP, "\t%ws\n", pNext->pwszName));
|
|
}
|
|
pNext->pNextName = pNewNode;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpInsertSidNode
|
|
//
|
|
// Synopsis: Inserts the specified new node into the caches
|
|
//
|
|
// Arguments: [ppRootNode] -- Root node in the name cache
|
|
// [pNewNode] -- Node to insert
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID AccctrlpInsertSidNode(PACTRL_NAME_CACHE *ppRootNode,
|
|
PACTRL_NAME_CACHE pNewNode)
|
|
{
|
|
PACTRL_NAME_CACHE pNext = NULL;
|
|
|
|
if(*ppRootNode == NULL)
|
|
{
|
|
*ppRootNode = pNewNode;
|
|
}
|
|
else
|
|
{
|
|
acDebugOut((DEB_TRACE_LOOKUP, "Collision inserting %ws with:\n", pNewNode->pwszName));
|
|
|
|
pNext = *ppRootNode;
|
|
acDebugOut((DEB_TRACE_LOOKUP, "\t%ws\n", pNext->pwszName));
|
|
while(pNext->pNextSid != NULL)
|
|
{
|
|
#if DBG
|
|
if(RtlEqualSid(pNewNode->pSid, pNext->pSid) == TRUE)
|
|
{
|
|
acDebugOut((DEB_ERROR, "Sid for %ws already in list: 0x%lx\n",
|
|
pNewNode->pwszName,
|
|
*ppRootNode));
|
|
// ASSERT(FALSE);
|
|
}
|
|
#endif
|
|
|
|
pNext = pNext->pNextSid;
|
|
|
|
acDebugOut((DEB_TRACE_LOOKUP, "\t%ws\n", pNext->pwszName));
|
|
}
|
|
pNext->pNextSid = pNewNode;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlLookupName
|
|
//
|
|
// Synopsis: Looks up the name for the specified SID
|
|
//
|
|
// Arguments: [pwszServer] -- Name of the server to remote the call to
|
|
// [pSid] -- Sid to lookup
|
|
// [fAllocateReturn]- If true, the name returned is allocated
|
|
// into a new buffer. Otherwise, a
|
|
// reference is returned.
|
|
// [ppwszName] -- Where the name is returned.
|
|
// [pSidNameUse] -- Type of the name that's returned.
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD
|
|
AccctrlLookupName(IN PWSTR pwszServer,
|
|
IN PSID pSid,
|
|
IN BOOL fAllocateReturn,
|
|
OUT PWSTR *ppwszName,
|
|
OUT PSID_NAME_USE pSidNameUse)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if(pSid == NULL)
|
|
{
|
|
return(ERROR_NONE_MAPPED);
|
|
}
|
|
|
|
RtlAcquireResourceShared(&gSidCacheLock, TRUE);
|
|
|
|
#if DBG
|
|
UNICODE_STRING SidString;
|
|
|
|
memset(&SidString, 0, sizeof(UNICODE_STRING));
|
|
|
|
if(pSid != NULL)
|
|
{
|
|
NTSTATUS Status = RtlConvertSidToUnicodeString(&SidString,
|
|
pSid,
|
|
TRUE);
|
|
if(!NT_SUCCESS(Status))
|
|
{
|
|
acDebugOut((DEB_ERROR, "Can't convert sid to string: 0x%lx\n", Status));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// First, see if the sid alreadt exists in our cache
|
|
//
|
|
PACTRL_NAME_CACHE pNode = AccctrlpLookupSidInCache(pSid);
|
|
if(pNode == NULL)
|
|
{
|
|
#if DBG
|
|
acDebugOut((DEB_TRACE_LOOKUP, "Sid %wZ not found in cache\n", &SidString));
|
|
#endif
|
|
//
|
|
// Grab a write lock
|
|
//
|
|
RtlConvertSharedToExclusive(&gSidCacheLock);
|
|
|
|
|
|
//
|
|
// We'll have to look it up...
|
|
//
|
|
PWSTR pwszName, pwszDomain;
|
|
dwErr = AccLookupAccountName(pwszServer,
|
|
pSid,
|
|
&pwszName,
|
|
&pwszDomain,
|
|
pSidNameUse);
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
PSID pNewSid = NULL;
|
|
ACC_ALLOC_AND_COPY_SID(pSid, pNewSid, dwErr);
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwErr = AccctrlpNewNameSidNode(pwszName,
|
|
pNewSid,
|
|
*pSidNameUse,
|
|
&pNode);
|
|
}
|
|
|
|
if(dwErr != ERROR_SUCCESS)
|
|
{
|
|
AccFree(pwszName);
|
|
AccFree(pwszDomain);
|
|
AccFree(pNewSid);
|
|
}
|
|
}
|
|
}
|
|
#if DBG
|
|
else
|
|
{
|
|
acDebugOut((DEB_TRACE_LOOKUP, "Sid %wZ found in cache\n", &SidString));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Finally, return the information
|
|
//
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
if(fAllocateReturn == TRUE)
|
|
{
|
|
ACC_ALLOC_AND_COPY_STRINGW(pNode->pwszName, *ppwszName, dwErr);
|
|
}
|
|
else
|
|
{
|
|
*ppwszName = pNode->pwszName;
|
|
}
|
|
|
|
*pSidNameUse = pNode->SidUse;
|
|
}
|
|
|
|
RtlReleaseResource(&gSidCacheLock);
|
|
|
|
return(dwErr);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlLookupSid
|
|
//
|
|
// Synopsis: Looks up the SID for the specified name
|
|
//
|
|
// Arguments: [pwszServer] -- Name of the server to remote the call to
|
|
// [pwszName] -- Name to lookup
|
|
// [fAllocateReturn]- If true, the name returned is allocated
|
|
// into a new buffer. Otherwise, a
|
|
// reference is returned.
|
|
// [ppwszName] -- Where the name is returned.
|
|
// [pSidNameUse] -- Type of the sid that's returned.
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD
|
|
AccctrlLookupSid(IN PWSTR pwszServer,
|
|
IN PWSTR pwszName,
|
|
IN BOOL fAllocateReturn,
|
|
OUT PSID *ppSid,
|
|
OUT PSID_NAME_USE pSidNameUse)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
PWSTR pwszLookupName = pwszName;
|
|
|
|
RtlAcquireResourceShared(&gSidCacheLock, TRUE);
|
|
|
|
//
|
|
// If we get a local name, convert it into machine/domain relative, so we can
|
|
// look it up properly.
|
|
//
|
|
dwErr = AccctrlpConvertUserToCacheName(pwszServer, pwszName, &pwszLookupName);
|
|
|
|
//
|
|
// Just return if the conversion failed.
|
|
//
|
|
|
|
if (pwszLookupName == NULL)
|
|
{
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwErr = ERROR_ACCESS_DENIED;
|
|
}
|
|
}
|
|
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// First, see if the sid already exists in our cache
|
|
//
|
|
PACTRL_NAME_CACHE pNode = AccctrlpLookupNameInCache(pwszLookupName);
|
|
if(pNode == NULL)
|
|
{
|
|
//
|
|
// Grab a write lock
|
|
//
|
|
RtlConvertSharedToExclusive(&gSidCacheLock);
|
|
|
|
acDebugOut((DEB_TRACE_LOOKUP,"Name %ws not found in cache\n", pwszLookupName));
|
|
//
|
|
// We'll have to look it up...
|
|
//
|
|
TRUSTEE_W Trustee;
|
|
memset(&Trustee, 0, sizeof(TRUSTEE_W));
|
|
Trustee.TrusteeForm = TRUSTEE_IS_NAME;
|
|
Trustee.ptstrName = pwszLookupName;
|
|
|
|
dwErr = AccLookupAccountSid(pwszServer,
|
|
&Trustee,
|
|
ppSid,
|
|
pSidNameUse);
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
PWSTR pwszNewName = NULL;
|
|
ACC_ALLOC_AND_COPY_STRINGW(pwszLookupName, pwszNewName, dwErr);
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwErr = AccctrlpNewNameSidNode(pwszNewName,
|
|
*ppSid,
|
|
*pSidNameUse,
|
|
&pNode);
|
|
}
|
|
|
|
if(dwErr != ERROR_SUCCESS)
|
|
{
|
|
AccFree(pwszNewName);
|
|
AccFree(*ppSid);
|
|
}
|
|
}
|
|
}
|
|
#if DBG
|
|
else
|
|
{
|
|
acDebugOut((DEB_TRACE_LOOKUP,"Name %ws found in cache\n", pwszLookupName));
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Finally, return the information
|
|
//
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
if(fAllocateReturn == TRUE)
|
|
{
|
|
ACC_ALLOC_AND_COPY_SID(pNode->pSid, *ppSid, dwErr);
|
|
}
|
|
else
|
|
{
|
|
*ppSid = pNode->pSid;
|
|
}
|
|
|
|
*pSidNameUse = pNode->SidUse;
|
|
}
|
|
|
|
AccctrlpFreeUserCacheName(pwszName, pwszLookupName);
|
|
}
|
|
|
|
RtlReleaseResource(&gSidCacheLock);
|
|
|
|
|
|
return(dwErr);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpConvertUserToCacheName
|
|
//
|
|
// Synopsis: Converts an input name that could be domain relative into a
|
|
// standard format for caching/returning
|
|
//
|
|
// Arguments: [pwszServer] -- Server to lookup the name on
|
|
// [pwszName] -- Original name format
|
|
// [ppwszCacheName]-- Name in the proper format
|
|
//
|
|
// Returns: ERROR_SUCCESS -- Success
|
|
// ERROR_NOT_ENOUGH_MEMORY A memory allocation failed
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
DWORD AccctrlpConvertUserToCacheName(PWSTR pwszServer,
|
|
PWSTR pwszName,
|
|
PWSTR *ppwszCacheName)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
//
|
|
// This is temporary until the name conversion APIs come into being
|
|
//
|
|
PSID pSid;
|
|
SID_NAME_USE SNE;
|
|
TRUSTEE_W Trustee;
|
|
memset(&Trustee, 0, sizeof(TRUSTEE_W));
|
|
Trustee.TrusteeForm = TRUSTEE_IS_NAME;
|
|
Trustee.ptstrName = pwszName;
|
|
|
|
dwErr = AccLookupAccountSid(pwszServer,
|
|
&Trustee,
|
|
&pSid,
|
|
&SNE);
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
PWSTR pwszDomain;
|
|
dwErr = AccLookupAccountName(pwszServer,
|
|
pSid,
|
|
ppwszCacheName,
|
|
&pwszDomain,
|
|
&SNE);
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
AccFree(pwszDomain);
|
|
}
|
|
|
|
AccFree(pSid);
|
|
}
|
|
|
|
|
|
return(dwErr);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Function: AccctrlpFreeUserCacheName
|
|
//
|
|
// Synopsis: Frees any memory potentially allocated by
|
|
// AccctrlpConvertUserToCacheName
|
|
//
|
|
// Arguments: [pwszName] -- Original name format
|
|
// [pwszCacheName] -- Name returned by
|
|
// AccctrlpConvertUserToCacheName
|
|
//
|
|
// Returns: VOID
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID AccctrlpFreeUserCacheName(PWSTR pwszName,
|
|
PWSTR pwszCacheName)
|
|
{
|
|
if(pwszName != pwszCacheName)
|
|
{
|
|
AccFree(pwszCacheName);
|
|
}
|
|
}
|
|
|
|
|