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.
 
 
 
 
 
 

333 lines
8.2 KiB

//
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996-2001
//
// Author: AdamEd
// Date: January 2000
//
// Abstractions for directory service layer
//
//
//---------------------------------------------------------------------
#include "cstore.hxx"
CServerContext::CServerContext() :
_wszServerName( NULL )
{
}
CServerContext::~CServerContext()
{
delete [] _wszServerName;
}
HRESULT
CServerContext::Initialize(
CServerContext* pServerContext )
{
return Initialize(
pServerContext->GetServerName() );
}
HRESULT
CServerContext::Initialize(
WCHAR* wszServerName )
{
if ( wszServerName )
{
_wszServerName = StringDuplicate( wszServerName );
if ( ! _wszServerName )
{
return E_OUTOFMEMORY;
}
}
return S_OK;
}
BOOL
CServerContext::Compare( CServerContext* pServerContext )
{
//
// If the caller doesn't specify a context, this is equivalent to the
// case where our context has no state
//
if ( ! pServerContext )
{
if ( ! _wszServerName )
{
return TRUE;
}
return FALSE;
}
//
// The caller specified the context, so we ensure they both have state
// or they both don't -- if there is a difference, they are not equivalent
//
if ( ( NULL == _wszServerName ) != ( NULL == pServerContext->_wszServerName ) )
{
return FALSE;
}
//
// We now compare all state specified in this context and the specified context
//
if ( _wszServerName )
{
if ( CSTR_EQUAL != CompareString(
LOCALE_INVARIANT,
NORM_IGNORECASE,
_wszServerName,
wcslen( _wszServerName ),
pServerContext->_wszServerName,
wcslen( pServerContext->_wszServerName ) ) )
{
return FALSE;
}
}
return TRUE;
}
WCHAR*
CServerContext::GetServerName()
{
return _wszServerName;
}
//*************************************************************
//
// DoesPathContainAServerName()
//
// Purpose: Checks the given ADSI path to see if it
// contains a server name
//
// Parameters: lpPath - ADSI path
//
// Return: True if the path contains a server name
// FALSE if not
//
//*************************************************************
BOOL DoesPathContainAServerName (LPTSTR lpPath)
{
BOOL bResult = FALSE;
//
// Skip over LDAP:// if found
//
if ( CompareString( LOCALE_INVARIANT, NORM_IGNORECASE,
lpPath, 7, L"LDAP://", 7 ) == CSTR_EQUAL )
{
lpPath += 7;
}
//
// Check if the 3rd character in the path is an equal sign.
// If so, this path does not contain a server name
//
if ((lstrlen(lpPath) > 2) && (*(lpPath + 2) != TEXT('=')))
{
bResult = TRUE;
}
return bResult;
}
HRESULT
DSGetAndValidateColumn(
HANDLE hDSObject,
ADS_SEARCH_HANDLE hSearchHandle,
ADSTYPE ADsType,
LPWSTR pszColumnName,
PADS_SEARCH_COLUMN pColumn
)
{
HRESULT hr;
//
// First, instruct adsi to unmarshal the data into
// the column
//
hr = ADSIGetColumn(
hDSObject,
hSearchHandle,
pszColumnName,
pColumn);
//
// Validate the returned data
//
if ( SUCCEEDED(hr) )
{
//
// Verify that the type information is correct --
// if it is not, we cannot safely interpret the data.
// Incorrect type information is most likely to happen
// when adsi is unable to download the schema, possibly
// due to kerberos errors
//
if ( ADsType != pColumn->dwADsType )
{
//
// We need to free the column, since the caller is not
// expected to free it if we return a failure
//
ADSIFreeColumn( hDSObject, pColumn );
hr = CS_E_SCHEMA_MISMATCH;
}
}
return hr;
}
HRESULT DSAccessCheck(
PSECURITY_DESCRIPTOR pSD,
PRSOPTOKEN pRsopUserToken,
BOOL* pbAccessAllowed
)
{
GENERIC_MAPPING DS_GENERIC_MAPPING = {
GENERIC_READ_MAPPING,
GENERIC_WRITE_MAPPING,
GENERIC_EXECUTE_MAPPING,
GENERIC_ALL_MAPPING };
DWORD dwAccessMask;
HRESULT hr;
hr = S_OK;
if ( pRsopUserToken )
{
hr = RsopAccessCheckByType(pSD,
0,
pRsopUserToken,
GENERIC_READ,
NULL,
0,
&DS_GENERIC_MAPPING,
NULL,
NULL,
&dwAccessMask,
pbAccessAllowed );
}
else
{
//
// A null user token means we are running in
// reporting mode where we are trying to dump the
// contents of the gpo rather than simulate what
// apps the target might receive,
// so we should not try to perform
// an access check (we are running as some user, not
// as the system). Instead, if we retrieved the app,
// we have access, so we always return TRUE in this case
//
*pbAccessAllowed = TRUE;
}
return hr;
}
HRESULT
DSServerOpenDSObject(
CServerContext* pServerContext,
LPWSTR pszDNName,
LONG lFlags,
PHANDLE phDSObject
)
{
WCHAR* wszServerBasedPath = NULL;
WCHAR* wszServerName = pServerContext ? pServerContext->GetServerName() : NULL;
WCHAR* wszPath = pszDNName;
BOOL bServerName = FALSE;
//
// Check to see if there's a server name in the path -- only do this
// if the caller is specifying a server name -- otherwise, we assume
// that there is no server name in the path (a domain name may be specified,
// but that is not the same as a server).
//
if ( wszServerName && DoesPathContainAServerName( wszPath ) )
{
lFlags |= ADS_SERVER_BIND;
bServerName = TRUE;
}
//
// If a server is specified and the path doesn't already have a server, we need to create a server based LDAP path
// to pass to adsi
//
if ( ! bServerName && wszServerName )
{
//
// The DN passed to this function is a serverless path of the form
//
// LDAP://<DN>
//
// We need to transform it to a path of the form
//
// LDAP://<Server>/<DN>
//
// We first allocate space for the transformation
//
DWORD cchServerBasedPath = wcslen( wszServerName ) + 1 + wcslen( pszDNName ) + 1;
wszServerBasedPath = new WCHAR [ cchServerBasedPath ];
if ( NULL == wszServerBasedPath )
{
return E_OUTOFMEMORY;
}
//
// Perform the transformation
//
(void) StringCchCopy( wszServerBasedPath, cchServerBasedPath, LDAPPREFIX );
(void) StringCchCat( wszServerBasedPath, cchServerBasedPath, wszServerName );
(void) StringCchCat( wszServerBasedPath, cchServerBasedPath, L"/" );
(void) StringCchCat( wszServerBasedPath, cchServerBasedPath, pszDNName + sizeof( LDAPPREFIX ) / sizeof(WCHAR) - 1 );
wszPath = wszServerBasedPath;
//
// Since we are binding to a server, add the flag that gives
// the hint to ldap to bind
//
lFlags |= ADS_SERVER_BIND;
}
HRESULT hr;
hr = ADSIOpenDSObject(
wszPath,
NULL,
NULL,
lFlags,
phDSObject);
if ( wszServerBasedPath )
{
delete [] wszServerBasedPath;
}
return hr;
}