|
|
/*****************************************************************************/
/* Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved /
/*****************************************************************************/
/*
* CSid.cpp - implementation file for CSid class. * * Created: 12-14-1997 by Sanjeev Surati * (based on classes from Windows NT Security by Nik Okuntseff) */
#include "precomp.h"
#include <assertbreak.h>
#include "Sid.h"
#include <comdef.h>
#include <accctrl.h>
#include "wbemnetapi32.h"
#include "SecUtils.h"
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Default class constructor.
//
// Inputs:
// None.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid::CSid( void ) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Class constructor.
//
// Inputs:
// PSID pSid - SID to validate and get account
// info for.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid::CSid( PSID pSid, LPCTSTR pszComputerName ) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { InitFromSid( pSid, pszComputerName ); }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Initializes the object from a PSid, with an indicator as to whether
// we should lookup and initialize the associated domain and account.
//
// Inputs:
// PSID pSid - PSid to look up.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
// bool fLookup - indicates whether to determine
// the domain and account associated with
// the sid at this time.
//
// Outputs:
// None.
//
// Returns:
// DWORD ERROR_SUCCESS if OK.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid::CSid( PSID pSid, LPCTSTR pszComputerName, bool fLookup ) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { InitFromSid(pSid, pszComputerName, fLookup); }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Class constructor.
//
// Inputs:
// LPCTSTR pszAccountName - Account name to validate
// and obtain info for.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid::CSid( LPCTSTR pszAccountName, LPCTSTR pszComputerName ) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { InitFromAccountName( pszAccountName, pszComputerName ); }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Class constructor.
//
// Inputs:
// LPCTSTR pszDomainName - Domain to combine with
// account name.
// LPCTSTR pszName - Name to combine with domain.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
// This flavor of the constructor combines a domain and account
// name in "DOMAIN\NAME" format and then initializes our data
// from there.
//
///////////////////////////////////////////////////////////////////
CSid::CSid( LPCTSTR pszDomainName, LPCTSTR pszName, LPCTSTR pszComputerName ) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { CHString strName;
if ( NULL == pszDomainName || *pszDomainName == '\0' ) { strName = pszName; } else { strName = pszDomainName; strName += '\\'; strName += pszName; }
InitFromAccountName(TOBSTRT(strName), pszComputerName ); }
#ifndef UNICODE
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Class constructor - this is used for wide char support when
// UNICODE is not defined.
//
// Inputs:
// LPCWSTR wstrDomainName - Domain to combine with
// account name.
// LPCWSTR wstrName - Name to combine with domain.
// LPCWSTR wstrComputerName - Remote computer to
// execute on.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
// This flavor of the constructor combines a domain and account
// name in "DOMAIN\NAME" format and then initializes our data
// from there. Again, this is used for wide char support when
// UNICODE is not defined.
//
///////////////////////////////////////////////////////////////////
CSid::CSid(LPCWSTR wstrDomainName, LPCWSTR wstrName, LPCWSTR wstrComputerName) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { LONG lTempNameLen = 0L; if(wstrDomainName==NULL && wstrName!=NULL) { lTempNameLen = wcslen(wstrName)+2; } else if(wstrDomainName!=NULL && wstrName==NULL) { lTempNameLen = wcslen(wstrDomainName)+2; } else if(wstrDomainName!=NULL && wstrName!=NULL) { lTempNameLen = wcslen(wstrName)+wcslen(wstrDomainName)+2; }
WCHAR* wstrTempName = NULL; try { wstrTempName = (WCHAR*) new WCHAR[lTempNameLen]; if(wstrTempName == NULL) { m_dwLastError = ::GetLastError(); } else { ZeroMemory(wstrTempName,lTempNameLen * sizeof(WCHAR)); if ( NULL == wstrDomainName || *wstrDomainName == '\0' ) { wcscpy(wstrTempName,wstrName); } else { wcscpy(wstrTempName,wstrDomainName); wcscat(wstrTempName,L"\\"); if(wstrName!=NULL) { wcscat(wstrTempName,wstrName); } } InitFromAccountNameW(wstrTempName, wstrComputerName); delete wstrTempName; } } catch(...) { if(wstrTempName != NULL) { delete wstrTempName; wstrTempName = NULL; } throw; } } #endif
///////////////////////////////////////////////////////////////////
//
// Function: CSid::CSid
//
// Class copy constructor.
//
// Inputs:
// const CSid r_Sid - CSid to copy.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid::CSid( const CSid &r_Sid ) : m_pSid( NULL ), m_snuAccountType( SidTypeUnknown ), m_dwLastError( ERROR_SUCCESS ) { // Handle WINNT SID pointer first
// pSid should be valid...
ASSERT_BREAK( r_Sid.IsValid() );
// Allocate a new SID and copy data into it.
DWORD dwSize = ::GetLengthSid( r_Sid.m_pSid ); m_pSid = malloc( dwSize ); if (m_pSid != NULL) { try { BOOL bResult = ::CopySid( dwSize, m_pSid, r_Sid.m_pSid ); ASSERT_BREAK( bResult );
// Now copy all other members
m_snuAccountType = r_Sid.m_snuAccountType; m_dwLastError = r_Sid.m_dwLastError; //m_strSid = r_Sid.m_strSid;
//m_strAccountName = r_Sid.m_strAccountName;
//m_strDomainName = r_Sid.m_strDomainName;
m_bstrtSid = r_Sid.m_bstrtSid; m_bstrtAccountName = r_Sid.m_bstrtAccountName; m_bstrtDomainName = r_Sid.m_bstrtDomainName; } catch(...) { if(m_pSid != NULL) { free(m_pSid); m_pSid = NULL; } throw; } } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::~CSid
//
// Class destructor
//
// Inputs:
// None.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid::~CSid( void ) { if ( m_pSid != NULL ) free ( m_pSid ); }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::operator=
//
// Equals operator.
//
// Inputs:
// const CSid r_Sid - CSid to copy.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
CSid & CSid::operator= ( const CSid &r_Sid ) { free( m_pSid ); m_pSid = NULL; // Handle WINNT SID pointer first
// pSid should be valid...
ASSERT_BREAK( r_Sid.IsValid( ) );
// if we do not
if (r_Sid.IsValid( )) { // Allocate a new SID and copy data into it.
DWORD dwSize = ::GetLengthSid( r_Sid.m_pSid ); try { m_pSid = malloc( dwSize ); ASSERT_BREAK( m_pSid != NULL ); if (m_pSid != NULL) { BOOL bResult = ::CopySid( dwSize, m_pSid, r_Sid.m_pSid ); ASSERT_BREAK( bResult ); } else { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
} catch(...) { if(m_pSid != NULL) { free(m_pSid); m_pSid = NULL; } throw; } } // end if
// Now copy all other members
m_snuAccountType = r_Sid.m_snuAccountType; m_dwLastError = r_Sid.m_dwLastError; m_bstrtSid = r_Sid.m_bstrtSid; m_bstrtAccountName = r_Sid.m_bstrtAccountName; m_bstrtDomainName = r_Sid.m_bstrtDomainName;
return ( *this ); }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::operator==
//
// Is Equal To comparison operator.
//
// Inputs:
// const CSid r_Sid - CSid to compare.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
BOOL CSid::operator== ( const CSid &r_Sid ) const { BOOL fReturn = FALSE;
// Call Equal SID only if both sids are non-NULL
if (IsValid() && r_Sid.IsValid() ) { fReturn = EqualSid( m_pSid, r_Sid.m_pSid ); } else { fReturn = ( m_pSid == r_Sid.m_pSid ); }
return fReturn; }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::GetDomainAccountName
//
// Obtains account name in "DOMAIN\NAME" format.
//
// Inputs:
// const CSid r_Sid - CSid to compare.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
// If Domain Name is empty, the return value will be only NAME.
//
///////////////////////////////////////////////////////////////////
void CSid::GetDomainAccountName( CHString& strName ) const { if ( m_bstrtDomainName.length() == 0 ) { strName = (wchar_t*)m_bstrtAccountName; } else { strName = (wchar_t*)m_bstrtDomainName; strName += _T('\\'); strName += (wchar_t*)m_bstrtAccountName; } }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::StringFromSid
//
// Static helper function to convert a PSID value into a human
// readable string.
//
// Inputs:
// PSID psid - SID to convert.
//
// Outputs:
// CHString& str - Storage for converted PSID
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
void CSid::StringFromSid( PSID psid, CHString& str ) { // Initialize m_strSid - human readable form of our SID
SID_IDENTIFIER_AUTHORITY *psia = NULL; psia = ::GetSidIdentifierAuthority( psid );
// We assume that only last byte is used (authorities between 0 and 15).
// Correct this if needed.
ASSERT_BREAK( psia->Value[0] == psia->Value[1] == psia->Value[2] == psia->Value[3] == psia->Value[4] == 0 ); DWORD dwTopAuthority = psia->Value[5];
str.Format( L"S-1-%u", dwTopAuthority ); CHString strSubAuthority; int iSubAuthorityCount = *( GetSidSubAuthorityCount( psid ) ); for ( int i = 0; i < iSubAuthorityCount; i++ ) {
DWORD dwSubAuthority = *( GetSidSubAuthority( psid, i ) ); strSubAuthority.Format( L"%u", dwSubAuthority ); str += _T("-") + strSubAuthority; } }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::StringFromSid
//
// Static helper function to convert a PSID value into a human
// readable string.
//
// Inputs:
// PSID psid - SID to convert.
//
// Outputs:
// CHString& str - Storage for converted PSID
//
// Returns:
// None.
//
// Comments: This version supports wide chars when UNICODE isn't
// defined.
//
///////////////////////////////////////////////////////////////////
void CSid::StringFromSidW( PSID psid, WCHAR** wstr ) { if(wstr!=NULL) { // Initialize m_strSid - human readable form of our SID
SID_IDENTIFIER_AUTHORITY *psia = ::GetSidIdentifierAuthority( psid );
// We assume that only last byte is used (authorities between 0 and 15).
// Correct this if needed.
ASSERT_BREAK( psia->Value[0] == psia->Value[1] == psia->Value[2] == psia->Value[3] == psia->Value[4] == 0 ); DWORD dwTopAuthority = psia->Value[5];
_bstr_t bstrtTempSid(L"S-1-"); WCHAR wstrAuth[32]; ZeroMemory(wstrAuth,sizeof(wstrAuth)); _ultow(dwTopAuthority,wstrAuth,10); bstrtTempSid+=wstrAuth; int iSubAuthorityCount = *( GetSidSubAuthorityCount( psid ) ); for ( int i = 0; i < iSubAuthorityCount; i++ ) {
DWORD dwSubAuthority = *( GetSidSubAuthority( psid, i ) ); ZeroMemory(wstrAuth,sizeof(wstrAuth)); _ultow(dwSubAuthority,wstrAuth,10); bstrtTempSid += L"-"; bstrtTempSid += wstrAuth; } // Now allocate the passed in wstr:
WCHAR* wstrtemp = NULL; try { wstrtemp = (WCHAR*) new WCHAR[bstrtTempSid.length() + 1]; if(wstrtemp!=NULL) { ZeroMemory(wstrtemp, bstrtTempSid.length() + 1); wcscpy(wstrtemp,(WCHAR*)bstrtTempSid); } *wstr = wstrtemp; } catch(...) { if(wstrtemp!=NULL) { delete wstrtemp; wstrtemp = NULL; } throw; } } }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::GetLength
//
// Returns the length of the internal PSID value.
//
// Inputs:
// None.
//
// Outputs:
// None.
//
// Returns:
// None.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
DWORD CSid::GetLength( void ) const { DWORD dwLength = 0;
if ( IsValid() ) { dwLength = GetLengthSid( m_pSid ); }
return dwLength; }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::InitFromAccountName
//
// Initializes the object from an account name.
//
// Inputs:
// LPCTSTR pszAccountName - Account name to validate
// and obtain info for.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
//
// Outputs:
// None.
//
// Returns:
// DWORD ERROR_SUCCESS if OK.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
DWORD CSid::InitFromAccountName( LPCTSTR pszAccountName, LPCTSTR pszComputerName ) { CHString strAccountName = pszAccountName; CHString strComputerName = pszComputerName;
// Account name should not be empty...
ASSERT_BREAK( !strAccountName.IsEmpty() );
// We need to obtain a SID first
DWORD dwSidSize = 0; DWORD dwDomainNameStrSize = 0; LPTSTR pszDomainName = NULL; BOOL bResult; { // This call should fail
bResult = ::LookupAccountName( TOBSTRT(strComputerName), TOBSTRT(strAccountName), m_pSid, &dwSidSize, pszDomainName, &dwDomainNameStrSize, &m_snuAccountType ); m_dwLastError = ::GetLastError();
}
ASSERT_BREAK( bResult == FALSE ); // ASSERT_BREAK( ERROR_INSUFFICIENT_BUFFER == m_dwLastError );
if ( ERROR_INSUFFICIENT_BUFFER == m_dwLastError ) { // Allocate buffers
m_pSid = NULL; pszDomainName = NULL; try { m_pSid = (PSID) malloc( dwSidSize ); pszDomainName = (LPTSTR) malloc( dwDomainNameStrSize * sizeof(TCHAR) ); if ((m_pSid == NULL) || (pszDomainName == NULL)) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
{ // Make the second call
bResult = ::LookupAccountName( TOBSTRT(strComputerName), TOBSTRT(strAccountName), m_pSid, &dwSidSize, pszDomainName, &dwDomainNameStrSize, &m_snuAccountType ); }
if ( bResult ) {
CHString chsSidTemp; StringFromSid( m_pSid, chsSidTemp ); m_bstrtSid = chsSidTemp;
// Initialize account name and domain name
// If the account name begins with "Domain\", remove that piece.
CHString strDomain(pszDomainName);
strDomain += _T('\\');
if ( 0 == strAccountName.Find( strDomain ) ) { m_bstrtAccountName = strAccountName.Right( strAccountName.GetLength() - strDomain.GetLength() ); } else { m_bstrtAccountName = strAccountName; }
m_bstrtDomainName = pszDomainName;
m_dwLastError = ERROR_SUCCESS; // We are good to go.
} else { // Now what went wrong?
m_dwLastError = ::GetLastError(); }
ASSERT_BREAK( ERROR_SUCCESS == m_dwLastError );
// Free the sid buffer if we didn't get our data
if ( !IsOK() && NULL != m_pSid ) { free ( m_pSid ); m_pSid = NULL; }
if ( NULL != pszDomainName ) { free ( pszDomainName ); } } catch(...) { if(m_pSid != NULL) { free(m_pSid); m_pSid = NULL; } if(pszDomainName != NULL) { free(pszDomainName); pszDomainName = NULL; } throw; }
} // IF ERROR_INSUFFICIENT_BUFFER
return m_dwLastError; }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::InitFromAccountNameW
//
// Initializes the object from an account name.
//
// Inputs:
// LPCTSTR pszAccountName - Account name to validate
// and obtain info for.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
//
// Outputs:
// None.
//
// Returns:
// DWORD ERROR_SUCCESS if OK.
//
// Comments: This flavor is used for wide char support when
// UNICODE is not defined.
//
///////////////////////////////////////////////////////////////////
DWORD CSid::InitFromAccountNameW(LPCWSTR wstrAccountName, LPCWSTR wstrComputerName ) { // Account name should not be empty...
ASSERT_BREAK(wcslen(wstrAccountName)!=0);
// We need to obtain a SID first
DWORD dwSidSize = 0; DWORD dwDomainNameStrSize = 0; WCHAR* wstrDomainName = NULL; BOOL bResult; { // This call should fail
bResult = ::LookupAccountNameW(wstrComputerName, wstrAccountName, m_pSid, &dwSidSize, wstrDomainName, &dwDomainNameStrSize, &m_snuAccountType ); } m_dwLastError = ::GetLastError();
ASSERT_BREAK( bResult == FALSE );
if (m_dwLastError == ERROR_INSUFFICIENT_BUFFER) { // Allocate buffers
m_pSid = NULL; try { m_pSid = (PSID) malloc( dwSidSize ); wstrDomainName = (WCHAR*) new WCHAR[dwDomainNameStrSize]; if (( m_pSid == NULL ) || ( wstrDomainName == NULL ) ) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
{ // Make the second call
bResult = ::LookupAccountNameW(wstrComputerName, wstrAccountName, m_pSid, &dwSidSize, wstrDomainName, &dwDomainNameStrSize, &m_snuAccountType ); } if(bResult) { WCHAR* pwch = NULL; WCHAR* pwchSid = NULL; try { StringFromSidW( m_pSid, &pwchSid ); m_bstrtSid = (LPCWSTR)pwchSid; if(pwchSid != NULL) { delete pwchSid; } } catch(...) { if(pwchSid != NULL) { delete pwchSid; } throw; }
// Initialize account name and domain name
// If the account name begins with "Domain\", remove that piece.
_bstr_t bstrtDomain(wstrDomainName); bstrtDomain += L"\\";
if((pwch = wcsstr(wstrAccountName,bstrtDomain)) != NULL) { m_bstrtAccountName = wstrAccountName + bstrtDomain.length(); } else { m_bstrtAccountName = wstrAccountName; } m_bstrtDomainName = wstrDomainName; m_dwLastError = ERROR_SUCCESS; // We are good to go.
} else { // Now what went wrong?
m_dwLastError = ::GetLastError(); }
ASSERT_BREAK( ERROR_SUCCESS == m_dwLastError );
// Free the sid buffer if we didn't get our data
if ( !IsOK() && NULL != m_pSid ) { free ( m_pSid ); m_pSid = NULL; }
if ( NULL != wstrDomainName ) { delete wstrDomainName; } } catch(...) { if(m_pSid != NULL) { free(m_pSid); m_pSid = NULL; } if ( NULL != wstrDomainName ) { delete wstrDomainName; wstrDomainName = NULL; } throw; }
} // IF ERROR_INSUFFICIENT_BUFFER
return m_dwLastError; }
///////////////////////////////////////////////////////////////////
//
// Function: CSid::InitFromSid
//
// Initializes the object from a PSid
//
// Inputs:
// PSID pSid - PSid to look up.
// LPCTSTR pszComputerName - Remote computer to
// execute on.
// bool fLookup - indicates whether to determine
// the domain and account associated with
// the sid at this time.
//
//
// Outputs:
// None.
//
// Returns:
// DWORD ERROR_SUCCESS if OK.
//
// Comments:
//
///////////////////////////////////////////////////////////////////
DWORD CSid::InitFromSid( PSID pSid, LPCTSTR pszComputerName, bool fLookup ) { // pSid should be valid...
ASSERT_BREAK( (pSid != NULL) && ::IsValidSid( pSid ) );
if ( (pSid != NULL) && ::IsValidSid( pSid ) ) { // Allocate a new SID and copy data into it.
DWORD dwSize = ::GetLengthSid( pSid ); m_pSid = NULL; try { m_pSid = malloc( dwSize ); if (m_pSid == NULL) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; }
BOOL bResult = ::CopySid( dwSize, m_pSid, pSid ); ASSERT_BREAK( bResult );
//StringFromSid( pSid, m_strSid );
WCHAR* pwstrSid = NULL; try { StringFromSidW( pSid, &pwstrSid ); m_bstrtSid = pwstrSid; delete pwstrSid; } catch(...) { if(pwstrSid != NULL) { delete pwstrSid; pwstrSid = NULL; } throw; } if(fLookup) { // Initialize account name and domain name
LPTSTR pszAccountName = NULL; LPTSTR pszDomainName = NULL; DWORD dwAccountNameSize = 0; DWORD dwDomainNameSize = 0; try { { // This call should fail
bResult = ::LookupAccountSid( pszComputerName, pSid, pszAccountName, &dwAccountNameSize, pszDomainName, &dwDomainNameSize, &m_snuAccountType ); m_dwLastError = ::GetLastError(); }
// Why were we breaking on these when we are expecting them to
// always happend?
//ASSERT_BREAK( bResult == FALSE );
//ASSERT_BREAK( ERROR_INSUFFICIENT_BUFFER == m_dwLastError );
if ( ERROR_INSUFFICIENT_BUFFER == m_dwLastError ) {
// Allocate buffers
if ( dwAccountNameSize != 0 ) { pszAccountName = (LPTSTR) malloc( dwAccountNameSize * sizeof(TCHAR)); if (pszAccountName == NULL) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } }
if ( dwDomainNameSize != 0 ) { pszDomainName = (LPTSTR) malloc( dwDomainNameSize * sizeof(TCHAR)); if (pszDomainName == NULL) { throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ; } }
{ // Make second call
bResult = ::LookupAccountSid( pszComputerName, pSid, pszAccountName, &dwAccountNameSize, pszDomainName, &dwDomainNameSize, &m_snuAccountType ); }
if ( bResult == TRUE ) { m_bstrtAccountName = pszAccountName; m_bstrtDomainName = pszDomainName;
// We're OKAY
m_dwLastError = ERROR_SUCCESS; } else {
// There are some accounts that do not have names, such as Logon Ids,
// for example S-1-5-X-Y. So this is still legal
m_bstrtAccountName = _T("Unknown Account"); m_bstrtDomainName = _T("Unknown Domain");
// Log the error
m_dwLastError = ::GetLastError();
}
ASSERT_BREAK( ERROR_SUCCESS == m_dwLastError );
if ( NULL != pszAccountName ) { free ( pszAccountName ); pszAccountName = NULL; }
if ( NULL != pszDomainName ) { free ( pszDomainName ); pszDomainName = NULL; }
} // If ERROR_INSUFFICIENT_BUFFER
} // try
catch(...) { if ( NULL != pszAccountName ) { free ( pszAccountName ); pszAccountName = NULL; }
if ( NULL != pszDomainName ) { free ( pszDomainName ); pszDomainName = NULL; } throw; } } // fLookup
} //try
catch(...) { if(m_pSid != NULL) { free(m_pSid); m_pSid = NULL; } throw; }
} // IF IsValidSid
else { m_dwLastError = ERROR_INVALID_PARAMETER; }
return m_dwLastError;
}
#ifdef NTONLY
void CSid::DumpSid(LPCWSTR wstrFilename) { CHString chstrTemp1((LPCWSTR)m_bstrtSid); CHString chstrTemp2;
Output(L"SID contents follow...", wstrFilename); // Output the sid string:
chstrTemp2.Format(L"SID string: %s", (LPCWSTR)chstrTemp1); Output(chstrTemp2, wstrFilename);
// Output the name:
if(m_bstrtAccountName.length() > 0) { chstrTemp2.Format(L"SID account name: %s", (LPCWSTR)m_bstrtAccountName); Output(chstrTemp2, wstrFilename); } else { chstrTemp2.Format(L"SID account name was not available"); Output(chstrTemp2, wstrFilename); }
// Output the domain:
if(m_bstrtDomainName.length() > 0) { chstrTemp2.Format(L"SID domain name: %s", (LPCWSTR)m_bstrtDomainName); Output(chstrTemp2, wstrFilename); } else { chstrTemp2.Format(L"SID domain name was not available"); Output(chstrTemp2, wstrFilename); } } #endif
|