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.

1352 lines
35 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: pwdssp.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 9-07-97 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "pwdsspp.h"
  18. typedef struct _PWD_CRED {
  19. DWORD Ref;
  20. } PWD_CRED, * PPWD_CRED;
  21. typedef struct _PWD_CONTEXT {
  22. DWORD Tag;
  23. HANDLE Token;
  24. } PWD_CONTEXT, *PPWD_CONTEXT ;
  25. PWD_CRED PwdGlobalAnsi;
  26. PWD_CRED PwdGlobalUnicode;
  27. #define CONTEXT_TAG 'txtC'
  28. #define ANONYMOUS_TOKEN ((HANDLE) 1)
  29. SecPkgInfoA PwdInfoA = { SECPKG_FLAG_CONNECTION |
  30. SECPKG_FLAG_ACCEPT_WIN32_NAME,
  31. 1,
  32. (WORD) -1,
  33. 768,
  34. PWDSSP_NAME_A,
  35. "Microsoft Clear Text Password Security Provider" };
  36. SecPkgInfoW PwdInfoW = { SECPKG_FLAG_CONNECTION |
  37. SECPKG_FLAG_ACCEPT_WIN32_NAME,
  38. 1,
  39. (WORD) -1,
  40. 768,
  41. PWDSSP_NAME_W,
  42. L"Microsoft Clear Text Password Security Provider" };
  43. SecurityFunctionTableA PwdTableA = {
  44. SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
  45. EnumerateSecurityPackagesA,
  46. NULL,
  47. AcquireCredentialsHandleA,
  48. FreeCredentialsHandle,
  49. NULL,
  50. InitializeSecurityContextA,
  51. AcceptSecurityContext,
  52. CompleteAuthToken,
  53. DeleteSecurityContext,
  54. ApplyControlToken,
  55. QueryContextAttributesA,
  56. ImpersonateSecurityContext,
  57. RevertSecurityContext,
  58. MakeSignature,
  59. VerifySignature,
  60. FreeContextBuffer,
  61. QuerySecurityPackageInfoA,
  62. NULL,
  63. NULL,
  64. NULL,
  65. NULL,
  66. NULL,
  67. NULL,
  68. QuerySecurityContextToken
  69. };
  70. SecurityFunctionTableW PwdTableW = {
  71. SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
  72. EnumerateSecurityPackagesW,
  73. NULL,
  74. AcquireCredentialsHandleW,
  75. FreeCredentialsHandle,
  76. NULL,
  77. InitializeSecurityContextW,
  78. AcceptSecurityContext,
  79. CompleteAuthToken,
  80. DeleteSecurityContext,
  81. ApplyControlToken,
  82. QueryContextAttributesW,
  83. ImpersonateSecurityContext,
  84. RevertSecurityContext,
  85. MakeSignature,
  86. VerifySignature,
  87. FreeContextBuffer,
  88. QuerySecurityPackageInfoW,
  89. NULL,
  90. NULL,
  91. NULL,
  92. NULL,
  93. NULL,
  94. NULL,
  95. QuerySecurityContextToken
  96. };
  97. //#define PwdAlloc(x) LsaIAllocateHeap(x)
  98. //#define PwdFree(x) LsaIFreeHeap(x)
  99. #define PwdAlloc(x) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,x)
  100. #define PwdFree(x) LocalFree(x)
  101. NTSTATUS
  102. VerifyCredentials(
  103. IN PWSTR UserName,
  104. IN PWSTR DomainName,
  105. IN PWSTR Password,
  106. IN ULONG VerifyFlags
  107. );
  108. UNICODE_STRING AuthenticationPackage;
  109. //+---------------------------------------------------------------------------
  110. //
  111. // Function: DllMain
  112. //
  113. // Synopsis: Entry point
  114. //
  115. // Arguments: [hInstance] --
  116. // [dwReason] --
  117. // [lpReserved] --
  118. //
  119. // Notes:
  120. //
  121. //----------------------------------------------------------------------------
  122. BOOL
  123. WINAPI
  124. DllMain(
  125. HINSTANCE hInstance,
  126. DWORD dwReason,
  127. LPVOID lpReserved)
  128. {
  129. if (dwReason == DLL_PROCESS_ATTACH)
  130. {
  131. DisableThreadLibraryCalls( hInstance );
  132. RtlInitUnicodeString(&AuthenticationPackage, MICROSOFT_KERBEROS_NAME_W);
  133. if ( !CacheInitialize() ) {
  134. return FALSE;
  135. }
  136. }
  137. return(TRUE);
  138. }
  139. //+---------------------------------------------------------------------------
  140. //
  141. // Function: PwdpParseBuffers
  142. //
  143. // Synopsis: Parse out right buffer descriptor
  144. //
  145. // Arguments: [pMessage] --
  146. // [pToken] --
  147. // [pEmpty] --
  148. //
  149. // Notes:
  150. //
  151. //----------------------------------------------------------------------------
  152. VOID
  153. PwdpParseBuffers(
  154. PSecBufferDesc pMessage,
  155. PSecBuffer * pToken,
  156. PSecBuffer * pEmpty)
  157. {
  158. ULONG i;
  159. PSecBuffer pFirstBlank = NULL;
  160. PSecBuffer pWholeMessage = NULL;
  161. for (i = 0 ; i < pMessage->cBuffers ; i++ )
  162. {
  163. if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_TOKEN )
  164. {
  165. pWholeMessage = &pMessage->pBuffers[i];
  166. if (pFirstBlank)
  167. {
  168. break;
  169. }
  170. }
  171. else if ( (pMessage->pBuffers[i].BufferType & (~SECBUFFER_ATTRMASK)) == SECBUFFER_EMPTY )
  172. {
  173. pFirstBlank = &pMessage->pBuffers[i];
  174. if (pWholeMessage)
  175. {
  176. break;
  177. }
  178. }
  179. }
  180. if (pToken)
  181. {
  182. *pToken = pWholeMessage;
  183. }
  184. if (pEmpty)
  185. {
  186. *pEmpty = pFirstBlank;
  187. }
  188. }
  189. //+---------------------------------------------------------------------------
  190. //
  191. // Function: AcquireCredentialsHandleW
  192. //
  193. // Synopsis: Get the credential handle
  194. //
  195. // Arguments: [pszPrincipal] --
  196. // [pszPackageName] --
  197. // [fCredentialUse] --
  198. // [pvLogonId] --
  199. // [pAuthData] --
  200. // [pGetKeyFn] --
  201. // [GetKey] --
  202. // [pvGetKeyArgument] --
  203. // [GetKey] --
  204. // [phCredential] --
  205. // [PTimeStamp] --
  206. //
  207. // Notes:
  208. //
  209. //----------------------------------------------------------------------------
  210. SECURITY_STATUS
  211. SEC_ENTRY
  212. AcquireCredentialsHandleW(
  213. SEC_WCHAR SEC_FAR * pszPrincipal, // Name of principal
  214. SEC_WCHAR SEC_FAR * pszPackageName, // Name of package
  215. unsigned long fCredentialUse, // Flags indicating use
  216. void SEC_FAR * pvLogonId, // Pointer to logon ID
  217. void SEC_FAR * pAuthData, // Package specific data
  218. SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func
  219. void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey()
  220. PCredHandle phCredential, // (out) Cred Handle
  221. PTimeStamp ptsExpiry // (out) Lifetime (optional)
  222. )
  223. {
  224. if (_wcsicmp(pszPackageName, PWDSSP_NAME_W))
  225. {
  226. return( SEC_E_SECPKG_NOT_FOUND );
  227. }
  228. if ( fCredentialUse & SECPKG_CRED_OUTBOUND )
  229. {
  230. return( SEC_E_NO_CREDENTIALS );
  231. }
  232. InterlockedIncrement( &PwdGlobalUnicode.Ref );
  233. phCredential->dwUpper = (ULONG_PTR) &PwdGlobalUnicode ;
  234. if ( ptsExpiry )
  235. {
  236. ptsExpiry->LowPart = (DWORD) 0xFFFFFFFF;
  237. ptsExpiry->HighPart = (DWORD) 0x7FFFFFFF;
  238. }
  239. return( SEC_E_OK );
  240. }
  241. //+---------------------------------------------------------------------------
  242. //
  243. // Function: AcquireCredentialsHandleA
  244. //
  245. // Synopsis: ANSI entry
  246. //
  247. // Arguments: [pszPrincipal] --
  248. // [pszPackageName] --
  249. // [fCredentialUse] --
  250. // [pvLogonId] --
  251. // [pAuthData] --
  252. // [pGetKeyFn] --
  253. // [GetKey] --
  254. // [pvGetKeyArgument] --
  255. // [GetKey] --
  256. // [phCredential] --
  257. //
  258. // Notes:
  259. //
  260. //----------------------------------------------------------------------------
  261. SECURITY_STATUS SEC_ENTRY
  262. AcquireCredentialsHandleA(
  263. SEC_CHAR SEC_FAR * pszPrincipal, // Name of principal
  264. SEC_CHAR SEC_FAR * pszPackageName, // Name of package
  265. unsigned long fCredentialUse, // Flags indicating use
  266. void SEC_FAR * pvLogonId, // Pointer to logon ID
  267. void SEC_FAR * pAuthData, // Package specific data
  268. SEC_GET_KEY_FN pGetKeyFn, // Pointer to GetKey() func
  269. void SEC_FAR * pvGetKeyArgument, // Value to pass to GetKey()
  270. PCredHandle phCredential, // (out) Cred Handle
  271. PTimeStamp ptsExpiry // (out) Lifetime (optional)
  272. )
  273. {
  274. if (_stricmp(pszPackageName, PWDSSP_NAME_A))
  275. {
  276. return( SEC_E_SECPKG_NOT_FOUND );
  277. }
  278. if ( fCredentialUse & SECPKG_CRED_OUTBOUND )
  279. {
  280. return( SEC_E_NO_CREDENTIALS );
  281. }
  282. InterlockedIncrement( &PwdGlobalAnsi.Ref );
  283. phCredential->dwUpper = (ULONG_PTR) &PwdGlobalAnsi ;
  284. if ( ptsExpiry )
  285. {
  286. ptsExpiry->LowPart = (DWORD) 0xFFFFFFFF;
  287. ptsExpiry->HighPart = (DWORD) 0x7FFFFFFF;
  288. }
  289. return(SEC_E_OK);
  290. }
  291. //+---------------------------------------------------------------------------
  292. //
  293. // Function: FreeCredentialHandle
  294. //
  295. // Synopsis: Free a credential handle
  296. //
  297. // Arguments: [free] --
  298. //
  299. // Notes:
  300. //
  301. //----------------------------------------------------------------------------
  302. SECURITY_STATUS
  303. SEC_ENTRY
  304. FreeCredentialsHandle(
  305. PCredHandle phCredential // Handle to free
  306. )
  307. {
  308. PPWD_CRED Cred;
  309. if ( (phCredential->dwUpper != (ULONG_PTR) &PwdGlobalAnsi ) &&
  310. (phCredential->dwUpper != (ULONG_PTR) &PwdGlobalUnicode ) )
  311. {
  312. return( SEC_E_INVALID_HANDLE );
  313. }
  314. Cred = (PPWD_CRED) phCredential->dwUpper ;
  315. InterlockedDecrement( &Cred->Ref );
  316. return( SEC_E_OK );
  317. }
  318. //+---------------------------------------------------------------------------
  319. //
  320. // Function: InitializeSecurityContextW
  321. //
  322. // Synopsis: Initialize a security context (outbound) NOT SUPPORTED
  323. //
  324. // Arguments: [phCredential] --
  325. // [phContext] --
  326. // [pszTargetName] --
  327. // [fContextReq] --
  328. // [Reserved1] --
  329. // [Reserved] --
  330. // [TargetDataRep] --
  331. // [pInput] --
  332. // [Reserved2] --
  333. // [Reserved] --
  334. // [phNewContext] --
  335. // [pOutput] --
  336. // [pfContextAttr] --
  337. //
  338. // Notes:
  339. //
  340. //----------------------------------------------------------------------------
  341. SECURITY_STATUS
  342. SEC_ENTRY
  343. InitializeSecurityContextW(
  344. PCredHandle phCredential, // Cred to base context
  345. PCtxtHandle phContext, // Existing context (OPT)
  346. SEC_WCHAR SEC_FAR * pszTargetName, // Name of target
  347. unsigned long fContextReq, // Context Requirements
  348. unsigned long Reserved1, // Reserved, MBZ
  349. unsigned long TargetDataRep, // Data rep of target
  350. PSecBufferDesc pInput, // Input Buffers
  351. unsigned long Reserved2, // Reserved, MBZ
  352. PCtxtHandle phNewContext, // (out) New Context handle
  353. PSecBufferDesc pOutput, // (inout) Output Buffers
  354. unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs
  355. PTimeStamp ptsExpiry // (out) Life span (OPT)
  356. )
  357. {
  358. return( SEC_E_UNSUPPORTED_FUNCTION );
  359. }
  360. //+---------------------------------------------------------------------------
  361. //
  362. // Function: InitializeSecurityContextA
  363. //
  364. // Synopsis: NOT SUPPORTED
  365. //
  366. // Arguments: [phCredential] --
  367. // [phContext] --
  368. // [pszTargetName] --
  369. // [fContextReq] --
  370. // [Reserved1] --
  371. // [TargetDataRep] --
  372. // [pInput] --
  373. // [Reserved2] --
  374. // [phNewContext] --
  375. // [pOutput] --
  376. // [pfContextAttr] --
  377. //
  378. // Notes:
  379. //
  380. //----------------------------------------------------------------------------
  381. SECURITY_STATUS
  382. SEC_ENTRY
  383. InitializeSecurityContextA(
  384. PCredHandle phCredential, // Cred to base context
  385. PCtxtHandle phContext, // Existing context (OPT)
  386. SEC_CHAR SEC_FAR * pszTargetName, // Name of target
  387. unsigned long fContextReq, // Context Requirements
  388. unsigned long Reserved1, // Reserved, MBZ
  389. unsigned long TargetDataRep, // Data rep of target
  390. PSecBufferDesc pInput, // Input Buffers
  391. unsigned long Reserved2, // Reserved, MBZ
  392. PCtxtHandle phNewContext, // (out) New Context handle
  393. PSecBufferDesc pOutput, // (inout) Output Buffers
  394. unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs
  395. PTimeStamp ptsExpiry // (out) Life span (OPT)
  396. )
  397. {
  398. return( SEC_E_UNSUPPORTED_FUNCTION );
  399. }
  400. PSEC_WINNT_AUTH_IDENTITY_A
  401. PwdpMakeAnsiCopy(
  402. PSEC_WINNT_AUTH_IDENTITY_A Ansi
  403. )
  404. {
  405. PSEC_WINNT_AUTH_IDENTITY_A New ;
  406. New = PwdAlloc( sizeof( SEC_WINNT_AUTH_IDENTITY_A ) +
  407. Ansi->UserLength + 1 +
  408. Ansi->DomainLength + 1 +
  409. Ansi->PasswordLength + 1 );
  410. if ( New )
  411. {
  412. New->User = (PSTR) (New + 1);
  413. CopyMemory( New->User, Ansi->User, Ansi->UserLength );
  414. New->User[ Ansi->UserLength ] = '\0';
  415. New->Domain = New->User + Ansi->UserLength + 1 ;
  416. CopyMemory( New->Domain, Ansi->Domain, Ansi->DomainLength );
  417. New->Domain[ Ansi->DomainLength ] = '\0';
  418. New->Password = New->Domain + Ansi->DomainLength + 1 ;
  419. CopyMemory( New->Password, Ansi->Password, Ansi->PasswordLength );
  420. New->Password[ Ansi->PasswordLength ] = '\0';
  421. }
  422. return( New );
  423. }
  424. PSEC_WINNT_AUTH_IDENTITY_W
  425. PwdpMakeWideCopy(
  426. PSEC_WINNT_AUTH_IDENTITY_W Wide,
  427. BOOLEAN ValidateOnly
  428. )
  429. {
  430. PSEC_WINNT_AUTH_IDENTITY_W New ;
  431. ULONG FlatUserLength ;
  432. PWSTR FlatUser = NULL;
  433. WCHAR FlatDomain[ DNLEN + 2 ];
  434. SEC_WINNT_AUTH_IDENTITY_W Local ;
  435. if ( (Wide->Domain == NULL) )
  436. {
  437. if( ValidateOnly )
  438. {
  439. ULONG Index;
  440. Local = *Wide ;
  441. FlatUserLength = wcslen( Wide->User );
  442. for( Index = 0 ; Index < FlatUserLength ; Index++ )
  443. {
  444. if( Wide->User[ Index ] == '\\' )
  445. {
  446. Local.Domain = Wide->User;
  447. Local.DomainLength = Index;
  448. Local.User = &(Wide->User[Index+1]);
  449. Local.UserLength = FlatUserLength - Index - 1;
  450. break;
  451. }
  452. }
  453. } else {
  454. FlatUserLength = wcslen( Wide->User ) + 1;
  455. if ( FlatUserLength < UNLEN+2 )
  456. {
  457. FlatUserLength = UNLEN + 2;
  458. }
  459. FlatUser = PwdAlloc(FlatUserLength * sizeof( WCHAR ));
  460. if ( FlatUser == NULL )
  461. {
  462. return NULL ;
  463. }
  464. if ( ! PwdCrackName( Wide->User,
  465. FlatDomain,
  466. FlatUser ) )
  467. {
  468. PwdFree( FlatUser );
  469. SetLastError( ERROR_NO_SUCH_USER );
  470. return NULL ;
  471. }
  472. Local = *Wide ;
  473. Local.User = FlatUser ;
  474. Local.Domain = FlatDomain ;
  475. Local.UserLength = wcslen( FlatUser );
  476. Local.DomainLength = wcslen( FlatDomain );
  477. }
  478. Wide = &Local ;
  479. }
  480. New = PwdAlloc( sizeof( SEC_WINNT_AUTH_IDENTITY_W ) +
  481. (Wide->UserLength + 1) * sizeof(WCHAR) +
  482. (Wide->DomainLength + 1) * sizeof(WCHAR) +
  483. (Wide->PasswordLength + 1) * sizeof(WCHAR) );
  484. if ( New )
  485. {
  486. New->User = (PWSTR) (New + 1);
  487. CopyMemory( New->User, Wide->User, Wide->UserLength * 2 );
  488. New->User[ Wide->UserLength ] = L'\0';
  489. New->UserLength = Wide->UserLength;
  490. New->Domain = New->User + Wide->UserLength + 1 ;
  491. CopyMemory( New->Domain, Wide->Domain, Wide->DomainLength * 2 );
  492. New->Domain[ Wide->DomainLength ] = L'\0';
  493. New->DomainLength = Wide->DomainLength;
  494. New->Password = New->Domain + Wide->DomainLength + 1 ;
  495. CopyMemory( New->Password, Wide->Password, Wide->PasswordLength * 2);
  496. New->Password[ Wide->PasswordLength ] = '\0';
  497. New->PasswordLength = Wide->PasswordLength;
  498. }
  499. if ( Wide == &Local )
  500. {
  501. if( FlatUser != NULL )
  502. {
  503. PwdFree( FlatUser );
  504. }
  505. }
  506. return( New );
  507. }
  508. //+---------------------------------------------------------------------------
  509. //
  510. // Function: AcceptSecurityContext
  511. //
  512. // Synopsis: Server side accept security context
  513. //
  514. // Arguments: [phCredential] --
  515. // [phContext] --
  516. // [pInput] --
  517. // [fContextReq] --
  518. // [TargetDataRep] --
  519. // [phNewContext] --
  520. // [pOutput] --
  521. // [pfContextAttr] --
  522. //
  523. // Notes:
  524. //
  525. //----------------------------------------------------------------------------
  526. SECURITY_STATUS
  527. SEC_ENTRY
  528. AcceptSecurityContext(
  529. PCredHandle phCredential, // Cred to base context
  530. PCtxtHandle phContext, // Existing context (OPT)
  531. PSecBufferDesc pInput, // Input buffer
  532. unsigned long fContextReq, // Context Requirements
  533. unsigned long TargetDataRep, // Target Data Rep
  534. PCtxtHandle phNewContext, // (out) New context handle
  535. PSecBufferDesc pOutput, // (inout) Output buffers
  536. unsigned long SEC_FAR * pfContextAttr, // (out) Context attributes
  537. PTimeStamp ptsExpiry // (out) Life span (OPT)
  538. )
  539. {
  540. PPWD_CONTEXT Context ;
  541. PSecBuffer Buffer ;
  542. DWORD Type;
  543. PSEC_WINNT_AUTH_IDENTITY_W Unknown ;
  544. PSEC_WINNT_AUTH_IDENTITY_A Ansi;
  545. PSEC_WINNT_AUTH_IDENTITY_W Unicode;
  546. HANDLE Token;
  547. BOOL Ret;
  548. if ( phCredential->dwUpper == (ULONG_PTR) &PwdGlobalAnsi )
  549. {
  550. Type = 1;
  551. }
  552. else
  553. {
  554. if ( phCredential->dwUpper == (ULONG_PTR) &PwdGlobalUnicode )
  555. {
  556. Type = 2;
  557. }
  558. else
  559. {
  560. return( SEC_E_INVALID_HANDLE );
  561. }
  562. }
  563. PwdpParseBuffers( pInput, &Buffer, NULL );
  564. if ( !Buffer )
  565. {
  566. return( SEC_E_INVALID_TOKEN );
  567. }
  568. Unknown = (PSEC_WINNT_AUTH_IDENTITY_W) Buffer->pvBuffer ;
  569. if ( Unknown->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE )
  570. {
  571. Type = 2 ;
  572. }
  573. if ( Type == 1 )
  574. {
  575. //
  576. // ANSI:
  577. //
  578. Ansi = PwdpMakeAnsiCopy( (PSEC_WINNT_AUTH_IDENTITY_A) Buffer->pvBuffer);
  579. if ( Ansi )
  580. {
  581. Ret = LogonUserA( Ansi->User, Ansi->Domain, Ansi->Password,
  582. LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
  583. &Token ) ;
  584. RtlSecureZeroMemory( Ansi->Password, Ansi->PasswordLength );
  585. PwdFree( Ansi );
  586. }
  587. else
  588. {
  589. Ret = FALSE ;
  590. }
  591. }
  592. else
  593. {
  594. BOOLEAN ValidateOnly = ((fContextReq & ASC_REQ_ALLOW_NON_USER_LOGONS) != 0);
  595. Unicode = PwdpMakeWideCopy(
  596. (PSEC_WINNT_AUTH_IDENTITY_W) Buffer->pvBuffer,
  597. ValidateOnly
  598. );
  599. if ( Unicode )
  600. {
  601. if( ValidateOnly )
  602. {
  603. PVOID DsContext = THSave();
  604. NTSTATUS Status;
  605. Status = VerifyCredentials(
  606. Unicode->User,
  607. Unicode->Domain,
  608. Unicode->Password,
  609. 0
  610. );
  611. THRestore( DsContext );
  612. if( NT_SUCCESS(Status) )
  613. {
  614. Ret = TRUE;
  615. Token = ANONYMOUS_TOKEN ;
  616. } else {
  617. Ret = FALSE;
  618. }
  619. } else {
  620. Ret = LogonUserW(
  621. Unicode->User,
  622. Unicode->Domain,
  623. Unicode->Password,
  624. LOGON32_LOGON_NETWORK,
  625. LOGON32_PROVIDER_DEFAULT,
  626. &Token
  627. );
  628. }
  629. RtlSecureZeroMemory( Unicode->Password, Unicode->PasswordLength * sizeof(WCHAR) );
  630. PwdFree( Unicode );
  631. }
  632. else
  633. {
  634. Ret = FALSE ;
  635. if ( GetLastError() == ERROR_NO_SUCH_USER )
  636. {
  637. Unicode = (PSEC_WINNT_AUTH_IDENTITY_W) Buffer->pvBuffer ;
  638. __try
  639. {
  640. if ( Unicode->PasswordLength == 0 )
  641. {
  642. Ret = TRUE ;
  643. Token = ANONYMOUS_TOKEN ;
  644. }
  645. }
  646. __except( EXCEPTION_EXECUTE_HANDLER )
  647. {
  648. NOTHING ;
  649. }
  650. }
  651. }
  652. }
  653. if ( Ret )
  654. {
  655. Context = (PPWD_CONTEXT) PwdAlloc( sizeof( PWD_CONTEXT ) );
  656. if ( Context )
  657. {
  658. Context->Tag = CONTEXT_TAG ;
  659. Context->Token = Token ;
  660. phNewContext->dwUpper = (ULONG_PTR) Context ;
  661. return( SEC_E_OK );
  662. }
  663. if ( Token != ANONYMOUS_TOKEN )
  664. {
  665. CloseHandle( Token );
  666. }
  667. return( SEC_E_INSUFFICIENT_MEMORY );
  668. }
  669. return( SEC_E_INVALID_TOKEN );
  670. }
  671. //+---------------------------------------------------------------------------
  672. //
  673. // Function: DeleteSecurityContext
  674. //
  675. // Synopsis: Deletes a security context
  676. //
  677. // Arguments: [phContext] --
  678. //
  679. // Notes:
  680. //
  681. //----------------------------------------------------------------------------
  682. SECURITY_STATUS
  683. SEC_ENTRY
  684. DeleteSecurityContext(
  685. PCtxtHandle phContext )
  686. {
  687. PPWD_CONTEXT Context;
  688. Context = (PPWD_CONTEXT) phContext->dwUpper ;
  689. #if DBG
  690. // What is the appropriate assert model? This dll does not seem to
  691. // nt specific, win32 does not provide a model, and the crt requires
  692. // NDEBUG to set, which is not always the case.
  693. if (!Context) {
  694. OutputDebugStringA("[PWDSSP]: !!Error!! - Context is NULL\n");
  695. DebugBreak();
  696. }
  697. #endif
  698. if ( Context->Tag == CONTEXT_TAG )
  699. {
  700. if ( Context->Token != ANONYMOUS_TOKEN )
  701. {
  702. CloseHandle( Context->Token );
  703. }
  704. PwdFree( Context );
  705. return( SEC_E_OK );
  706. }
  707. return( SEC_E_INVALID_HANDLE );
  708. }
  709. //+---------------------------------------------------------------------------
  710. //
  711. // Function: ImpersonateSecurityContext
  712. //
  713. // Synopsis: Impersonate the security context
  714. //
  715. // Arguments: [impersonate] --
  716. //
  717. // Notes:
  718. //
  719. //----------------------------------------------------------------------------
  720. SECURITY_STATUS
  721. SEC_ENTRY
  722. ImpersonateSecurityContext(
  723. PCtxtHandle phContext // Context to impersonate
  724. )
  725. {
  726. PPWD_CONTEXT Context;
  727. HANDLE hThread;
  728. NTSTATUS Status ;
  729. Context = (PPWD_CONTEXT) phContext->dwUpper ;
  730. if ( Context->Tag == CONTEXT_TAG )
  731. {
  732. if ( Context->Token != ANONYMOUS_TOKEN )
  733. {
  734. hThread = GetCurrentThread();
  735. if(SetThreadToken( &hThread, Context->Token ))
  736. {
  737. Status = SEC_E_OK ;
  738. } else {
  739. Status = SEC_E_NO_IMPERSONATION;
  740. }
  741. }
  742. else
  743. {
  744. Status = NtImpersonateAnonymousToken(
  745. NtCurrentThread() );
  746. }
  747. return( Status );
  748. }
  749. return( SEC_E_INVALID_HANDLE );
  750. }
  751. //+---------------------------------------------------------------------------
  752. //
  753. // Function: RevertSecurityContext
  754. //
  755. // Synopsis: Revert the security context
  756. //
  757. // Notes:
  758. //
  759. //----------------------------------------------------------------------------
  760. SECURITY_STATUS
  761. SEC_ENTRY
  762. RevertSecurityContext(
  763. PCtxtHandle phContext // Context from which to re
  764. )
  765. {
  766. PPWD_CONTEXT Context;
  767. Context = (PPWD_CONTEXT) phContext->dwUpper ;
  768. if ( Context->Tag == CONTEXT_TAG )
  769. {
  770. RevertToSelf();
  771. return( SEC_E_OK );
  772. }
  773. return( SEC_E_INVALID_HANDLE );
  774. }
  775. SECURITY_STATUS
  776. SEC_ENTRY
  777. QueryContextAttributesA(
  778. PCtxtHandle phContext, // Context to query
  779. unsigned long ulAttribute, // Attribute to query
  780. void SEC_FAR * pBuffer // Buffer for attributes
  781. )
  782. {
  783. return( SEC_E_UNSUPPORTED_FUNCTION );
  784. }
  785. SECURITY_STATUS
  786. SEC_ENTRY
  787. QueryContextAttributesW(
  788. PCtxtHandle phContext, // Context to query
  789. unsigned long ulAttribute, // Attribute to query
  790. void SEC_FAR * pBuffer // Buffer for attributes
  791. )
  792. {
  793. return( SEC_E_UNSUPPORTED_FUNCTION );
  794. }
  795. //+---------------------------------------------------------------------------
  796. //
  797. // Function: PwdpCopyInfoW
  798. //
  799. // Synopsis: Helper - copy package info around
  800. //
  801. // Arguments: [ppPackageInfo] --
  802. //
  803. // Notes:
  804. //
  805. //----------------------------------------------------------------------------
  806. SECURITY_STATUS
  807. PwdpCopyInfoW(
  808. PSecPkgInfoW * ppPackageInfo)
  809. {
  810. DWORD cbTotal;
  811. PSecPkgInfoW pInfo;
  812. PWSTR pszCopy;
  813. cbTotal = sizeof(SecPkgInfoW) +
  814. (wcslen(PwdInfoW.Name) + wcslen(PwdInfoW.Comment) + 2) * 2;
  815. pInfo = PwdAlloc( cbTotal );
  816. if (pInfo)
  817. {
  818. *pInfo = PwdInfoW;
  819. pszCopy = (PWSTR) (pInfo + 1);
  820. pInfo->Name = pszCopy;
  821. wcscpy(pszCopy, PwdInfoW.Name);
  822. pszCopy += wcslen(PwdInfoW.Name) + 1;
  823. pInfo->Comment = pszCopy;
  824. wcscpy(pszCopy, PwdInfoW.Comment);
  825. *ppPackageInfo = pInfo;
  826. return(SEC_E_OK);
  827. }
  828. return(SEC_E_INSUFFICIENT_MEMORY);
  829. }
  830. //+---------------------------------------------------------------------------
  831. //
  832. // Function: PwdpCopyInfoA
  833. //
  834. // Synopsis: copy ansi package info around
  835. //
  836. // Notes:
  837. //
  838. //----------------------------------------------------------------------------
  839. SECURITY_STATUS
  840. PwdpCopyInfoA(
  841. PSecPkgInfoA * ppPackageInfo)
  842. {
  843. DWORD cbTotal;
  844. PSecPkgInfoA pInfo;
  845. PSTR pszCopy;
  846. cbTotal = sizeof(SecPkgInfoA) +
  847. strlen(PwdInfoA.Name) + strlen(PwdInfoA.Comment) + 2;
  848. pInfo = PwdAlloc( cbTotal );
  849. if (pInfo)
  850. {
  851. *pInfo = PwdInfoA;
  852. pszCopy = (PSTR) (pInfo + 1);
  853. pInfo->Name = pszCopy;
  854. strcpy(pszCopy, PwdInfoA.Name);
  855. pszCopy += strlen(PwdInfoA.Name) + 1;
  856. pInfo->Comment = pszCopy;
  857. strcpy(pszCopy, PwdInfoA.Comment);
  858. *ppPackageInfo = pInfo;
  859. return(SEC_E_OK);
  860. }
  861. return(SEC_E_INSUFFICIENT_MEMORY);
  862. }
  863. //+---------------------------------------------------------------------------
  864. //
  865. // Function: EnumerateSecurityPackagesW
  866. //
  867. // Synopsis: Enumerate packages in this DLL
  868. //
  869. // Arguments: [pcPackages] --
  870. // [info] --
  871. //
  872. // Notes:
  873. //
  874. //----------------------------------------------------------------------------
  875. SECURITY_STATUS
  876. SEC_ENTRY
  877. EnumerateSecurityPackagesW(
  878. unsigned long SEC_FAR * pcPackages, // Receives num. packages
  879. PSecPkgInfoW SEC_FAR * ppPackageInfo // Receives array of info
  880. )
  881. {
  882. SECURITY_STATUS scRet;
  883. *ppPackageInfo = NULL;
  884. scRet = PwdpCopyInfoW(ppPackageInfo);
  885. if (SUCCEEDED(scRet))
  886. {
  887. *pcPackages = 1;
  888. return(scRet);
  889. }
  890. *pcPackages = 0;
  891. return(scRet);
  892. }
  893. //+---------------------------------------------------------------------------
  894. //
  895. // Function: EnumerateSecurityPackagesA
  896. //
  897. // Synopsis: Enumerate
  898. //
  899. // Arguments: [pcPackages] --
  900. // [info] --
  901. //
  902. // Notes:
  903. //
  904. //----------------------------------------------------------------------------
  905. SECURITY_STATUS SEC_ENTRY
  906. EnumerateSecurityPackagesA(
  907. unsigned long SEC_FAR * pcPackages, // Receives num. packages
  908. PSecPkgInfoA SEC_FAR * ppPackageInfo // Receives array of info
  909. )
  910. {
  911. SECURITY_STATUS scRet;
  912. *ppPackageInfo = NULL;
  913. scRet = PwdpCopyInfoA(ppPackageInfo);
  914. if (SUCCEEDED(scRet))
  915. {
  916. *pcPackages = 1;
  917. return(scRet);
  918. }
  919. *pcPackages = 0;
  920. return(scRet);
  921. }
  922. //+---------------------------------------------------------------------------
  923. //
  924. // Function: QuerySecurityPackageInfoW
  925. //
  926. // Synopsis: Query individual package info
  927. //
  928. // Arguments: [pszPackageName] --
  929. // [info] --
  930. //
  931. // Notes:
  932. //
  933. //----------------------------------------------------------------------------
  934. SECURITY_STATUS SEC_ENTRY
  935. QuerySecurityPackageInfoW(
  936. SEC_WCHAR SEC_FAR * pszPackageName, // Name of package
  937. PSecPkgInfoW * ppPackageInfo // Receives package info
  938. )
  939. {
  940. if (_wcsicmp(pszPackageName, PWDSSP_NAME_W))
  941. {
  942. return(SEC_E_SECPKG_NOT_FOUND);
  943. }
  944. return(PwdpCopyInfoW(ppPackageInfo));
  945. }
  946. //+---------------------------------------------------------------------------
  947. //
  948. // Function: QuerySecurityPackageInfoA
  949. //
  950. // Synopsis: Same, ansi
  951. //
  952. // Arguments: [pszPackageName] --
  953. // [info] --
  954. //
  955. // Notes:
  956. //
  957. //----------------------------------------------------------------------------
  958. SECURITY_STATUS SEC_ENTRY
  959. QuerySecurityPackageInfoA(
  960. SEC_CHAR SEC_FAR * pszPackageName, // Name of package
  961. PSecPkgInfoA * ppPackageInfo // Receives package info
  962. )
  963. {
  964. if (_stricmp(pszPackageName, PWDSSP_NAME_A))
  965. {
  966. return(SEC_E_SECPKG_NOT_FOUND);
  967. }
  968. return(PwdpCopyInfoA(ppPackageInfo));
  969. }
  970. SECURITY_STATUS
  971. SEC_ENTRY
  972. MakeSignature(PCtxtHandle phContext,
  973. DWORD fQOP,
  974. PSecBufferDesc pMessage,
  975. ULONG MessageSeqNo)
  976. {
  977. return(SEC_E_UNSUPPORTED_FUNCTION);
  978. }
  979. SECURITY_STATUS SEC_ENTRY
  980. VerifySignature(PCtxtHandle phContext,
  981. PSecBufferDesc pMessage,
  982. ULONG MessageSeqNo,
  983. DWORD * pfQOP)
  984. {
  985. return(SEC_E_UNSUPPORTED_FUNCTION);
  986. }
  987. SECURITY_STATUS
  988. SEC_ENTRY
  989. SealMessage(PCtxtHandle phContext,
  990. DWORD fQOP,
  991. PSecBufferDesc pMessage,
  992. ULONG MessageSeqNo)
  993. {
  994. return(SEC_E_UNSUPPORTED_FUNCTION);
  995. }
  996. SECURITY_STATUS SEC_ENTRY
  997. UnsealMessage(PCtxtHandle phContext,
  998. PSecBufferDesc pMessage,
  999. ULONG MessageSeqNo,
  1000. DWORD * pfQOP)
  1001. {
  1002. return(SEC_E_UNSUPPORTED_FUNCTION);
  1003. }
  1004. SECURITY_STATUS SEC_ENTRY
  1005. ApplyControlToken(
  1006. PCtxtHandle phContext, // Context to modify
  1007. PSecBufferDesc pInput // Input token to apply
  1008. )
  1009. {
  1010. return( SEC_E_UNSUPPORTED_FUNCTION );
  1011. }
  1012. SECURITY_STATUS
  1013. SEC_ENTRY
  1014. FreeContextBuffer(
  1015. PVOID p)
  1016. {
  1017. if( p != NULL )
  1018. {
  1019. PwdFree( p );
  1020. }
  1021. return( SEC_E_OK );
  1022. }
  1023. SECURITY_STATUS
  1024. SEC_ENTRY
  1025. QuerySecurityContextToken(
  1026. PCtxtHandle phContext,
  1027. PHANDLE Token)
  1028. {
  1029. PPWD_CONTEXT Context;
  1030. Context = (PPWD_CONTEXT) phContext->dwUpper ;
  1031. if ( Context->Tag == CONTEXT_TAG )
  1032. {
  1033. *Token = Context->Token ;
  1034. return( SEC_E_OK );
  1035. }
  1036. return( SEC_E_INVALID_HANDLE );
  1037. }
  1038. SECURITY_STATUS SEC_ENTRY
  1039. CompleteAuthToken(
  1040. PCtxtHandle phContext, // Context to complete
  1041. PSecBufferDesc pToken // Token to complete
  1042. )
  1043. {
  1044. return( SEC_E_UNSUPPORTED_FUNCTION );
  1045. }
  1046. PSecurityFunctionTableA
  1047. SEC_ENTRY
  1048. InitSecurityInterfaceA( VOID )
  1049. {
  1050. return( &PwdTableA );
  1051. }
  1052. PSecurityFunctionTableW
  1053. SEC_ENTRY
  1054. InitSecurityInterfaceW( VOID )
  1055. {
  1056. return( &PwdTableW );
  1057. }
  1058. NTSTATUS
  1059. VerifyCredentials(
  1060. IN PWSTR UserName,
  1061. IN PWSTR DomainName,
  1062. IN PWSTR Password,
  1063. IN ULONG VerifyFlags
  1064. )
  1065. {
  1066. PKERB_VERIFY_CREDENTIALS_REQUEST pVerifyRequest;
  1067. KERB_VERIFY_CREDENTIALS_REQUEST VerifyRequest;
  1068. ULONG cbVerifyRequest;
  1069. PVOID pResponse = NULL;
  1070. ULONG cbResponse;
  1071. USHORT cbUserName;
  1072. USHORT cbDomainName;
  1073. USHORT cbPassword;
  1074. NTSTATUS ProtocolStatus = STATUS_LOGON_FAILURE;
  1075. NTSTATUS Status;
  1076. cbUserName = (USHORT)(lstrlenW(UserName) * sizeof(WCHAR)) ;
  1077. cbDomainName = (USHORT)(lstrlenW(DomainName) * sizeof(WCHAR)) ;
  1078. cbPassword = (USHORT)(lstrlenW(Password) * sizeof(WCHAR)) ;
  1079. cbVerifyRequest = sizeof(VerifyRequest) +
  1080. cbUserName +
  1081. cbDomainName +
  1082. cbPassword ;
  1083. pVerifyRequest = &VerifyRequest;
  1084. ZeroMemory( &VerifyRequest, sizeof(VerifyRequest) );
  1085. pVerifyRequest->MessageType = KerbVerifyCredentialsMessage ;
  1086. //
  1087. // do the length, buffers, copy, marshall dance.
  1088. //
  1089. pVerifyRequest->UserName.Length = cbUserName;
  1090. pVerifyRequest->UserName.MaximumLength = cbUserName;
  1091. pVerifyRequest->UserName.Buffer = UserName;
  1092. pVerifyRequest->DomainName.Length = cbDomainName;
  1093. pVerifyRequest->DomainName.MaximumLength = cbDomainName;
  1094. pVerifyRequest->DomainName.Buffer = DomainName;
  1095. pVerifyRequest->Password.Length = cbPassword;
  1096. pVerifyRequest->Password.MaximumLength = cbPassword;
  1097. pVerifyRequest->Password.Buffer = Password;
  1098. pVerifyRequest->VerifyFlags = VerifyFlags;
  1099. Status = I_LsaICallPackage(
  1100. &AuthenticationPackage,
  1101. pVerifyRequest,
  1102. cbVerifyRequest,
  1103. &pResponse,
  1104. &cbResponse,
  1105. &ProtocolStatus
  1106. );
  1107. if(!NT_SUCCESS(Status))
  1108. {
  1109. goto Cleanup;
  1110. }
  1111. Status = ProtocolStatus;
  1112. Cleanup:
  1113. return Status;
  1114. }