Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1108 lines
32 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: ldapstor.cpp
//
// Contents: Ldap Store Provider implementation
//
// History: 17-Oct-97 kirtd Created
// 01-Jan-02 philh Changed to internally use UNICODE Urls
//
//----------------------------------------------------------------------------
#include <global.hxx>
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::CLdapStore, public
//
// Synopsis: Constructor
//
//----------------------------------------------------------------------------
CLdapStore::CLdapStore (
OUT BOOL& rfResult
)
: m_pBinding( NULL ),
m_hCacheStore( NULL ),
m_dwOpenFlags( 0 ),
m_fDirty( FALSE )
{
rfResult = TRUE;
memset( &m_UrlComponents, 0, sizeof( m_UrlComponents ) );
if (! Pki_InitializeCriticalSection( &m_StoreLock ))
{
rfResult = FALSE;
}
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::~CLdapStore, public
//
// Synopsis: Destructor
//
//----------------------------------------------------------------------------
CLdapStore::~CLdapStore ()
{
DeleteCriticalSection( &m_StoreLock );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::OpenStore, public
//
// Synopsis: open store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::OpenStore (
LPCSTR pszStoreProv,
DWORD dwMsgAndCertEncodingType,
HCRYPTPROV hCryptProv,
DWORD dwFlags,
const void* pvPara,
HCERTSTORE hCertStore,
PCERT_STORE_PROV_INFO pStoreProvInfo
)
{
BOOL fResult = TRUE;
DWORD dwRetrievalFlags;
DWORD dwBindFlags;
assert( m_pBinding == NULL );
assert( m_hCacheStore == NULL );
assert( m_dwOpenFlags == 0 );
assert( m_fDirty == FALSE );
m_dwOpenFlags = dwFlags;
m_hCacheStore = hCertStore;
if ( pvPara == NULL )
{
SetLastError( (DWORD) E_INVALIDARG );
return( FALSE );
}
if ( (dwFlags & CERT_STORE_UNSAFE_PHYSICAL_FLAG) &&
(dwFlags & CERT_LDAP_STORE_OPENED_FLAG) )
{
SetLastError( (DWORD) E_INVALIDARG );
return( FALSE );
}
__try
{
LPCWSTR pwszUrl;
if (dwFlags & CERT_LDAP_STORE_OPENED_FLAG)
{
PCERT_LDAP_STORE_OPENED_PARA pOpenedPara;
// Will set this before returning. Don't want to do an
// unbind if the open fails.
m_dwOpenFlags &= ~CERT_LDAP_STORE_UNBIND_FLAG;
pOpenedPara = (PCERT_LDAP_STORE_OPENED_PARA) pvPara;
m_pBinding = (LDAP *) pOpenedPara->pvLdapSessionHandle;
pwszUrl = pOpenedPara->pwszLdapUrl;
}
else
{
pwszUrl = (LPCWSTR) pvPara;
m_dwOpenFlags |= CERT_LDAP_STORE_UNBIND_FLAG;
}
if ( LdapCrackUrl( pwszUrl, &m_UrlComponents ) == FALSE )
{
return( FALSE );
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
SetLastError( GetExceptionCode() );
return( FALSE );
}
dwRetrievalFlags = 0;
dwBindFlags = LDAP_BIND_AUTH_SSPI_ENABLE_FLAG |
LDAP_BIND_AUTH_SIMPLE_ENABLE_FLAG;
if (dwFlags & CERT_LDAP_STORE_SIGN_FLAG)
{
dwRetrievalFlags |= CRYPT_LDAP_SIGN_RETRIEVAL;
dwBindFlags &= ~LDAP_BIND_AUTH_SIMPLE_ENABLE_FLAG;
}
if (dwFlags & CERT_LDAP_STORE_AREC_EXCLUSIVE_FLAG)
{
dwRetrievalFlags |= CRYPT_LDAP_AREC_EXCLUSIVE_RETRIEVAL;
dwBindFlags &= ~LDAP_BIND_AUTH_SIMPLE_ENABLE_FLAG;
}
if (!( dwFlags & CERT_LDAP_STORE_OPENED_FLAG ) )
{
fResult = LdapGetBindings(
m_UrlComponents.pwszHost,
m_UrlComponents.Port,
dwRetrievalFlags,
dwBindFlags,
LDAP_STORE_TIMEOUT,
NULL,
&m_pBinding
);
}
if ( ( fResult == TRUE ) && !( dwFlags & CERT_STORE_READONLY_FLAG ) )
{
fResult = LdapHasWriteAccess( m_pBinding, &m_UrlComponents,
LDAP_STORE_TIMEOUT );
if ( fResult == FALSE )
{
SetLastError( (DWORD) ERROR_ACCESS_DENIED );
}
}
if ( fResult == TRUE )
{
if ( m_dwOpenFlags & CERT_STORE_DELETE_FLAG )
{
m_fDirty = TRUE;
fResult = InternalCommit( 0 );
if ( fResult == TRUE )
{
pStoreProvInfo->dwStoreProvFlags = CERT_STORE_PROV_DELETED_FLAG;
if (dwFlags & CERT_LDAP_STORE_UNBIND_FLAG)
{
m_dwOpenFlags |= CERT_LDAP_STORE_UNBIND_FLAG;
}
}
CloseStore( 0 );
return( fResult );
}
fResult = FillCacheStore( FALSE );
// Note, LDAP_REFERRAL gets mapped to ERROR_MORE_DATA. Sometimes
// referral errors aren't detected until doing the ldap search.
if ( !fResult &&
!(dwFlags & CERT_LDAP_STORE_OPENED_FLAG) &&
((LDAP_BIND_AUTH_SSPI_ENABLE_FLAG |
LDAP_BIND_AUTH_SIMPLE_ENABLE_FLAG) == dwBindFlags)
&&
(ERROR_MORE_DATA == GetLastError()) )
{
// Try again doing simple bind.
LdapFreeBindings( m_pBinding );
m_pBinding = NULL;
fResult = LdapGetBindings(
m_UrlComponents.pwszHost,
m_UrlComponents.Port,
dwRetrievalFlags,
LDAP_BIND_AUTH_SIMPLE_ENABLE_FLAG,
LDAP_STORE_TIMEOUT,
NULL,
&m_pBinding
);
if ( fResult )
{
fResult = FillCacheStore( FALSE );
}
}
}
if ( fResult == TRUE )
{
pStoreProvInfo->cStoreProvFunc = LDAP_PROV_FUNC_COUNT;
pStoreProvInfo->rgpvStoreProvFunc = (void **)rgpvLdapProvFunc;
pStoreProvInfo->hStoreProv = (HCERTSTOREPROV)this;
if (dwFlags & CERT_LDAP_STORE_UNBIND_FLAG)
{
m_dwOpenFlags |= CERT_LDAP_STORE_UNBIND_FLAG;
}
}
else
{
CloseStore( 0 );
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::CloseStore, public
//
// Synopsis: close the store
//
//----------------------------------------------------------------------------
VOID
CLdapStore::CloseStore (DWORD dwFlags)
{
DWORD LastError = GetLastError();
EnterCriticalSection( &m_StoreLock );
InternalCommit( 0 );
LdapFreeUrlComponents( &m_UrlComponents );
memset( &m_UrlComponents, 0, sizeof( m_UrlComponents ) );
if (m_dwOpenFlags & CERT_LDAP_STORE_UNBIND_FLAG)
{
LdapFreeBindings( m_pBinding );
}
m_pBinding = NULL;
LeaveCriticalSection( &m_StoreLock );
SetLastError( LastError );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::DeleteCert, public
//
// Synopsis: delete cert from store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::DeleteCert (PCCERT_CONTEXT pCertContext, DWORD dwFlags)
{
return( WriteCheckSetDirtyWithLock(
CONTEXT_OID_CERTIFICATE,
(LPVOID)pCertContext,
0
) );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::DeleteCrl, public
//
// Synopsis: delete CRL from store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::DeleteCrl (PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
{
return( WriteCheckSetDirtyWithLock(
CONTEXT_OID_CRL,
(LPVOID)pCrlContext,
0
) );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::DeleteCtl, public
//
// Synopsis: delete CTL from store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::DeleteCtl (PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
{
return( WriteCheckSetDirtyWithLock(
CONTEXT_OID_CTL,
(LPVOID)pCtlContext,
0
) );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::SetCertProperty, public
//
// Synopsis: set a property on the cert
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::SetCertProperty (
PCCERT_CONTEXT pCertContext,
DWORD dwPropId,
DWORD dwFlags,
const void* pvPara
)
{
// NOTENOTE: Properties are NOT persisted
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::SetCrlProperty, public
//
// Synopsis: set a property on the CRL
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::SetCrlProperty (
PCCRL_CONTEXT pCrlContext,
DWORD dwPropId,
DWORD dwFlags,
const void* pvPara
)
{
// NOTENOTE: Properties are NOT persisted
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::SetCtlProperty, public
//
// Synopsis: set a property on the CTL
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::SetCtlProperty (
PCCTL_CONTEXT pCrlContext,
DWORD dwPropId,
DWORD dwFlags,
const void* pvPara
)
{
// NOTENOTE: Properties are NOT persisted
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::WriteCert, public
//
// Synopsis: write cert to store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::WriteCert (PCCERT_CONTEXT pCertContext, DWORD dwFlags)
{
return( WriteCheckSetDirtyWithLock(
CONTEXT_OID_CERTIFICATE,
(LPVOID)pCertContext,
dwFlags
) );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::WriteCrl, public
//
// Synopsis: write CRL to store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::WriteCrl (PCCRL_CONTEXT pCrlContext, DWORD dwFlags)
{
return( WriteCheckSetDirtyWithLock(
CONTEXT_OID_CRL,
(LPVOID)pCrlContext,
dwFlags
) );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::WriteCtl, public
//
// Synopsis: write CTL to store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::WriteCtl (PCCTL_CONTEXT pCtlContext, DWORD dwFlags)
{
return( WriteCheckSetDirtyWithLock(
CONTEXT_OID_CTL,
(LPVOID)pCtlContext,
dwFlags
) );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::StoreControl, public
//
// Synopsis: store control dispatch
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::StoreControl (DWORD dwFlags, DWORD dwCtrlType, LPVOID pvCtrlPara)
{
switch ( dwCtrlType )
{
case CERT_STORE_CTRL_COMMIT:
return( Commit( dwFlags ) );
case CERT_STORE_CTRL_RESYNC:
return( Resync() );
}
SetLastError( (DWORD) ERROR_CALL_NOT_IMPLEMENTED );
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::Commit, public
//
// Synopsis: commit the store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::Commit (DWORD dwFlags)
{
BOOL fResult;
EnterCriticalSection( &m_StoreLock );
fResult = InternalCommit( dwFlags );
LeaveCriticalSection( &m_StoreLock );
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::Resync, public
//
// Synopsis: resync the store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::Resync ()
{
BOOL fResult;
EnterCriticalSection( &m_StoreLock );
fResult = FillCacheStore( TRUE );
LeaveCriticalSection( &m_StoreLock );
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::FillCacheStore, private
//
// Synopsis: fill the cache store
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::FillCacheStore (BOOL fClearCache)
{
BOOL fResult;
CRYPT_BLOB_ARRAY cba;
if ( fClearCache == TRUE )
{
if ( ObjectContextDeleteAllObjectsFromStore( m_hCacheStore ) == FALSE )
{
return( FALSE );
}
}
fResult = LdapSendReceiveUrlRequest(
m_pBinding,
&m_UrlComponents,
0, // dwRetrievalFlags
LDAP_STORE_TIMEOUT,
&cba,
NULL
);
if (fResult)
{
HCERTSTORE hStore = NULL;
fResult = CreateObjectContext (
CRYPT_RETRIEVE_MULTIPLE_OBJECTS,
&cba,
CERT_QUERY_CONTENT_FLAG_CERT |
CERT_QUERY_CONTENT_FLAG_CTL |
CERT_QUERY_CONTENT_FLAG_CRL |
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
CERT_QUERY_CONTENT_FLAG_CERT_PAIR,
FALSE, // fQuerySingleContext
(LPVOID*) &hStore
);
if (fResult)
{
fResult = I_CertUpdateStore( m_hCacheStore, hStore, 0, NULL );
CertCloseStore( hStore, 0 );
}
CCryptBlobArray BlobArray( &cba, 0 );
BlobArray.FreeArray( TRUE );
}
else if (GetLastError() == CRYPT_E_NOT_FOUND)
{
fResult = TRUE;
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::InternalCommit, private
//
// Synopsis: commit current changes
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::InternalCommit (DWORD dwFlags)
{
BOOL fResult = TRUE;
LPCSTR pszContextOid = CONTEXT_OID_CERTIFICATE;
LPVOID pvContext = NULL;
struct berval** abv;
struct berval** newabv;
DWORD cbv = 0;
DWORD cCount;
DWORD cArray = MIN_BERVAL;
if ( dwFlags & CERT_STORE_CTRL_COMMIT_CLEAR_FLAG )
{
m_fDirty = FALSE;
return( TRUE );
}
if ( m_dwOpenFlags & CERT_STORE_READONLY_FLAG )
{
SetLastError( (DWORD) ERROR_ACCESS_DENIED );
return( FALSE );
}
if ( ( m_fDirty == FALSE ) &&
!( dwFlags & CERT_STORE_CTRL_COMMIT_FORCE_FLAG ) )
{
return( TRUE );
}
abv = (struct berval**)malloc( cArray * sizeof( struct berval* ) );
if ( abv == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
memset( abv, 0, cArray * sizeof( struct berval * ) );
while ( ( fResult == TRUE ) &&
( ( pvContext = ObjectContextEnumObjectsInStore(
m_hCacheStore,
pszContextOid,
pvContext,
&pszContextOid
) ) != NULL ) )
{
abv[cbv] = (struct berval*)malloc( sizeof( struct berval ) );
if ( abv[cbv] != NULL )
{
ObjectContextGetEncodedBits(
pszContextOid,
pvContext,
&(abv[cbv]->bv_len),
(LPBYTE *)&(abv[cbv]->bv_val)
);
cbv += 1;
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
fResult = FALSE;
ObjectContextFree( pszContextOid, pvContext );
}
if ( cbv == ( cArray - 1 ) )
{
newabv = (struct berval**)realloc(
abv,
( cArray + GROW_BERVAL ) *
sizeof( struct berval* )
);
if ( newabv != NULL )
{
abv = newabv;
memset( &abv[cArray], 0, GROW_BERVAL * sizeof( struct berval* ) );
cArray += GROW_BERVAL;
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
fResult = FALSE;
}
}
}
if ( fResult == TRUE )
{
ULONG lderr;
LDAPModW mod;
LDAPModW* amod[2];
assert( m_UrlComponents.cAttr == 1 );
mod.mod_type = m_UrlComponents.apwszAttr[0];
mod.mod_op = LDAP_MOD_BVALUES;
amod[0] = &mod;
amod[1] = NULL;
if ( cbv > 0 )
{
mod.mod_op |= LDAP_MOD_REPLACE;
mod.mod_bvalues = abv;
}
else
{
mod.mod_op |= LDAP_MOD_DELETE;
mod.mod_bvalues = NULL;
}
if ( ( lderr = ldap_modify_sW(
m_pBinding,
m_UrlComponents.pwszDN,
amod
) ) == LDAP_SUCCESS )
{
m_fDirty = FALSE;
}
else
{
SetLastError( I_CryptNetLdapMapErrorToWin32( m_pBinding, lderr ) );
fResult = FALSE;
}
}
for ( cCount = 0; cCount < cbv; cCount++ )
{
free( abv[cCount] );
}
free( abv );
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Member: CLdapStore::WriteCheckSetDirtyWithLock, private
//
// Synopsis: if the store is writable, set the dirty flag taking the store
// lock where appropriate
//
//----------------------------------------------------------------------------
BOOL
CLdapStore::WriteCheckSetDirtyWithLock (
LPCSTR pszContextOid,
LPVOID pvContext,
DWORD dwFlags
)
{
if ( m_dwOpenFlags & CERT_STORE_READONLY_FLAG )
{
SetLastError( (DWORD) ERROR_ACCESS_DENIED );
return( FALSE );
}
EnterCriticalSection( &m_StoreLock );
if ( ( dwFlags >> 16 ) == CERT_STORE_ADD_ALWAYS )
{
LPVOID pv;
if ( ( pv = ObjectContextFindCorrespondingObject(
m_hCacheStore,
pszContextOid,
pvContext
) ) != NULL )
{
ObjectContextFree( pszContextOid, pv );
SetLastError( (DWORD) CRYPT_E_EXISTS );
LeaveCriticalSection( &m_StoreLock );
return( FALSE );
}
}
m_fDirty = TRUE;
LeaveCriticalSection( &m_StoreLock );
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvOpenStore
//
// Synopsis: provider open store entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvOpenStore (
IN LPCSTR pszStoreProv,
IN DWORD dwMsgAndCertEncodingType,
IN HCRYPTPROV hCryptProv,
IN DWORD dwFlags,
IN const void* pvPara,
IN HCERTSTORE hCertStore,
IN OUT PCERT_STORE_PROV_INFO pStoreProvInfo
)
{
BOOL fResult = FALSE;
CLdapStore* pLdap;
pLdap = new CLdapStore ( fResult );
if ( pLdap == NULL )
{
SetLastError( (DWORD) E_OUTOFMEMORY );
return( FALSE );
}
if ( fResult == FALSE )
{
delete pLdap;
return( FALSE );
}
fResult = pLdap->OpenStore(
pszStoreProv,
dwMsgAndCertEncodingType,
hCryptProv,
dwFlags,
pvPara,
hCertStore,
pStoreProvInfo
);
if ( fResult == FALSE )
{
delete pLdap;
}
return( fResult );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvCloseStore
//
// Synopsis: provider close store entry point
//
//----------------------------------------------------------------------------
void WINAPI LdapProvCloseStore (
IN HCERTSTOREPROV hStoreProv,
IN DWORD dwFlags
)
{
( (CLdapStore *)hStoreProv )->CloseStore( dwFlags );
delete (CLdapStore *)hStoreProv;
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvDeleteCert
//
// Synopsis: provider delete certificate entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvDeleteCert (
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwFlags
)
{
return( ( (CLdapStore *)hStoreProv )->DeleteCert( pCertContext, dwFlags ) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvDeleteCrl
//
// Synopsis: provider delete CRL entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvDeleteCrl (
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwFlags
)
{
return( ( (CLdapStore *)hStoreProv )->DeleteCrl( pCrlContext, dwFlags ) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvDeleteCtl
//
// Synopsis: provider delete CTL entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvDeleteCtl (
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwFlags
)
{
return( ( (CLdapStore *)hStoreProv )->DeleteCtl( pCtlContext, dwFlags ) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvSetCertProperty
//
// Synopsis: provider set certificate property entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvSetCertProperty (
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void* pvData
)
{
return( ( (CLdapStore *)hStoreProv )->SetCertProperty(
pCertContext,
dwPropId,
dwFlags,
pvData
) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvSetCrlProperty
//
// Synopsis: provider set CRL property entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvSetCrlProperty (
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void* pvData
)
{
return( ( (CLdapStore *)hStoreProv )->SetCrlProperty(
pCrlContext,
dwPropId,
dwFlags,
pvData
) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvSetCtlProperty
//
// Synopsis: provider set CTL property entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvSetCtlProperty (
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwPropId,
IN DWORD dwFlags,
IN const void* pvData
)
{
return( ( (CLdapStore *)hStoreProv )->SetCtlProperty(
pCtlContext,
dwPropId,
dwFlags,
pvData
) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvWriteCert
//
// Synopsis: provider write certificate entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvWriteCert (
IN HCERTSTOREPROV hStoreProv,
IN PCCERT_CONTEXT pCertContext,
IN DWORD dwFlags
)
{
return( ( (CLdapStore *)hStoreProv )->WriteCert( pCertContext, dwFlags ) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvWriteCrl
//
// Synopsis: provider write CRL entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvWriteCrl (
IN HCERTSTOREPROV hStoreProv,
IN PCCRL_CONTEXT pCrlContext,
IN DWORD dwFlags
)
{
return( ( (CLdapStore *)hStoreProv )->WriteCrl( pCrlContext, dwFlags ) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvWriteCtl
//
// Synopsis: provider write CTL entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvWriteCtl (
IN HCERTSTOREPROV hStoreProv,
IN PCCTL_CONTEXT pCtlContext,
IN DWORD dwFlags
)
{
return( ( (CLdapStore *)hStoreProv )->WriteCtl( pCtlContext, dwFlags ) );
}
//+---------------------------------------------------------------------------
//
// Function: LdapProvStoreControl
//
// Synopsis: provider control entry point
//
//----------------------------------------------------------------------------
BOOL WINAPI LdapProvStoreControl (
IN HCERTSTOREPROV hStoreProv,
IN DWORD dwFlags,
IN DWORD dwCtrlType,
IN LPVOID pvCtrlPara
)
{
return( ( (CLdapStore *)hStoreProv )->StoreControl(
dwFlags,
dwCtrlType,
pvCtrlPara
) );
}
//+---------------------------------------------------------------------------
//
// Function: I_CryptNetGetUserDsStoreUrl
//
// Synopsis: get user DS store URL
//
//----------------------------------------------------------------------------
BOOL WINAPI
I_CryptNetGetUserDsStoreUrl (
IN LPWSTR pwszUserAttribute,
OUT LPWSTR* ppwszUrl
)
{
BOOL fResult;
DWORD dwLastError = 0;
WCHAR wszUser[MAX_PATH];
ULONG nUser = MAX_PATH;
LPWSTR pwszUser = wszUser;
HMODULE hModule = NULL;
PFN_GETUSERNAMEEXW pfnGetUserNameExW = NULL;
hModule = LoadLibraryA( "secur32.dll" );
if ( hModule == NULL )
{
return( FALSE );
}
pfnGetUserNameExW = (PFN_GETUSERNAMEEXW)GetProcAddress(
hModule,
"GetUserNameExW"
);
if ( pfnGetUserNameExW == NULL )
{
FreeLibrary( hModule );
return( FALSE );
}
fResult = ( *pfnGetUserNameExW )( NameFullyQualifiedDN, pwszUser, &nUser );
if ( fResult == FALSE )
{
if ( ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) ||
( GetLastError() == ERROR_MORE_DATA ) )
{
pwszUser = new WCHAR [nUser];
if ( pwszUser != NULL )
{
fResult = ( *pfnGetUserNameExW )(
NameFullyQualifiedDN,
pwszUser,
&nUser
);
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
fResult = FALSE;
}
}
}
if ( fResult == TRUE )
{
DWORD cchUrl = 0;
LPWSTR pwszUrl = NULL;
cchUrl = wcslen(USER_DS_STORE_URL_PREFIX) + wcslen(pwszUser) +
wcslen(USER_DS_STORE_URL_SEPARATOR) + wcslen(pwszUserAttribute) + 1;
pwszUrl = (LPWSTR)CryptMemAlloc(cchUrl * sizeof(WCHAR));
if ( pwszUrl != NULL )
{
wcscpy(pwszUrl, USER_DS_STORE_URL_PREFIX);
wcscat(pwszUrl, pwszUser);
wcscat(pwszUrl, USER_DS_STORE_URL_SEPARATOR);
wcscat(pwszUrl, pwszUserAttribute);
*ppwszUrl = pwszUrl;
}
else
{
SetLastError( (DWORD) E_OUTOFMEMORY );
fResult = FALSE;
}
}
dwLastError = GetLastError();
if ( pwszUser != wszUser )
{
delete [] pwszUser;
}
FreeLibrary( hModule );
SetLastError(dwLastError);
return( fResult );
}