/vmidentity/interop/idm/ad/sspi.c

https://github.com/vmware/lightwave · C · 288 lines · 195 code · 58 blank · 35 comment · 23 complexity · 65392a0a840d845b142e537910a960ee MD5 · raw file

  1. /*
  2. * Copyright © 2012-2015 VMware, Inc. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the “License”); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an “AS IS” BASIS, without
  10. * warranties or conditions of any kind, EITHER EXPRESS OR IMPLIED. See the
  11. * License for the specific language governing permissions and limitations
  12. * under the License.
  13. */
  14. /*
  15. * Module Name:
  16. *
  17. * sspi.c
  18. *
  19. * Abstract:
  20. *
  21. * Identity Manager - Active Directory Integration
  22. *
  23. * SSPI
  24. *
  25. * Authors: Krishna Ganugapati (krishnag@vmware.com)
  26. * Sriram Nambakam (snambakam@vmware.com)
  27. * Adam Bernstein (abernstein@vmware.com)
  28. *
  29. */
  30. #include "stdafx.h"
  31. DWORD
  32. IDMCreateAuthContext(
  33. LPWSTR pszPackageName,
  34. PIDM_AUTH_CONTEXT * ppAuthContext
  35. )
  36. {
  37. PIDM_AUTH_CONTEXT pAuthContext = NULL;
  38. DWORD dwError = 0;
  39. TimeStamp Lifetime = {0};
  40. PSecPkgInfo pPackageInfo = NULL;
  41. SECURITY_STATUS secError = SEC_E_OK;
  42. if (!pszPackageName || !ppAuthContext)
  43. {
  44. dwError = ERROR_INVALID_PARAMETER;
  45. BAIL_ON_ERROR(dwError);
  46. }
  47. secError = QuerySecurityPackageInfo (pszPackageName, &pPackageInfo);
  48. BAIL_ON_SECURITY_ERROR(secError, dwError);
  49. dwError = IDMAllocateMemory(
  50. sizeof(IDM_AUTH_CONTEXT),
  51. (PVOID *)&pAuthContext);
  52. BAIL_ON_ERROR(dwError);
  53. pAuthContext->fNewConversation = TRUE;
  54. pAuthContext->dwState = AUTH_START_STATE;
  55. pAuthContext->dwMaxTokenSize = pPackageInfo->cbMaxToken;
  56. secError = AcquireCredentialsHandle (
  57. NULL,
  58. pszPackageName,
  59. SECPKG_CRED_INBOUND,
  60. NULL,
  61. NULL,
  62. NULL,
  63. NULL,
  64. &pAuthContext->hCredsHandle,
  65. &Lifetime);
  66. BAIL_ON_SECURITY_ERROR(secError, dwError);
  67. pAuthContext->phCredsHandle = &pAuthContext->hCredsHandle;
  68. *ppAuthContext = pAuthContext;
  69. cleanup:
  70. if (pPackageInfo)
  71. {
  72. FreeContextBuffer(pPackageInfo);
  73. }
  74. return dwError;
  75. error:
  76. if (pAuthContext)
  77. {
  78. IDMFreeAuthContext(pAuthContext);
  79. }
  80. goto cleanup;
  81. }
  82. DWORD
  83. IDMAuthenticate2(
  84. PIDM_AUTH_CONTEXT pAuthContext,
  85. LPBYTE pInputBuffer,
  86. DWORD dwInputBufferSize,
  87. LPBYTE * ppOutputBuffer,
  88. DWORD * pdwOutputBufferSize,
  89. BOOL * pfDone
  90. )
  91. {
  92. DWORD dwError = 0;
  93. TimeStamp Lifetime = {0};
  94. SecBufferDesc OutBuffDesc = {0};
  95. SecBuffer OutSecBuff = {0};
  96. SecBufferDesc InBuffDesc = {0};
  97. SecBuffer InSecBuff = {0};
  98. ULONG Attribs = 0;
  99. DWORD dwOutputBufferSize = 0;
  100. LPBYTE pOutputBuffer = NULL;
  101. SECURITY_STATUS secError = SEC_E_OK;
  102. if (!pAuthContext ||
  103. !pInputBuffer ||
  104. !ppOutputBuffer ||
  105. !pdwOutputBufferSize ||
  106. !pfDone)
  107. {
  108. dwError = ERROR_INVALID_PARAMETER;
  109. BAIL_ON_ERROR(dwError);
  110. }
  111. if (pAuthContext->dwState == AUTH_START_COMPLETE)
  112. {
  113. dwError = ERROR_INVALID_STATE;
  114. BAIL_ON_ERROR(dwError);
  115. }
  116. //----------------------------------------------------------------
  117. // Prepare output buffers.
  118. dwError = IDMAllocateMemory(
  119. pAuthContext->dwMaxTokenSize,
  120. &pOutputBuffer);
  121. BAIL_ON_ERROR(dwError);
  122. dwOutputBufferSize = pAuthContext->dwMaxTokenSize;
  123. OutBuffDesc.ulVersion = 0;
  124. OutBuffDesc.cBuffers = 1;
  125. OutBuffDesc.pBuffers = &OutSecBuff;
  126. OutSecBuff.cbBuffer = dwOutputBufferSize;
  127. OutSecBuff.BufferType = SECBUFFER_TOKEN;
  128. OutSecBuff.pvBuffer = pOutputBuffer;
  129. //----------------------------------------------------------------
  130. // Prepare input buffers.
  131. InBuffDesc.ulVersion = 0;
  132. InBuffDesc.cBuffers = 1;
  133. InBuffDesc.pBuffers = &InSecBuff;
  134. InSecBuff.cbBuffer = dwInputBufferSize;
  135. InSecBuff.BufferType = SECBUFFER_TOKEN;
  136. InSecBuff.pvBuffer = pInputBuffer;
  137. secError = AcceptSecurityContext (
  138. pAuthContext->phCredsHandle,
  139. pAuthContext->fNewConversation ? NULL : &pAuthContext->hCtxtHandle,
  140. &InBuffDesc,
  141. Attribs,
  142. SECURITY_NATIVE_DREP,
  143. &pAuthContext->hCtxtHandle,
  144. &OutBuffDesc,
  145. &Attribs,
  146. &Lifetime
  147. );
  148. BAIL_ON_SECURITY_ERROR(secError, dwError);
  149. pAuthContext->phCtxtHandle = &pAuthContext->hCtxtHandle;
  150. if (pAuthContext->fNewConversation)
  151. {
  152. pAuthContext->fNewConversation = FALSE;
  153. }
  154. //----------------------------------------------------------------
  155. // Complete token if applicable.
  156. if ((SEC_I_COMPLETE_NEEDED == dwError)
  157. || (SEC_I_COMPLETE_AND_CONTINUE == dwError))
  158. {
  159. dwError = CompleteAuthToken (&pAuthContext->hCtxtHandle, &OutBuffDesc);
  160. BAIL_ON_ERROR(dwError);
  161. }
  162. dwOutputBufferSize = OutSecBuff.cbBuffer;
  163. *pfDone = !((SEC_I_CONTINUE_NEEDED == secError)
  164. || (SEC_I_COMPLETE_AND_CONTINUE == secError));
  165. pAuthContext->dwState = *pfDone ? AUTH_START_COMPLETE : AUTH_START_CONTINUE;
  166. *pdwOutputBufferSize = dwOutputBufferSize;
  167. *ppOutputBuffer = pOutputBuffer;
  168. cleanup:
  169. return dwError;
  170. error:
  171. IDM_SAFE_FREE_MEMORY(pOutputBuffer);
  172. goto cleanup;
  173. }
  174. DWORD
  175. IDMGetUserInformationFromAuthContext(
  176. PIDM_AUTH_CONTEXT pAuthContext,
  177. PIDM_USER_INFO * ppIdmUserInformation
  178. )
  179. {
  180. DWORD dwError = 0;
  181. HANDLE hClientToken = NULL;
  182. CtxtHandle hSecCtxt = {0};
  183. PIDM_USER_INFO pUserInfo = NULL;
  184. SECURITY_STATUS secError = SEC_E_OK;
  185. if (!pAuthContext || !ppIdmUserInformation)
  186. {
  187. dwError = ERROR_INVALID_PARAMETER;
  188. BAIL_ON_ERROR(dwError);
  189. }
  190. if (pAuthContext->dwState != AUTH_START_COMPLETE)
  191. {
  192. dwError = ERROR_INVALID_STATE;
  193. BAIL_ON_ERROR(dwError);
  194. }
  195. dwError = IDMInitializeSidCache();
  196. BAIL_ON_ERROR(dwError);
  197. hSecCtxt = pAuthContext->hCtxtHandle;
  198. secError = QuerySecurityContextToken(&hSecCtxt, &hClientToken);
  199. BAIL_ON_SECURITY_ERROR(secError, dwError);
  200. dwError = IDMGetUserInfo(hClientToken, &pUserInfo);
  201. BAIL_ON_ERROR(dwError);
  202. *ppIdmUserInformation = pUserInfo;
  203. error:
  204. if (hClientToken)
  205. {
  206. CloseHandle(hClientToken);
  207. }
  208. return dwError;
  209. }
  210. VOID
  211. IDMFreeAuthContext(
  212. PIDM_AUTH_CONTEXT pAuthContext
  213. )
  214. {
  215. if (pAuthContext)
  216. {
  217. if (pAuthContext->phCredsHandle)
  218. {
  219. FreeCredentialsHandle(&pAuthContext->hCredsHandle);
  220. pAuthContext->phCredsHandle = NULL;
  221. }
  222. if (pAuthContext->phCtxtHandle)
  223. {
  224. DeleteSecurityContext(&pAuthContext->hCtxtHandle);
  225. pAuthContext->phCtxtHandle = NULL;
  226. }
  227. IDM_SAFE_FREE_MEMORY(pAuthContext);
  228. pAuthContext = NULL;
  229. }
  230. }