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.

194 lines
5.0 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // SYNOPSIS
  6. //
  7. // Defines the class RasUser.
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #include <ias.h>
  11. #include <iastlutl.h>
  12. #define IASSAMAPI
  13. #include <iaslsa.h>
  14. #include <iasntds.h>
  15. #include <iasparms.h>
  16. #include <sdoias.h>
  17. #include <rasuser.h>
  18. #include <userschema.h>
  19. //////////
  20. // Attributes that should be retrieved for each user.
  21. //////////
  22. const PCWSTR USER_PARMS[] =
  23. {
  24. L"userParameters",
  25. NULL
  26. };
  27. HRESULT RasUser::initialize() throw ()
  28. {
  29. //////////
  30. // Let's get everything that could fail out of the way first.
  31. //////////
  32. PIASATTRIBUTE attrs[3];
  33. DWORD error = IASAttributeAlloc(3, attrs);
  34. if (error) { return HRESULT_FROM_WIN32(error); }
  35. //////////
  36. // Initialize the dial-in bit attributes.
  37. //////////
  38. attrs[0]->dwId = IAS_ATTRIBUTE_ALLOW_DIALIN;
  39. attrs[0]->Value.itType = IASTYPE_BOOLEAN;
  40. attrs[0]->Value.Boolean = TRUE;
  41. attrs[1]->dwFlags = 0;
  42. allowAccess.attach(attrs[0], false);
  43. attrs[1]->dwId = IAS_ATTRIBUTE_ALLOW_DIALIN;
  44. attrs[1]->Value.itType = IASTYPE_BOOLEAN;
  45. attrs[1]->Value.Boolean = FALSE;
  46. attrs[1]->dwFlags = 0;
  47. denyAccess.attach(attrs[1], false);
  48. attrs[2]->dwId = RADIUS_ATTRIBUTE_SERVICE_TYPE;
  49. attrs[2]->Value.itType = IASTYPE_ENUM;
  50. attrs[2]->Value.Enumerator = 4;
  51. attrs[2]->dwFlags = IAS_INCLUDE_IN_ACCEPT;
  52. callbackFramed.attach(attrs[2], false);
  53. return S_OK;
  54. }
  55. void RasUser::finalize() throw ()
  56. {
  57. allowAccess.release();
  58. denyAccess.release();
  59. callbackFramed.release();
  60. }
  61. IASREQUESTSTATUS RasUser::processUser(
  62. IASRequest& request,
  63. PCWSTR domainName,
  64. PCWSTR username
  65. )
  66. {
  67. IASTraceString("Using downlevel dial-in parameters.");
  68. DWORD error;
  69. RAS_USER_0 ru0;
  70. // Try using LDAP first since it's fastest.
  71. IASNtdsResult result;
  72. error = IASNtdsQueryUserAttributes(
  73. domainName,
  74. username,
  75. LDAP_SCOPE_SUBTREE,
  76. const_cast<PWCHAR*>(USER_PARMS),
  77. &result
  78. );
  79. if (error == NO_ERROR)
  80. {
  81. // Retrieve the connection for this message.
  82. LDAP* ld = ldap_conn_from_msg(NULL, result.msg);
  83. LDAPMessage* entry = ldap_first_entry(ld, result.msg);
  84. if (entry)
  85. {
  86. // Store the user's DN.
  87. PWCHAR dn = ldap_get_dnW(ld, entry);
  88. IASStoreFQUserName(request, DS_FQDN_1779_NAME, dn);
  89. ldap_memfree(dn);
  90. // There is at most one attribute.
  91. PWCHAR *str = ldap_get_valuesW(
  92. ld,
  93. entry,
  94. const_cast<PWCHAR>(USER_PARMS[0])
  95. );
  96. // It's okay if we didn't get anything, the API can handle NULL
  97. // UserParameters.
  98. error = IASParmsQueryRasUser0((str ? *str : NULL), &ru0);
  99. ldap_value_freeW(str);
  100. }
  101. else
  102. {
  103. error = ERROR_NO_SUCH_USER;
  104. }
  105. }
  106. else if (error == ERROR_DS_NOT_INSTALLED)
  107. {
  108. // No DS, so fall back to SAM APIs.
  109. error = IASGetRASUserInfo(username, domainName, &ru0);
  110. }
  111. if (error)
  112. {
  113. IASTraceFailure("Per-user attribute retrieval", error);
  114. HRESULT hr = IASMapWin32Error(error, IAS_SERVER_UNAVAILABLE);
  115. return IASProcessFailure(request, hr);
  116. }
  117. // Used for injecting single attributes.
  118. ATTRIBUTEPOSITION pos, *first, *last;
  119. first = &pos;
  120. last = first + 1;
  121. //////////
  122. // Insert the always present Allow-Dialin attribute.
  123. //////////
  124. if ((ru0.bfPrivilege & RASPRIV_DialinPrivilege) == 0)
  125. {
  126. first->pAttribute = denyAccess;
  127. }
  128. else
  129. {
  130. first->pAttribute = allowAccess;
  131. }
  132. IASTraceString("Inserting attribute msNPAllowDialin.");
  133. OverwriteAttribute(request, first, last);
  134. //////////
  135. // Insert the "Callback Framed" service type if callback is allowed.
  136. //////////
  137. if ((ru0.bfPrivilege & RASPRIV_CallbackType) != RASPRIV_NoCallback)
  138. {
  139. first->pAttribute = callbackFramed;
  140. IASTraceString("Inserting attribute msRADIUSServiceType.");
  141. OverwriteAttribute(request, first, last);
  142. }
  143. //////////
  144. // Insert the Callback-Number if present.
  145. //////////
  146. if (ru0.bfPrivilege & RASPRIV_AdminSetCallback)
  147. {
  148. IASAttribute callback(true);
  149. callback->dwId = RADIUS_ATTRIBUTE_CALLBACK_NUMBER;
  150. callback.setOctetString(ru0.wszPhoneNumber);
  151. callback.setFlag(IAS_INCLUDE_IN_ACCEPT);
  152. first->pAttribute = callback;
  153. IASTraceString("Inserting attribute msRADIUSCallbackNumber.");
  154. OverwriteAttribute(request, first, last);
  155. }
  156. IASTraceString("Successfully retrieved per-user attributes.");
  157. return IAS_REQUEST_STATUS_HANDLED;
  158. }