Source code of Windows XP (NT5)
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.

122 lines
3.4 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // ldapdnary.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file defines the class LDAPDictionary.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/24/1998 Original version.
  16. // 04/20/1998 Added flags and InjectorProc to the attribute schema.
  17. // 05/01/1998 InjectorProc takes an ATTRIBUTEPOSITION array.
  18. // 03/23/1999 Store user's DN.
  19. //
  20. ///////////////////////////////////////////////////////////////////////////////
  21. #include <ias.h>
  22. #include <iastlutl.h>
  23. #include <attrcvt.h>
  24. #include <autohdl.h>
  25. #include <ldapdnary.h>
  26. #include <samutil.h>
  27. //////////
  28. // Smart wrapper around an array of LDAP berval's.
  29. //////////
  30. typedef auto_handle< berval**,
  31. ULONG (LDAPAPI*)(struct berval**),
  32. &ldap_value_free_len
  33. > LDAPValues;
  34. //////////
  35. // Create an attribute from a berval based on the schema info in 'def'.
  36. //////////
  37. inline PIASATTRIBUTE createAttribute(
  38. const LDAPAttribute& def,
  39. const berval& val
  40. )
  41. {
  42. // Convert the value.
  43. PIASATTRIBUTE attr = IASAttributeFromBerVal(val, def.iasType);
  44. // Set the rest of the fields.
  45. attr->dwId = def.iasID;
  46. attr->dwFlags = def.flags;
  47. return attr;
  48. }
  49. void LDAPDictionary::insert(
  50. IAttributesRaw* dst,
  51. LDAPMessage* src
  52. ) const
  53. {
  54. // Retrieve the connection for this message.
  55. LDAP* ld = ldap_conn_from_msg(NULL, src);
  56. // Used to hold converted attributes. This is defined outside the loop
  57. // to avoid unnecessary constructor/destructor calls.
  58. IASTL::IASAttributeVectorWithBuffer<8> attrs;
  59. // There's only one entry in the message.
  60. LDAPMessage* e = ldap_first_entry(ld, src);
  61. // Store the user's DN.
  62. PWCHAR dn = ldap_get_dnW(ld, e);
  63. IASStoreFQUserName(dst, DS_FQDN_1779_NAME, dn);
  64. ldap_memfree(dn);
  65. // Iterate through all the attributes in the entry.
  66. BerElement* ptr;
  67. for (wchar_t* a = ldap_first_attributeW(ld, e, &ptr);
  68. a != NULL;
  69. a = ldap_next_attributeW(ld, e, ptr))
  70. {
  71. // Lookup the schema information.
  72. const LDAPAttribute* def = find(a);
  73. // If it doesn't exist, we must not be interested in this attribute.
  74. if (def == NULL) { continue; }
  75. IASTracePrintf("Inserting attribute %S.", a);
  76. // Retrieve the values.
  77. LDAPValues vals(ldap_get_values_lenW(ld, e, a));
  78. // Make sure we have enough room. We don't want to throw an
  79. // exception in 'push_back' since it would cause a leak.
  80. attrs.reserve(ldap_count_values_len(vals));
  81. // Iterate through the values.
  82. for (size_t i = 0; vals.get()[i]; ++i)
  83. {
  84. // Add to the array of attributes without addref'ing.
  85. attrs.push_back(
  86. createAttribute(*def, *(vals.get()[i])),
  87. false
  88. );
  89. }
  90. // Inject into the request.
  91. def->injector(dst, attrs.begin(), attrs.end());
  92. // Clear out the vector so we can reuse it.
  93. attrs.clear();
  94. }
  95. }
  96. //////////
  97. // Comparison function used by bsearch to lookup definitions.
  98. //////////
  99. int __cdecl LDAPDictionary::compare(const void *elem1, const void *elem2)
  100. {
  101. return wcscmp(((LDAPAttribute*)elem1)->ldapName,
  102. ((LDAPAttribute*)elem2)->ldapName);
  103. }