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.

166 lines
4.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // netuser.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file declares the class NetUser.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/26/1998 Original version.
  16. // 03/20/1998 Add support for RAS attributes.
  17. // 03/31/1998 The denyAccess attribute wasn't being initialized properly.
  18. // 04/02/1998 Include Service-Type attribute for callback.
  19. // 04/24/1998 Use RAS API for local users when running under
  20. // Workstation or NT4.
  21. // 04/30/1998 Convert to IASSyncHandler.
  22. // Reject unknown users.
  23. // 05/01/1998 InjectProc takes an ATTRIBUTEPOSITION array.
  24. // 05/19/1998 Converted to NtSamHandler.
  25. // 06/19/1998 Use injector functions for adding per-user attributes.
  26. // 07/20/1998 Multi-valued attributes were using duplicate loop variable.
  27. // 10/19/1998 Use IASParmsXXX API instead of Datastore2.
  28. //
  29. ///////////////////////////////////////////////////////////////////////////////
  30. #include <ias.h>
  31. #include <iasutil.h>
  32. #include <attrcvt.h>
  33. #include <autohdl.h>
  34. #include <varvec.h>
  35. #define IASSAMAPI
  36. #include <iaslsa.h>
  37. #include <iasparms.h>
  38. #include <userschema.h>
  39. #include <netuser.h>
  40. //////////
  41. // Create an attribute from a VARIANT based on the schema info in 'def'.
  42. //////////
  43. PIASATTRIBUTE createAttribute(
  44. const LDAPAttribute& def,
  45. VARIANT& value
  46. )
  47. {
  48. // Convert the value.
  49. PIASATTRIBUTE attr = IASAttributeFromVariant(&value, def.iasType);
  50. // Set the attribute ID ...
  51. attr->dwId = def.iasID;
  52. // Set the flags.
  53. attr->dwFlags = def.flags;
  54. return attr;
  55. }
  56. IASREQUESTSTATUS NetUser::processUser(
  57. IASRequest& request,
  58. PCWSTR domainName,
  59. PCWSTR username
  60. )
  61. {
  62. //////////
  63. // Only handle non-domain users.
  64. //////////
  65. if (IASGetRole() == IAS_ROLE_DC || !IASIsDomainLocal(domainName))
  66. {
  67. return IAS_REQUEST_STATUS_INVALID;
  68. }
  69. IASTraceString("Using NT5 local user parameters.");
  70. //////////
  71. // Retrieve the UserParameters for this user.
  72. //////////
  73. auto_handle< PWSTR, HLOCAL (WINAPI*)(HLOCAL), &LocalFree > userParms;
  74. DWORD error = IASGetUserParameters(
  75. username,
  76. domainName,
  77. &userParms
  78. );
  79. if (error != NO_ERROR)
  80. {
  81. IASTraceFailure("IASGetUserParameters", error);
  82. return IASProcessFailure(
  83. request,
  84. IASMapWin32Error(
  85. error,
  86. IAS_SERVER_UNAVAILABLE
  87. )
  88. );
  89. }
  90. // Used for converting attributes. These are defined outside the loop to
  91. // avoid unnecessary constructor/destructor calls.
  92. IASAttributeVectorWithBuffer<8> attrs;
  93. _variant_t value;
  94. //////////
  95. // Iterate through the per-user attributes.
  96. //////////
  97. for (size_t i = 0; i < USER_SCHEMA_ELEMENTS; ++i)
  98. {
  99. HRESULT hr = IASParmsQueryUserProperty(
  100. userParms,
  101. USER_SCHEMA[i].ldapName,
  102. &value
  103. );
  104. if (FAILED(hr)) { _com_issue_error(hr); }
  105. // If the VARIANT is empty, this property was never set.
  106. if (V_VT(&value) == VT_EMPTY) { continue; }
  107. IASTracePrintf("Inserting attribute %S.", USER_SCHEMA[i].ldapName);
  108. // The variant is either a single value or an array of VARIANT's.
  109. if (V_VT(&value) != (VT_ARRAY | VT_VARIANT))
  110. {
  111. // Insert the attribute without addref'ing.
  112. attrs.push_back(
  113. createAttribute(USER_SCHEMA[i], value),
  114. false
  115. );
  116. }
  117. else
  118. {
  119. CVariantVector<VARIANT> array(&value);
  120. // Make sure we have enough room. We don't want to throw an
  121. // exception in 'push_back' since it would cause a leak.
  122. attrs.reserve(array.size());
  123. for (size_t j = 0; j < array.size(); ++j)
  124. {
  125. // Add to the array of attributes without addref'ing.
  126. attrs.push_back(
  127. createAttribute(USER_SCHEMA[i], array[j]),
  128. false
  129. );
  130. }
  131. }
  132. // Inject into the request.
  133. USER_SCHEMA[i].injector(request, attrs.begin(), attrs.end());
  134. // Clear the attributes and the variant for reuse.
  135. attrs.clear();
  136. value.Clear();
  137. }
  138. IASTraceString("Successfully retrieved per-user attributes.");
  139. return IAS_REQUEST_STATUS_HANDLED;
  140. }