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
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);
|
|
}
|