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.

562 lines
14 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: credapi.c
  8. //
  9. // Contents: Credential related APIs to the SPMgr
  10. // - LsaEstablishCreds
  11. // - LsaLogonUser
  12. // - LsaAcquireCredHandle
  13. // - LsaFreeCredHandle
  14. //
  15. //
  16. // History: 20 May 92 RichardW Commented existing code
  17. //
  18. //------------------------------------------------------------------------
  19. #include <lsapch.hxx>
  20. extern "C"
  21. {
  22. #include "adtp.h"
  23. #include "msaudite.h" // LsaAuditLogon
  24. #include "suppcred.h"
  25. }
  26. //+-------------------------------------------------------------------------
  27. //
  28. // Function: WLsaEstablishCreds
  29. //
  30. // Synopsis: Establishes credentials for a process.
  31. //
  32. // Effects:
  33. //
  34. // Arguments:
  35. //
  36. // Requires:
  37. //
  38. // Returns:
  39. //
  40. // Notes:
  41. //
  42. //--------------------------------------------------------------------------
  43. NTSTATUS
  44. WLsaEstablishCreds( PSECURITY_STRING pName,
  45. PSECURITY_STRING pSecPackage,
  46. DWORD cbKey,
  47. PBYTE pbKey,
  48. PCredHandle pcredHandle,
  49. PTimeStamp ptsExpiry)
  50. {
  51. return(SEC_E_UNSUPPORTED_FUNCTION);
  52. }
  53. //+-------------------------------------------------------------------------
  54. //
  55. // Function: WLsaAcquireCredHandle
  56. //
  57. // Synopsis:
  58. //
  59. // Effects:
  60. //
  61. // Arguments:
  62. //
  63. // Requires:
  64. //
  65. // Returns:
  66. //
  67. // Notes:
  68. //
  69. //--------------------------------------------------------------------------
  70. NTSTATUS
  71. WLsaAcquireCredHandle( PSECURITY_STRING pPrincipal,
  72. PSECURITY_STRING pSecPackage,
  73. DWORD fCredentialUse,
  74. PLUID pLogonID,
  75. PVOID pvAuthData,
  76. PVOID pvGetKeyFn,
  77. PVOID pvGetKeyArgument,
  78. PCredHandle phCredential,
  79. PTimeStamp ptsExpiry)
  80. {
  81. PLSAP_SECURITY_PACKAGE pspPackage;
  82. NTSTATUS scRet;
  83. LUID CallerLogonID;
  84. PSession pSession = GetCurrentSession();
  85. SECPKG_CLIENT_INFO ClientInfo;
  86. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  87. //
  88. // Check if the caller is restricted
  89. //
  90. scRet = LsapGetClientInfo(&ClientInfo);
  91. if (!NT_SUCCESS(scRet))
  92. {
  93. DebugLog((DEB_ERROR,"Failed to get client info: 0x%x\n",scRet));
  94. return(scRet);
  95. }
  96. //
  97. // If the caller is restricted, fail the call for now. This should change
  98. // if packages are able to support restrictions. In that case, the call
  99. // should check the package capabilities for handling restrictions and
  100. // if it supports restrictions, allow the call to continue.
  101. //
  102. if (ClientInfo.Restricted)
  103. {
  104. DebugLog((DEB_WARN,"Trying to acquire credentials with a restrictred token\n"));
  105. scRet = SEC_E_NO_CREDENTIALS;
  106. return(scRet);
  107. }
  108. #if DBG
  109. if (pPrincipal->Length)
  110. {
  111. DebugLog((DEB_TRACE_WAPI, "[%x] AcquireCredentialHandle(%ws, %ws)\n",
  112. pSession->dwProcessID, pPrincipal->Buffer, pSecPackage->Buffer));
  113. }
  114. else
  115. {
  116. DebugLog((DEB_TRACE_WAPI, "[%x] AcquireCredHandle(%x:%x, %ws)\n",
  117. pSession->dwProcessID, pLogonID->HighPart, pLogonID->LowPart,
  118. pSecPackage->Buffer));
  119. }
  120. #endif // DBG
  121. phCredential->dwUpper = 0;
  122. phCredential->dwLower = 0xFFFFFFFF;
  123. ptsExpiry->LowPart = 0;
  124. ptsExpiry->HighPart = 0;
  125. pspPackage = SpmpLookupPackageAndRequest(pSecPackage,
  126. SP_ORDINAL_ACQUIRECREDHANDLE);
  127. if (!pspPackage)
  128. {
  129. return(SEC_E_SECPKG_NOT_FOUND);
  130. }
  131. SetCurrentPackageId(pspPackage->dwPackageID);
  132. CallerLogonID = *pLogonID;
  133. StartCallToPackage( pspPackage );
  134. __try
  135. {
  136. scRet = pspPackage->FunctionTable.AcquireCredentialsHandle(pPrincipal,
  137. fCredentialUse,
  138. &CallerLogonID,
  139. pvAuthData,
  140. pvGetKeyFn,
  141. pvGetKeyArgument,
  142. &phCredential->dwUpper,
  143. ptsExpiry);
  144. }
  145. __except (SP_EXCEPTION)
  146. {
  147. scRet = GetExceptionCode();
  148. scRet = SPException(scRet, pspPackage->dwPackageID);
  149. }
  150. EndCallToPackage( pspPackage );
  151. if (FAILED(scRet))
  152. {
  153. DebugLog((DEB_WARN, "Failed to acquire cred handle for %ws with %ws\n",
  154. pPrincipal->Buffer, pSecPackage->Buffer));
  155. return(scRet);
  156. }
  157. phCredential->dwLower = pspPackage->dwPackageID;
  158. if(!AddCredHandle(pSession, phCredential, 0))
  159. {
  160. DebugLog(( DEB_ERROR, "Failed adding credential handle %p:%p to session %p\n",
  161. phCredential->dwUpper, phCredential->dwLower,
  162. pSession ));
  163. pspPackage = SpmpLookupPackageAndRequest(pSecPackage,
  164. SP_ORDINAL_FREECREDHANDLE);
  165. if( pspPackage )
  166. {
  167. ULONG OldCallCount = CallInfo->CallInfo.CallCount;
  168. CallInfo->CallInfo.CallCount = 1 ;
  169. //
  170. // remove the handle from the underlying package.
  171. //
  172. StartCallToPackage( pspPackage );
  173. __try
  174. {
  175. pspPackage->FunctionTable.FreeCredentialsHandle(
  176. phCredential->dwUpper
  177. );
  178. }
  179. __except (SP_EXCEPTION)
  180. {
  181. NOTHING;
  182. }
  183. EndCallToPackage( pspPackage );
  184. CallInfo->CallInfo.CallCount = OldCallCount;
  185. }
  186. phCredential->dwLower = 0;
  187. phCredential->dwUpper = 0;
  188. return SEC_E_INSUFFICIENT_MEMORY;
  189. }
  190. LsapLogCallInfo( CallInfo, pSession, *phCredential );
  191. return(scRet);
  192. }
  193. NTSTATUS
  194. WLsaAddCredentials(
  195. PCredHandle phCredential,
  196. PSECURITY_STRING pPrincipal,
  197. PSECURITY_STRING pSecPackage,
  198. DWORD fCredentialUse,
  199. PVOID pvAuthData,
  200. PVOID pvGetKeyFn,
  201. PVOID pvGetKeyArgument,
  202. PTimeStamp ptsExpiry)
  203. {
  204. PLSAP_SECURITY_PACKAGE pspPackage;
  205. NTSTATUS scRet;
  206. LUID CallerLogonID;
  207. PSession pSession = GetCurrentSession();
  208. SECPKG_CLIENT_INFO ClientInfo;
  209. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  210. PVOID CredKey ;
  211. //
  212. // Check if the caller is restricted
  213. //
  214. scRet = LsapGetClientInfo(&ClientInfo);
  215. if (!NT_SUCCESS(scRet))
  216. {
  217. DebugLog((DEB_ERROR,"Failed to get client info: 0x%x\n",scRet));
  218. return(scRet);
  219. }
  220. //
  221. // If the caller is restricted, fail the call for now. This should change
  222. // if packages are able to support restrictions. In that case, the call
  223. // should check the package capabilities for handling restrictions and
  224. // if it supports restrictions, allow the call to continue.
  225. //
  226. if (ClientInfo.Restricted)
  227. {
  228. DebugLog((DEB_WARN,"Trying to acquire credentials with a restrictred token\n"));
  229. scRet = SEC_E_NO_CREDENTIALS;
  230. return(scRet);
  231. }
  232. #if DBG
  233. if (pPrincipal->Length)
  234. {
  235. DebugLog((DEB_TRACE_WAPI, "[%x] AddCredentials(%ws, %ws)\n",
  236. pSession->dwProcessID, pPrincipal->Buffer, pSecPackage->Buffer));
  237. }
  238. else
  239. {
  240. DebugLog((DEB_TRACE_WAPI, "[%x] AddCredentials(%ws)\n",
  241. pSession->dwProcessID,
  242. pSecPackage->Buffer));
  243. }
  244. #endif // DBG
  245. ptsExpiry->LowPart = 0;
  246. ptsExpiry->HighPart = 0;
  247. LsapLogCallInfo( CallInfo, pSession, *phCredential );
  248. scRet = ValidateCredHandle(
  249. pSession,
  250. phCredential,
  251. &CredKey );
  252. if ( NT_SUCCESS( scRet ) )
  253. {
  254. pspPackage = SpmpValidRequest( phCredential->dwLower,
  255. SP_ORDINAL_ADDCREDENTIALS );
  256. }
  257. else
  258. {
  259. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  260. return( SEC_E_INVALID_HANDLE );
  261. }
  262. if (!pspPackage)
  263. {
  264. return(SEC_E_SECPKG_NOT_FOUND);
  265. }
  266. SetCurrentPackageId(pspPackage->dwPackageID);
  267. StartCallToPackage( pspPackage );
  268. __try
  269. {
  270. scRet = pspPackage->FunctionTable.AddCredentials(
  271. phCredential->dwUpper,
  272. pPrincipal,
  273. pSecPackage,
  274. fCredentialUse,
  275. pvAuthData,
  276. pvGetKeyFn,
  277. pvGetKeyArgument,
  278. ptsExpiry);
  279. }
  280. __except (SP_EXCEPTION)
  281. {
  282. scRet = GetExceptionCode();
  283. scRet = SPException(scRet, pspPackage->dwPackageID);
  284. }
  285. EndCallToPackage( pspPackage );
  286. if (FAILED(scRet))
  287. {
  288. DebugLog((DEB_WARN, "Failed to add credentials for %ws with %ws\n",
  289. pPrincipal->Buffer, pSecPackage->Buffer));
  290. return(scRet);
  291. }
  292. LsapLogCallInfo( CallInfo, pSession, *phCredential );
  293. return(scRet);
  294. }
  295. //+-------------------------------------------------------------------------
  296. //
  297. // Function: WLsaFreeCredHandle
  298. //
  299. // Synopsis: Worker function to free a cred handle,
  300. //
  301. // Effects: calls into a package to free the handle
  302. //
  303. // Arguments:
  304. //
  305. // Requires:
  306. //
  307. // Returns:
  308. //
  309. // Notes:
  310. //
  311. //--------------------------------------------------------------------------
  312. NTSTATUS
  313. WLsaFreeCredHandle( PCredHandle phCreds)
  314. {
  315. NTSTATUS scRet;
  316. PSession pSession = GetCurrentSession();
  317. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  318. PLSAP_SECURITY_PACKAGE pPackage;
  319. IsOkayToExec(0);
  320. DebugLog((DEB_TRACE_WAPI, "[%x] WLsaFreeCredHandle(%p : %p)\n",
  321. pSession->dwProcessID, phCreds->dwUpper, phCreds->dwLower));
  322. scRet = ValidateAndDerefCredHandle( pSession, phCreds );
  323. if ( !NT_SUCCESS( scRet ) )
  324. {
  325. if ( ( CallInfo->Flags & CALL_FLAG_NO_HANDLE_CHK ) == 0 )
  326. {
  327. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  328. }
  329. }
  330. LsapLogCallInfo( CallInfo, pSession, *phCreds );
  331. if (SUCCEEDED(scRet))
  332. {
  333. phCreds->dwUpper = phCreds->dwLower = 0xFFFFFFFF;
  334. }
  335. return(scRet);
  336. }
  337. //+-------------------------------------------------------------------------
  338. //
  339. // Function: SpmpFreePrimaryCredentials
  340. //
  341. // Synopsis: Frees primary credentials allocated with LsapAllocateLsaHeap
  342. //
  343. // Effects:
  344. //
  345. // Arguments:
  346. //
  347. // Requires:
  348. //
  349. // Returns:
  350. //
  351. // Notes:
  352. //
  353. //
  354. //--------------------------------------------------------------------------
  355. VOID
  356. SpmpFreePrimaryCredentials(
  357. IN PSECPKG_PRIMARY_CRED PrimaryCred
  358. )
  359. {
  360. if (PrimaryCred->DownlevelName.Buffer != NULL)
  361. {
  362. LsapFreeLsaHeap(PrimaryCred->DownlevelName.Buffer);
  363. PrimaryCred->DownlevelName.Buffer = NULL;
  364. }
  365. if (PrimaryCred->DomainName.Buffer != NULL)
  366. {
  367. LsapFreeLsaHeap(PrimaryCred->DomainName.Buffer);
  368. PrimaryCred->DomainName.Buffer = NULL;
  369. }
  370. if (PrimaryCred->DnsDomainName.Buffer != NULL)
  371. {
  372. LsapFreeLsaHeap(PrimaryCred->DnsDomainName.Buffer);
  373. PrimaryCred->DnsDomainName.Buffer = NULL;
  374. }
  375. if (PrimaryCred->Upn.Buffer != NULL)
  376. {
  377. LsapFreeLsaHeap(PrimaryCred->Upn.Buffer);
  378. PrimaryCred->Upn.Buffer = NULL;
  379. }
  380. if (PrimaryCred->Password.Buffer != NULL)
  381. {
  382. LsapFreeLsaHeap(PrimaryCred->Password.Buffer);
  383. PrimaryCred->Password.Buffer = NULL;
  384. }
  385. if (PrimaryCred->LogonServer.Buffer != NULL)
  386. {
  387. LsapFreeLsaHeap(PrimaryCred->LogonServer.Buffer);
  388. PrimaryCred->LogonServer.Buffer = NULL;
  389. }
  390. if (PrimaryCred->UserSid != NULL)
  391. {
  392. LsapFreeLsaHeap(PrimaryCred->UserSid);
  393. PrimaryCred->UserSid = NULL;
  394. }
  395. }
  396. //+-------------------------------------------------------------------------
  397. //
  398. // Function: WLsaQueryCredAttributes
  399. //
  400. // Synopsis: SPMgr worker to query credential attributes
  401. //
  402. // Effects:
  403. //
  404. // Arguments:
  405. //
  406. // Requires:
  407. //
  408. // Returns:
  409. //
  410. // Notes:
  411. //
  412. //
  413. //--------------------------------------------------------------------------
  414. NTSTATUS
  415. WLsaQueryCredAttributes(
  416. PCredHandle phCredentials,
  417. ULONG ulAttribute,
  418. PVOID pBuffer
  419. )
  420. {
  421. NTSTATUS scRet;
  422. PSession pSession = GetCurrentSession();
  423. PLSA_CALL_INFO CallInfo = LsapGetCurrentCall();
  424. PLSAP_SECURITY_PACKAGE pPackage;
  425. PVOID CredKey = NULL ;
  426. DebugLog((DEB_TRACE_WAPI, "[%x] WLsaQueryCredAttributes(%p : %p)\n",
  427. pSession->dwProcessID, phCredentials->dwUpper, phCredentials->dwLower));
  428. LsapLogCallInfo( CallInfo, pSession, *phCredentials );
  429. scRet = ValidateCredHandle(
  430. pSession,
  431. phCredentials,
  432. &CredKey );
  433. if ( !NT_SUCCESS( scRet ) )
  434. {
  435. DsysAssert( (pSession->fSession & SESFLAG_KERNEL) == 0 );
  436. return( scRet );
  437. }
  438. pPackage = SpmpValidRequest(phCredentials->dwLower,
  439. SP_ORDINAL_QUERYCREDATTR );
  440. if (pPackage)
  441. {
  442. SetCurrentPackageId(phCredentials->dwLower);
  443. StartCallToPackage( pPackage );
  444. __try
  445. {
  446. scRet = pPackage->FunctionTable.QueryCredentialsAttributes(
  447. phCredentials->dwUpper,
  448. ulAttribute,
  449. pBuffer
  450. );
  451. }
  452. __except (SP_EXCEPTION)
  453. {
  454. scRet = GetExceptionCode();
  455. scRet = SPException(scRet, phCredentials->dwLower);
  456. }
  457. EndCallToPackage( pPackage );
  458. }
  459. else
  460. {
  461. scRet = SEC_E_INVALID_HANDLE;
  462. }
  463. DerefCredHandle( pSession, NULL, CredKey );
  464. return(scRet);
  465. }