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.
 
 
 
 
 
 

1013 lines
20 KiB

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: drt.cxx
//
// Contents: Main for OleDs DRT
//
//
// History: 28-Oct-94 KrishnaG, created OleDs DRT
// 28-Oct-94 ChuckC, rewritten.
//
//----------------------------------------------------------------------------
#include "precomp.h"
// Description:
//
// Ldap utilities expect the domain name to be a fully qualified dns name.
// This function takes a flat or dns name as input, and returns the
// fully qualified dns name as output.
//
// Parameters:
//
// pszDomain - caller supplied domain name to be "cracked"
// pfCracked - TRUE if cracking was required, FALSE if the supplied domain
// name was already in the corrrect form.
// ppszDomain - the cracked name if pfCracked is set to TRUE. Caller
// frees this string with NsuFree.
//
DWORD
CrackDomainName(
IN WCHAR* pszDomain, // domain name from the caller
OUT BOOL* pbCracked, //
OUT WCHAR** ppszDomain) // will point to pszDomain or pszBuffer on success
{
DWORD dwErr = NO_ERROR;
PDOMAIN_CONTROLLER_INFOW pDcInfo = NULL;
// Initialize
//
*pbCracked = FALSE;
*ppszDomain = NULL;
// NULL domain means "use default" to ldap, so no further processing is
// needed.
//
if (pszDomain == NULL) {
return NO_ERROR;
}
// If the domain name contains a period, then assume, that it is already
// a fully qualified dns name.
//
if (wcsstr(pszDomain, L"."))
{
return NO_ERROR;
}
// Otherwise, use DsGetDcName to discover the fully qualified domain name
// of the supplied domain
//
dwErr = DsGetDcNameW(
NULL,
pszDomain,
NULL,
NULL,
DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME,
&pDcInfo);
NSU_BAIL_ON_ERROR(dwErr);
// If the domain name is not returned, then we have a problem
//
if ((pDcInfo == NULL) || (pDcInfo->DomainName == NULL))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
NSU_BAIL_ON_ERROR(dwErr);
}
// Pull out the dns name from the dc info
//
dwErr = NsuStringDupW(
ppszDomain,
4 * 1024, // not supporting > 4k chars names
pDcInfo->DomainName);
NSU_BAIL_ON_ERROR(dwErr);
*pbCracked = TRUE;
NSU_CLEANUP:
if (pDcInfo) {
NetApiBufferFree(pDcInfo);
}
return dwErr;
}
DWORD
LdapOpen(
WCHAR *domainName,
int portno,
HLDAP * phLdapHandle
)
{
int ldaperr = 0;
void *ldapOption;
HLDAP hLdapHandle = NULL;
DWORD dwError = 0;
WCHAR* pszCracked = NULL;
BOOL bCracked = FALSE;
// Discover the domain name in the form ldap expects.
//
// If cracking the name fails, then try to connect using the caller
// supplied domain name anyway before failing altogether.
//
dwError = CrackDomainName(domainName, &bCracked, &pszCracked);
if (dwError == ERROR_SUCCESS) {
if (bCracked) {
domainName = pszCracked;
}
}
dwError = ERROR_SUCCESS;
hLdapHandle = ldap_init(domainName, portno );
if (hLdapHandle == NULL ) {
dwError = ERROR_BAD_NETPATH;
goto error;
}
//
// Now process versioning
//
ldapOption = (void *) LDAP_VERSION3;
ldaperr = ldap_set_option(
hLdapHandle,
LDAP_OPT_VERSION,
&(ldapOption)
);
ldapOption = LDAP_OPT_ON;
//
// Ignoring errors for ldap_set_option because we can't force these on
// non-AD directory services (e.g. NDS)
ldaperr = ldap_set_option(
hLdapHandle,
LDAP_OPT_ENCRYPT,
&(ldapOption)
);
ldaperr = ldap_set_option(
hLdapHandle,
LDAP_OPT_SIGN,
&(ldapOption)
);
ldaperr = ldap_connect(hLdapHandle, NULL);
if (ldaperr) {
dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
goto error;
}
//
// Disabled Callback function support and chasing external referrals
// KrishnaG - do I need to support this.
*phLdapHandle = hLdapHandle;
return(dwError);
error:
if (hLdapHandle != NULL) {
ldaperr = ldap_unbind( hLdapHandle );
}
if (pszCracked != NULL) {
NsuFree(&pszCracked);
}
return (dwError);
}
DWORD
LdapBind(
HLDAP hLdapHandle
)
{
int ldaperr = 0;
ldaperr = ldap_bind_s(hLdapHandle, NULL, NULL, LDAP_AUTH_SSPI);
return (ldaperr);
}
DWORD
LdapSearchHelper(
HLDAP hLdapHandle,
WCHAR *base,
int scope,
WCHAR *filter,
WCHAR *attrs[],
int attrsonly,
struct l_timeval *timeout,
LDAPMessage **res
)
{
int nCount = 0;
int j = 0;
int ldaperr = 0;
DWORD dwError = 0;
if ( timeout == NULL )
{
ldaperr = ldap_search_s(
hLdapHandle,
base,
scope,
filter,
attrs,
attrsonly,
res
);
dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
}
else
{
ldaperr = ldap_search_st(
hLdapHandle,
base,
scope,
filter,
attrs,
attrsonly,
timeout,
res
);
dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
}
//
// Is there an error with checking the no of results
//
return (dwError);
}
DWORD
LdapSearchS(
HLDAP hLdapHandle,
WCHAR *base,
int scope,
WCHAR *filter,
WCHAR *attrs[],
int attrsonly,
LDAPMessage **res
)
{
DWORD dwError = 0;
dwError = LdapSearchHelper(
hLdapHandle,
base,
scope,
filter,
attrs,
attrsonly,
NULL,
res
);
//
// Is there a check needed for connection errors
//
return(dwError);
}
DWORD
LdapSearchST(
HLDAP hLdapHandle,
WCHAR *base,
int scope,
WCHAR *filter,
WCHAR *attrs[],
int attrsonly,
struct l_timeval *timeout,
LDAPMessage **res
)
{
DWORD dwError = 0;
dwError = LdapSearchHelper(
hLdapHandle,
base,
scope,
filter,
attrs,
attrsonly,
timeout,
res
);
return(dwError);
}
//
// Completely new functionality - block ported from YihsinS code in ADSI
//
DWORD
LdapAbandon(
HLDAP hLdapHandle,
int msgid
)
{
// No error code, 0 if success, -1 otherwise
return ldap_abandon( hLdapHandle, msgid );
}
DWORD
LdapResult(
HLDAP hLdapHandle,
int msgid,
int all,
struct l_timeval *timeout,
LDAPMessage **res,
int *restype
)
{
DWORD dwError = 0;
int ldaperr = 0;
*restype = ldap_result( hLdapHandle, msgid, all, timeout, res );
if ( *restype == -1 ) // error
ldaperr = LdapGetLastError();
if (ldaperr) {
if (!ldap_count_entries( hLdapHandle, *res )) {
dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
}
}else {
dwError = 0;
}
return(dwError);
}
void
LdapMsgFree(
LDAPMessage *res
)
{
ldap_msgfree( res ); // Returns the type of message freed which
// is not interesting
}
int
LdapResult2Error(
HLDAP hLdapHandle,
LDAPMessage *res,
int freeit
)
{
return ldap_result2error( hLdapHandle, res, freeit );
}
DWORD
LdapFirstEntry(
HLDAP hLdapHandle,
LDAPMessage *res,
LDAPMessage **pfirst
)
{
DWORD dwError = 0;
int ldaperr = 0;
*pfirst = ldap_first_entry( hLdapHandle, res );
if ( *pfirst == NULL )
{
ldaperr = LdapGetLastError();
dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
}
return(dwError);
}
DWORD
LdapNextEntry(
HLDAP hLdapHandle,
LDAPMessage *entry,
LDAPMessage **pnext
)
{
DWORD dwError = 0;
int ldaperr = 0;
*pnext = ldap_next_entry( hLdapHandle, entry );
if ( *pnext == NULL )
{
ldaperr = LdapGetLastError();
dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
}
return(dwError);
}
int
LdapCountEntries(
HLDAP hLdapHandle,
LDAPMessage *res
)
{
return ldap_count_entries( hLdapHandle, res );
}
DWORD
LdapFirstAttribute(
HLDAP hLdapHandle,
LDAPMessage *entry,
void **ptr,
WCHAR **pattr
)
{
// NOTE: The return value from ldap_first_attribute is static and
// should not be freed
*pattr = ldap_first_attribute( hLdapHandle, entry,
(struct berelement **) ptr ); // static data
if ( *pattr == NULL )
{
DWORD dwError = 0;
int ldaperr = 0;
// Error occurred or end of attributes
ldaperr = LdapGetLastError();
CheckAndSetExtendedError( hLdapHandle, ldaperr);
return(dwError);
}
return NO_ERROR;
}
DWORD
LdapNextAttribute(
HLDAP hLdapHandle,
LDAPMessage *entry,
void *ptr,
WCHAR **pattr
)
{
// NOTE: The return value from ldap_next_attribute is static and
// should not be freed
*pattr = ldap_next_attribute( hLdapHandle, entry,
(struct berelement *) ptr ); // static data
#if 0 // Ignore the error code here since at the end of the enumeration,
// we will probably get an error code here ( both Andy and umich's
// dll will return errors sometimes. No error returned from NTDS,
// but errors are returned from Exchange server )
if ( *pattr == NULL )
{
DWORD hr = NO_ERROR;
int ldaperr = 0;
// Error occurred or end of attributes
ldaperr = LdapGetLastError();
dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
return(dwError);
}
#endif
return S_OK;
}
//
// NOTE: LdapGetValues return S_OK if attribute [attr] has no values
// (*[pvalues] =NULL, *[pcount]=0) but all else ok.
//
DWORD
LdapGetValues(
HLDAP hLdapHandle,
LDAPMessage *entry,
WCHAR *attr,
WCHAR ***pvalues,
int *pcount
)
{
DWORD dwError = 0;
int ldaperr = 0;
*pvalues = ldap_get_values( hLdapHandle, entry, attr );
if ( *pvalues == NULL ) {
*pcount=0;
//
// ldap_get_values succeeds if attribute has no values
// but all else ok. (confiremed with anoopa)
//
ldaperr = LdapGetLastError();
if (ldaperr) {
dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
}
//
// KrishnaG if *pvalues is NULL which means I don't get back a
// value - return an ERROR
//
return(ERROR_DS_NO_ATTRIBUTE_OR_VALUE);
}
*pcount = ldap_count_values( *pvalues );
return S_OK;
}
//
// NOTE: LdapGetValuesLen return S_OK if attribute [attr] has no values
// (*[pvalues] =NULL, *[pcount]=0) but all else ok.
//
DWORD
LdapGetValuesLen(
HLDAP hLdapHandle,
LDAPMessage *entry,
WCHAR *attr,
struct berval ***pvalues,
int *pcount
)
{
//
// NOTE: this can contain binary data as well as strings,
// strings are ascii, no conversion is done here
//
char *pszAttrA = NULL;
DWORD dwError = 0;
int ldaperr = 0;
*pvalues = ldap_get_values_len( hLdapHandle, entry, attr );
if ( *pvalues == NULL ){
*pcount=0;
//
// ldap_get_values succeeds if attribute has no values
// but all else ok. (confiremed with anoopa)
//
ldaperr = LdapGetLastError();
if (ldaperr) {
dwError = CheckAndSetExtendedError( hLdapHandle,ldaperr);
}
return(ERROR_DS_NO_ATTRIBUTE_OR_VALUE);
}
*pcount = ldap_count_values_len( *pvalues );
return S_OK;
}
void
LdapValueFree(
WCHAR **vals
)
{
ldap_value_free( vals );
}
void
LdapValueFreeLen(
struct berval **vals
)
{
ldap_value_free_len( vals );
}
void
LdapMemFree(
WCHAR *pszString
)
{
ldap_memfree( pszString );
}
void
LdapAttributeFree(
WCHAR *pszString
)
{
// String from ldap_first/next_attribute should not be freed,
// so do nothing here
}
DWORD
LdapGetDn(
HLDAP hLdapHandle,
LDAPMessage *entry,
WCHAR **pdn
)
{
int ldaperr = 0;
DWORD dwError = 0;
*pdn = ldap_get_dn( hLdapHandle, entry );
if ( *pdn == NULL )
{
// Error occurred
ldaperr = LdapGetLastError();
dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
return(dwError);
}
return(dwError);
}
DWORD
CheckAndSetExtendedError(
HLDAP hLdapHandle,
int ldaperr
)
{
DWORD dwErr = NO_ERROR;
switch (ldaperr) {
case LDAP_SUCCESS :
dwErr = NO_ERROR;
break;
case LDAP_OPERATIONS_ERROR :
dwErr = ERROR_DS_OPERATIONS_ERROR;
break;
case LDAP_PROTOCOL_ERROR :
dwErr = ERROR_DS_PROTOCOL_ERROR;
break;
case LDAP_TIMELIMIT_EXCEEDED :
dwErr = ERROR_DS_TIMELIMIT_EXCEEDED;
break;
case LDAP_SIZELIMIT_EXCEEDED :
dwErr = ERROR_DS_SIZELIMIT_EXCEEDED;
break;
case LDAP_COMPARE_FALSE :
dwErr = ERROR_DS_COMPARE_FALSE;
break;
case LDAP_COMPARE_TRUE :
dwErr = ERROR_DS_COMPARE_TRUE;
break;
case LDAP_AUTH_METHOD_NOT_SUPPORTED :
dwErr = ERROR_DS_AUTH_METHOD_NOT_SUPPORTED;
break;
case LDAP_STRONG_AUTH_REQUIRED :
dwErr = ERROR_DS_STRONG_AUTH_REQUIRED;
break;
case LDAP_PARTIAL_RESULTS :
//
// Make sure we handle
// partial results.
//
dwErr = ERROR_MORE_DATA;
break;
case LDAP_REFERRAL :
dwErr = ERROR_DS_REFERRAL;
break;
case LDAP_ADMIN_LIMIT_EXCEEDED :
dwErr = ERROR_DS_ADMIN_LIMIT_EXCEEDED;
break;
case LDAP_UNAVAILABLE_CRIT_EXTENSION :
dwErr = ERROR_DS_UNAVAILABLE_CRIT_EXTENSION;
break;
case LDAP_CONFIDENTIALITY_REQUIRED :
dwErr = ERROR_DS_CONFIDENTIALITY_REQUIRED;
break;
case LDAP_NO_SUCH_ATTRIBUTE :
dwErr = ERROR_DS_NO_ATTRIBUTE_OR_VALUE;
break;
case LDAP_UNDEFINED_TYPE :
dwErr = ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED;
break;
case LDAP_INAPPROPRIATE_MATCHING :
dwErr = ERROR_DS_INAPPROPRIATE_MATCHING;
break;
case LDAP_CONSTRAINT_VIOLATION :
dwErr = ERROR_DS_CONSTRAINT_VIOLATION;
break;
case LDAP_ATTRIBUTE_OR_VALUE_EXISTS :
dwErr = ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS;
break;
case LDAP_INVALID_SYNTAX :
dwErr = ERROR_DS_INVALID_ATTRIBUTE_SYNTAX;
break;
case LDAP_NO_SUCH_OBJECT :
dwErr = ERROR_DS_NO_SUCH_OBJECT;
break;
case LDAP_ALIAS_PROBLEM :
dwErr = ERROR_DS_ALIAS_PROBLEM;
break;
case LDAP_INVALID_DN_SYNTAX :
dwErr = ERROR_DS_INVALID_DN_SYNTAX;
break;
case LDAP_IS_LEAF :
dwErr = ERROR_DS_IS_LEAF;
break;
case LDAP_ALIAS_DEREF_PROBLEM :
dwErr = ERROR_DS_ALIAS_DEREF_PROBLEM;
break;
case LDAP_INAPPROPRIATE_AUTH :
dwErr = ERROR_DS_INAPPROPRIATE_AUTH;
break;
case LDAP_INVALID_CREDENTIALS :
dwErr = ERROR_LOGON_FAILURE;
break;
case LDAP_INSUFFICIENT_RIGHTS :
dwErr = ERROR_ACCESS_DENIED;
break;
case LDAP_BUSY :
dwErr = ERROR_DS_BUSY;
break;
case LDAP_UNAVAILABLE :
dwErr = ERROR_DS_UNAVAILABLE;
break;
case LDAP_UNWILLING_TO_PERFORM :
dwErr = ERROR_DS_UNWILLING_TO_PERFORM;
break;
case LDAP_LOOP_DETECT :
dwErr = ERROR_DS_LOOP_DETECT;
break;
case LDAP_NAMING_VIOLATION :
dwErr = ERROR_DS_NAMING_VIOLATION;
break;
case LDAP_OBJECT_CLASS_VIOLATION :
dwErr = ERROR_DS_OBJ_CLASS_VIOLATION;
break;
case LDAP_NOT_ALLOWED_ON_NONLEAF :
dwErr = ERROR_DS_CANT_ON_NON_LEAF;
break;
case LDAP_NOT_ALLOWED_ON_RDN :
dwErr = ERROR_DS_CANT_ON_RDN;
break;
case LDAP_ALREADY_EXISTS :
dwErr = ERROR_OBJECT_ALREADY_EXISTS;
break;
case LDAP_NO_OBJECT_CLASS_MODS :
dwErr = ERROR_DS_CANT_MOD_OBJ_CLASS;
break;
case LDAP_RESULTS_TOO_LARGE :
dwErr = ERROR_DS_OBJECT_RESULTS_TOO_LARGE;
break;
case LDAP_AFFECTS_MULTIPLE_DSAS :
dwErr = ERROR_DS_AFFECTS_MULTIPLE_DSAS;
break;
case LDAP_OTHER :
dwErr = ERROR_GEN_FAILURE;
break;
case LDAP_SERVER_DOWN :
dwErr = ERROR_DS_SERVER_DOWN;
break;
case LDAP_LOCAL_ERROR :
dwErr = ERROR_DS_LOCAL_ERROR;
break;
case LDAP_ENCODING_ERROR :
dwErr = ERROR_DS_ENCODING_ERROR;
break;
case LDAP_DECODING_ERROR :
dwErr = ERROR_DS_DECODING_ERROR;
break;
case LDAP_TIMEOUT :
dwErr = ERROR_TIMEOUT;
break;
case LDAP_AUTH_UNKNOWN :
dwErr = ERROR_DS_AUTH_UNKNOWN;
break;
case LDAP_FILTER_ERROR :
dwErr = ERROR_DS_FILTER_UNKNOWN;
break;
case LDAP_USER_CANCELLED :
dwErr = ERROR_CANCELLED;
break;
case LDAP_PARAM_ERROR :
dwErr = ERROR_DS_PARAM_ERROR;
break;
case LDAP_NO_MEMORY :
dwErr = ERROR_NOT_ENOUGH_MEMORY;
break;
case LDAP_CONNECT_ERROR :
dwErr = ERROR_CONNECTION_REFUSED;
break;
case LDAP_NOT_SUPPORTED :
dwErr = ERROR_DS_NOT_SUPPORTED;
break;
case LDAP_NO_RESULTS_RETURNED :
dwErr = ERROR_DS_NO_RESULTS_RETURNED;
break;
case LDAP_CONTROL_NOT_FOUND :
dwErr = ERROR_DS_CONTROL_NOT_FOUND;
break;
case LDAP_MORE_RESULTS_TO_RETURN :
dwErr = ERROR_MORE_DATA;
break;
case LDAP_CLIENT_LOOP :
dwErr = ERROR_DS_CLIENT_LOOP;
break;
case LDAP_REFERRAL_LIMIT_EXCEEDED :
dwErr = ERROR_DS_REFERRAL_LIMIT_EXCEEDED;
break;
default:
dwErr = ERROR_DS_BUSY;
}
return(dwErr);
}
DWORD
LdapAddS(
HLDAP hLdapHandle,
WCHAR *dn,
LDAPModW *attrs[]
)
{
DWORD dwError = 0;
int ldaperr = 0;
ldaperr = ldap_add_s( hLdapHandle, dn, attrs );
dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
return(dwError);
}
DWORD
LdapModifyS(
HLDAP hLdapHandle,
WCHAR *dn,
LDAPModW *mods[]
)
{
DWORD dwError = 0;
int ldaperr = 0;
ldaperr = ldap_modify_s( hLdapHandle, dn, mods);
dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
return(dwError);
}
DWORD
LdapDeleteS(
HLDAP hLdapHandle,
WCHAR *dn
)
{
DWORD dwError = 0;
int ldaperr = 0;
ldaperr = ldap_delete_s( hLdapHandle, dn );
dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
return(dwError);
}