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.
 
 
 
 
 
 

138 lines
4.0 KiB

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corp. All rights reserved.
//
// FILE
//
// ldapdnary.cpp
//
// SYNOPSIS
//
// This file defines the class LDAPDictionary.
//
// MODIFICATION HISTORY
//
// 02/24/1998 Original version.
// 04/20/1998 Added flags and InjectorProc to the attribute schema.
// 05/01/1998 InjectorProc takes an ATTRIBUTEPOSITION array.
// 03/23/1999 Store user's DN.
//
///////////////////////////////////////////////////////////////////////////////
#include <ias.h>
#include <iastlutl.h>
#include <attrcvt.h>
#include <autohdl.h>
#include <ldapdnary.h>
#include <samutil.h>
#include "ldapcxn.h"
//////////
// Smart wrapper around an array of LDAP berval's.
//////////
typedef auto_handle< berval**,
ULONG (LDAPAPI*)(struct berval**),
&ldap_value_free_len
> LDAPValues;
//////////
// Create an attribute from a berval based on the schema info in 'def'.
//////////
inline PIASATTRIBUTE createAttribute(
const LDAPAttribute& def,
const berval& val
)
{
// Convert the value.
PIASATTRIBUTE attr = IASAttributeFromBerVal(val, def.iasType);
// Set the rest of the fields.
attr->dwId = def.iasID;
attr->dwFlags = def.flags;
return attr;
}
void LDAPDictionary::insert(
IAttributesRaw* dst,
LDAPMessage* src
) const
{
// Retrieve the connection for this message.
LDAP* ld = ldap_conn_from_msg(NULL, src);
// Used to hold converted attributes. This is defined outside the loop
// to avoid unnecessary constructor/destructor calls.
IASTL::IASAttributeVectorWithBuffer<8> attrs;
// There's only one entry in the message.
LDAPMessage* e = ldap_first_entry(ld, src);
// Store the user's DN.
PWCHAR dn = ldap_get_dnW(ld, e);
IASStoreFQUserName(dst, DS_FQDN_1779_NAME, dn);
ldap_memfree(dn);
// Iterate through all the attributes in the entry.
BerElement* ptr;
for (wchar_t* a = ldap_first_attributeW(ld, e, &ptr);
a != NULL;
a = ldap_next_attributeW(ld, e, ptr))
{
// Lookup the schema information.
const LDAPAttribute* def = find(a);
// If it doesn't exist, we must not be interested in this attribute.
if (def == NULL) { continue; }
IASTracePrintf("Inserting attribute %S.", a);
// Retrieve the values.
LDAPValues vals(ldap_get_values_lenW(ld, e, a));
if (static_cast<struct berval**>(vals) == 0)
{
ULONG error = LdapGetLastError();
ULONG winError = LdapMapErrorToWin32(error);
if (winError != NO_ERROR)
{
IASTraceLdapFailure("ldap_get_values_lenW", error, ld);
IASTL::issue_error(HRESULT_FROM_WIN32(winError));
}
else
{
// Most likely cause
IASTL::issue_error(E_OUTOFMEMORY);
}
}
// Make sure we have enough room. We don't want to throw an
// exception in 'push_back' since it would cause a leak.
attrs.reserve(ldap_count_values_len(vals));
// Iterate through the values.
for (size_t i = 0; vals.get()[i]; ++i)
{
// Add to the array of attributes without addref'ing.
attrs.push_back(
createAttribute(*def, *(vals.get()[i])),
false
);
}
// Inject into the request.
def->injector(dst, attrs.begin(), attrs.end());
// Clear out the vector so we can reuse it.
attrs.clear();
}
}
//////////
// Comparison function used by bsearch to lookup definitions.
//////////
int __cdecl LDAPDictionary::compare(const void *elem1, const void *elem2)
{
return wcscmp(((LDAPAttribute*)elem1)->ldapName,
((LDAPAttribute*)elem2)->ldapName);
}