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

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 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. #include "ldapcxn.h"
  28. //////////
  29. // Smart wrapper around an array of LDAP berval's.
  30. //////////
  31. typedef auto_handle< berval**,
  32. ULONG (LDAPAPI*)(struct berval**),
  33. &ldap_value_free_len
  34. > LDAPValues;
  35. //////////
  36. // Create an attribute from a berval based on the schema info in 'def'.
  37. //////////
  38. inline PIASATTRIBUTE createAttribute(
  39. const LDAPAttribute& def,
  40. const berval& val
  41. )
  42. {
  43. // Convert the value.
  44. PIASATTRIBUTE attr = IASAttributeFromBerVal(val, def.iasType);
  45. // Set the rest of the fields.
  46. attr->dwId = def.iasID;
  47. attr->dwFlags = def.flags;
  48. return attr;
  49. }
  50. void LDAPDictionary::insert(
  51. IAttributesRaw* dst,
  52. LDAPMessage* src
  53. ) const
  54. {
  55. // Retrieve the connection for this message.
  56. LDAP* ld = ldap_conn_from_msg(NULL, src);
  57. // Used to hold converted attributes. This is defined outside the loop
  58. // to avoid unnecessary constructor/destructor calls.
  59. IASTL::IASAttributeVectorWithBuffer<8> attrs;
  60. // There's only one entry in the message.
  61. LDAPMessage* e = ldap_first_entry(ld, src);
  62. // Store the user's DN.
  63. PWCHAR dn = ldap_get_dnW(ld, e);
  64. IASStoreFQUserName(dst, DS_FQDN_1779_NAME, dn);
  65. ldap_memfree(dn);
  66. // Iterate through all the attributes in the entry.
  67. BerElement* ptr;
  68. for (wchar_t* a = ldap_first_attributeW(ld, e, &ptr);
  69. a != NULL;
  70. a = ldap_next_attributeW(ld, e, ptr))
  71. {
  72. // Lookup the schema information.
  73. const LDAPAttribute* def = find(a);
  74. // If it doesn't exist, we must not be interested in this attribute.
  75. if (def == NULL) { continue; }
  76. IASTracePrintf("Inserting attribute %S.", a);
  77. // Retrieve the values.
  78. LDAPValues vals(ldap_get_values_lenW(ld, e, a));
  79. if (static_cast<struct berval**>(vals) == 0)
  80. {
  81. ULONG error = LdapGetLastError();
  82. ULONG winError = LdapMapErrorToWin32(error);
  83. if (winError != NO_ERROR)
  84. {
  85. IASTraceLdapFailure("ldap_get_values_lenW", error, ld);
  86. IASTL::issue_error(HRESULT_FROM_WIN32(winError));
  87. }
  88. else
  89. {
  90. // Most likely cause
  91. IASTL::issue_error(E_OUTOFMEMORY);
  92. }
  93. }
  94. // Make sure we have enough room. We don't want to throw an
  95. // exception in 'push_back' since it would cause a leak.
  96. attrs.reserve(ldap_count_values_len(vals));
  97. // Iterate through the values.
  98. for (size_t i = 0; vals.get()[i]; ++i)
  99. {
  100. // Add to the array of attributes without addref'ing.
  101. attrs.push_back(
  102. createAttribute(*def, *(vals.get()[i])),
  103. false
  104. );
  105. }
  106. // Inject into the request.
  107. def->injector(dst, attrs.begin(), attrs.end());
  108. // Clear out the vector so we can reuse it.
  109. attrs.clear();
  110. }
  111. }
  112. //////////
  113. // Comparison function used by bsearch to lookup definitions.
  114. //////////
  115. int __cdecl LDAPDictionary::compare(const void *elem1, const void *elem2)
  116. {
  117. return wcscmp(((LDAPAttribute*)elem1)->ldapName,
  118. ((LDAPAttribute*)elem2)->ldapName);
  119. }