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.

1235 lines
32 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1995 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: ntauth.c
  7. //
  8. // Description: Contains entrypoints to do NT back-end authentication for
  9. // ppp.
  10. //
  11. // History: Feb 11,1997 NarenG Created original version.
  12. //
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <ntlsa.h>
  17. #include <ntmsv1_0.h>
  18. #include <ntsamp.h>
  19. #include <crypt.h>
  20. #include <crypt.h>
  21. #define INC_OLE2
  22. #include <windows.h>
  23. #include <lmcons.h>
  24. #include <netlib.h> // For NetpGetDomainNameEx
  25. #include <lmapibuf.h>
  26. #include <lmaccess.h>
  27. #include <raserror.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <locale.h>
  32. #include <shlobj.h>
  33. #include <dsclient.h>
  34. #include <dsgetdc.h>
  35. #include <ntdsapi.h>
  36. #include <rasman.h>
  37. #include <rasppp.h>
  38. #include <mprerror.h>
  39. #include <rasauth.h>
  40. #include <mprlog.h>
  41. #include <pppcp.h>
  42. #include <rtutils.h>
  43. #define INCL_RASAUTHATTRIBUTES
  44. #define INCL_HOSTWIRE
  45. #define INCL_MISC
  46. #include <ppputil.h>
  47. #define ALLOCATE_GLOBALS
  48. #include "ntauth.h"
  49. #include "resource.h"
  50. //**
  51. //
  52. // Call: RasAuthDllEntry
  53. //
  54. // Returns: TRUE - Success
  55. // FALSE - Failure
  56. //
  57. // Description:
  58. //
  59. BOOL
  60. RasAuthDllEntry(
  61. HANDLE hinstDll,
  62. DWORD fdwReason,
  63. LPVOID lpReserved
  64. )
  65. {
  66. switch (fdwReason)
  67. {
  68. case DLL_PROCESS_ATTACH:
  69. {
  70. DisableThreadLibraryCalls( hinstDll );
  71. g_hInstance = hinstDll;
  72. break;
  73. }
  74. case DLL_PROCESS_DETACH:
  75. {
  76. g_hInstance = NULL;
  77. break;
  78. }
  79. default:
  80. break;
  81. }
  82. return( TRUE );
  83. }
  84. //**
  85. //
  86. // Call: RasAuthProviderInitialize
  87. //
  88. // Returns: NO_ERROR - Success
  89. // Non-zero returns - Failure
  90. //
  91. // Description:
  92. //
  93. DWORD APIENTRY
  94. RasAuthProviderInitialize(
  95. IN RAS_AUTH_ATTRIBUTE * pServerAttributes,
  96. IN HANDLE hEventLog,
  97. IN DWORD dwLoggingLevel
  98. )
  99. {
  100. DWORD dwRetCode = NO_ERROR;
  101. HRESULT hResult;
  102. NT_PRODUCT_TYPE NtProductType = NtProductLanManNt;
  103. LPWSTR lpwstrDomainNamePtr = NULL;
  104. BOOLEAN fIsWorkgroupName = FALSE;
  105. //
  106. // If already initalized, we return
  107. //
  108. if ( g_fInitialized )
  109. {
  110. return( NO_ERROR );
  111. }
  112. g_dwTraceIdNt = INVALID_TRACEID;
  113. setlocale( LC_ALL,"" );
  114. g_dwTraceIdNt = TraceRegisterA( "RASAUTH" );
  115. hResult = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  116. if ( FAILED( hResult ) )
  117. {
  118. return( HRESULT_CODE( hResult ) );
  119. }
  120. hResult = InitializeIas( TRUE );
  121. if ( FAILED( hResult ) )
  122. {
  123. dwRetCode = HRESULT_CODE( hResult );
  124. TRACE1("Initialize Ias failed with %d", dwRetCode );
  125. CoUninitialize();
  126. return( dwRetCode );
  127. }
  128. g_hEventLog = hEventLog;
  129. g_LoggingLevel = dwLoggingLevel;
  130. if (!LoadString(g_hInstance, IDS_UNAUTHENTICATED_USER,
  131. g_aszUnauthenticatedUser, MaxCharsUnauthUser_c))
  132. {
  133. g_aszUnauthenticatedUser[0] = 0;
  134. }
  135. g_fInitialized = TRUE;
  136. TRACE("RasAuthProviderInitialize succeeded");
  137. return( NO_ERROR );
  138. }
  139. //**
  140. //
  141. // Call: RasAuthProviderTerminate
  142. //
  143. // Returns: NO_ERROR - Success
  144. // Non-zero returns - Failure
  145. //
  146. // Description:
  147. //
  148. DWORD APIENTRY
  149. RasAuthProviderTerminate(
  150. VOID
  151. )
  152. {
  153. //
  154. // If already terminated, we return
  155. //
  156. if ( !g_fInitialized )
  157. {
  158. return( NO_ERROR );
  159. }
  160. g_fInitialized = FALSE;
  161. if ( g_dwTraceIdNt != INVALID_TRACEID )
  162. {
  163. TraceDeregisterA( g_dwTraceIdNt );
  164. }
  165. ShutdownIas();
  166. CoUninitialize();
  167. TRACE("RasAuthTerminate succeeded");
  168. return( NO_ERROR );
  169. }
  170. //**
  171. //
  172. // Call: RasAcctProviderInitialize
  173. //
  174. // Returns: NO_ERROR - Success
  175. // Non-zero returns - Failure
  176. //
  177. // Description:
  178. //
  179. DWORD APIENTRY
  180. RasAcctProviderInitialize(
  181. IN RAS_AUTH_ATTRIBUTE * pServerAttributes,
  182. IN HANDLE hEventLog,
  183. IN DWORD dwLoggingLevel
  184. )
  185. {
  186. RAS_AUTH_ATTRIBUTE * pOutAttributes = NULL;
  187. DWORD dwResultCode;
  188. DWORD dwRetCode = RasAuthProviderInitialize( pServerAttributes,
  189. hEventLog,
  190. dwLoggingLevel );
  191. if ( dwRetCode == NO_ERROR )
  192. {
  193. dwRetCode = IASSendReceiveAttributes( RAS_IAS_ACCOUNTING_ON,
  194. pServerAttributes,
  195. &pOutAttributes,
  196. &dwResultCode );
  197. if ( pOutAttributes != NULL )
  198. {
  199. RasAuthAttributeDestroy( pOutAttributes );
  200. }
  201. if ( dwRetCode == NO_ERROR )
  202. {
  203. //
  204. // Make a copy of the Server attributes
  205. //
  206. g_pServerAttributes = RasAuthAttributeCopy( pServerAttributes );
  207. if ( g_pServerAttributes == NULL )
  208. {
  209. dwRetCode = GetLastError();
  210. }
  211. }
  212. }
  213. g_hEventLog = hEventLog;
  214. g_LoggingLevel = dwLoggingLevel;
  215. return( dwRetCode );
  216. }
  217. //**
  218. //
  219. // Call: RasAcctProviderTerminate
  220. //
  221. // Returns: NO_ERROR - Success
  222. // Non-zero returns - Failure
  223. //
  224. // Description:
  225. //
  226. DWORD APIENTRY
  227. RasAcctProviderTerminate(
  228. VOID
  229. )
  230. {
  231. RAS_AUTH_ATTRIBUTE * pOutAttributes = NULL;
  232. DWORD dwResultCode;
  233. IASSendReceiveAttributes( RAS_IAS_ACCOUNTING_OFF,
  234. g_pServerAttributes,
  235. &pOutAttributes,
  236. &dwResultCode );
  237. if ( pOutAttributes != NULL )
  238. {
  239. RasAuthAttributeDestroy( pOutAttributes );
  240. }
  241. if ( g_pServerAttributes != NULL )
  242. {
  243. RasAuthAttributeDestroy( g_pServerAttributes );
  244. g_pServerAttributes = NULL;
  245. }
  246. RasAuthProviderTerminate();
  247. return( NO_ERROR );
  248. }
  249. //**
  250. //
  251. // Call: RasAcctProviderStartAccounting
  252. //
  253. // Returns: NO_ERROR - Success
  254. // Non-zero returns - Failure
  255. //
  256. // Description:
  257. //
  258. DWORD APIENTRY
  259. RasAcctProviderStartAccounting(
  260. IN RAS_AUTH_ATTRIBUTE * pInAttributes,
  261. OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes
  262. )
  263. {
  264. DWORD dwResultCode = NO_ERROR;
  265. TRACE("RasStartAccounting called");
  266. return( IASSendReceiveAttributes( RAS_IAS_START_ACCOUNTING,
  267. pInAttributes,
  268. ppOutAttributes,
  269. &dwResultCode ) );
  270. }
  271. //**
  272. //
  273. // Call: RasAcctProviderStopAccounting
  274. //
  275. // Returns: NO_ERROR - Success
  276. // Non-zero returns - Failure
  277. //
  278. // Description:
  279. //
  280. DWORD APIENTRY
  281. RasAcctProviderStopAccounting(
  282. IN RAS_AUTH_ATTRIBUTE * pInAttributes,
  283. OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes
  284. )
  285. {
  286. DWORD dwResultCode = NO_ERROR;
  287. TRACE("RasStopAccounting called");
  288. return( IASSendReceiveAttributes( RAS_IAS_STOP_ACCOUNTING,
  289. pInAttributes,
  290. ppOutAttributes,
  291. &dwResultCode ) );
  292. }
  293. //**
  294. //
  295. // Call: RasAcctConfigChangeNotification
  296. //
  297. // Returns: NO_ERROR - Success
  298. // Non-zero returns - Failure
  299. //
  300. // Description: Reloads config information dynamically
  301. //
  302. DWORD APIENTRY
  303. RasAcctConfigChangeNotification(
  304. IN DWORD dwLoggingLevel
  305. )
  306. {
  307. TRACE("RasAcctConfigChangeNotification called");
  308. g_LoggingLevel = dwLoggingLevel;
  309. return( NO_ERROR );
  310. }
  311. //**
  312. //
  313. // Call: RasAcctProviderInterimAccounting
  314. //
  315. // Returns: NO_ERROR - Success
  316. // Non-zero returns - Failure
  317. //
  318. // Description:
  319. //
  320. DWORD APIENTRY
  321. RasAcctProviderInterimAccounting(
  322. IN RAS_AUTH_ATTRIBUTE * pInAttributes,
  323. OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes
  324. )
  325. {
  326. DWORD dwResultCode = NO_ERROR;
  327. TRACE("RasInterimAccounting called");
  328. return( IASSendReceiveAttributes( RAS_IAS_INTERIM_ACCOUNTING,
  329. pInAttributes,
  330. ppOutAttributes,
  331. &dwResultCode ) );
  332. }
  333. //**
  334. //
  335. // Call: RasAuthConfigChangeNotification
  336. //
  337. // Returns: NO_ERROR - Success
  338. // Non-zero returns - Failure
  339. //
  340. // Description: Reloads config information dynamically
  341. //
  342. DWORD APIENTRY
  343. RasAuthConfigChangeNotification(
  344. IN DWORD dwLoggingLevel
  345. )
  346. {
  347. TRACE("RasAuthConfigChangeNotification called");
  348. g_LoggingLevel = dwLoggingLevel;
  349. return( NO_ERROR );
  350. }
  351. //**
  352. //
  353. // Call: MapIasRetCodeToRasError
  354. //
  355. // Description: Maps IAS_RETCODE to an error in raserror.h or mprerror.h
  356. //
  357. DWORD
  358. MapIasRetCodeToRasError(
  359. IN LONG lFailureReason
  360. )
  361. {
  362. DWORD dwError;
  363. switch ( lFailureReason )
  364. {
  365. case IAS_CHANGE_PASSWORD_FAILURE:
  366. dwError = ERROR_CHANGING_PASSWORD;
  367. break;
  368. case IAS_ACCOUNT_DISABLED:
  369. dwError = ERROR_ACCT_DISABLED;
  370. break;
  371. case IAS_ACCOUNT_EXPIRED:
  372. dwError = ERROR_ACCT_EXPIRED;
  373. break;
  374. case IAS_INVALID_LOGON_HOURS:
  375. case IAS_INVALID_DIALIN_HOURS:
  376. dwError = ERROR_DIALIN_HOURS_RESTRICTION;
  377. break;
  378. case IAS_DIALIN_DISABLED:
  379. dwError = ERROR_NO_DIALIN_PERMISSION;
  380. break;
  381. case IAS_SESSION_TIMEOUT:
  382. dwError = ERROR_AUTH_SERVER_TIMEOUT;
  383. break;
  384. case IAS_INVALID_PORT_TYPE:
  385. dwError = ERROR_ALLOWED_PORT_TYPE_RESTRICTION;
  386. break;
  387. case IAS_INVALID_AUTH_TYPE:
  388. dwError = ERROR_AUTH_PROTOCOL_RESTRICTION;
  389. break;
  390. default:
  391. dwError = ERROR_AUTHENTICATION_FAILURE;
  392. break;
  393. }
  394. return( dwError );
  395. }
  396. //**
  397. //
  398. // Call: IASSendReceiveAttributes
  399. //
  400. // Returns: NO_ERROR - Success
  401. // Non-zero returns - Failure
  402. //
  403. // Description: Will send attributes to and receive attributes from IAS
  404. //
  405. DWORD
  406. IASSendReceiveAttributes(
  407. IN RAS_IAS_REQUEST_TYPE RequestType,
  408. IN RAS_AUTH_ATTRIBUTE * pInAttributes,
  409. OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes,
  410. OUT DWORD * lpdwResultCode
  411. )
  412. {
  413. DWORD dwIndex;
  414. HRESULT hResult;
  415. LONG IasResponse;
  416. LONG IasRequest;
  417. DWORD dwInAttributeCount = 0;
  418. DWORD dwTotalInAttributeCount = 0;
  419. PIASATTRIBUTE * ppInIasAttributes = NULL;
  420. DWORD dwOutAttributeCount = 0;
  421. PIASATTRIBUTE * ppOutIasAttributes = NULL;
  422. IAS_INET_ADDR InetAddr = 0;
  423. RAS_AUTH_ATTRIBUTE * pNASIdentifier = NULL;
  424. RAS_AUTH_ATTRIBUTE * pCallingStationId = NULL;
  425. DWORD dwLength;
  426. PVOID pValue;
  427. BOOL fConvertToAnsi;
  428. DWORD dwRetCode = NO_ERROR;
  429. LPSTR lpsUserName = g_aszUnauthenticatedUser;
  430. LONG lFailureReason;
  431. RasAuthAttributesPrint( g_dwTraceIdNt, TRACE_NTAUTH, pInAttributes );
  432. switch( RequestType )
  433. {
  434. case RAS_IAS_START_ACCOUNTING:
  435. case RAS_IAS_STOP_ACCOUNTING:
  436. case RAS_IAS_INTERIM_ACCOUNTING:
  437. case RAS_IAS_ACCOUNTING_ON:
  438. case RAS_IAS_ACCOUNTING_OFF:
  439. IasRequest = IAS_REQUEST_ACCOUNTING;
  440. break;
  441. case RAS_IAS_ACCESS_REQUEST:
  442. IasRequest = IAS_REQUEST_ACCESS_REQUEST;
  443. break;
  444. default:
  445. ASSERT( FALSE );
  446. return( ERROR_INVALID_PARAMETER );
  447. }
  448. *ppOutAttributes = NULL;
  449. *lpdwResultCode = ERROR_AUTHENTICATION_FAILURE;
  450. hResult = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  451. if ( FAILED( hResult ) )
  452. {
  453. return( HRESULT_CODE( hResult ) );
  454. }
  455. do
  456. {
  457. //
  458. // First findout how many attributes there are
  459. //
  460. for ( dwInAttributeCount = 0;
  461. pInAttributes[dwInAttributeCount].raaType != raatMinimum;
  462. dwInAttributeCount++);
  463. dwTotalInAttributeCount = dwInAttributeCount;
  464. if ( IasRequest == IAS_REQUEST_ACCOUNTING )
  465. {
  466. //
  467. // Add one more of the Acct-Status-Type attribute
  468. //
  469. dwTotalInAttributeCount++;
  470. }
  471. //
  472. // Add two more for Client-IP-Address and Client-Friendly-Name
  473. //
  474. dwTotalInAttributeCount += 2;
  475. //
  476. // Now allocate an array of pointer to attributes
  477. //
  478. ppInIasAttributes =
  479. (PIASATTRIBUTE *)
  480. MemAllocIas(sizeof(PIASATTRIBUTE) * dwTotalInAttributeCount);
  481. if ( ppInIasAttributes == NULL )
  482. {
  483. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  484. break;
  485. }
  486. ZeroMemory( ppInIasAttributes,
  487. sizeof(PIASATTRIBUTE) * dwTotalInAttributeCount );
  488. //
  489. // Now allocate the attributes
  490. //
  491. hResult = AllocateAttributes( dwTotalInAttributeCount,
  492. ppInIasAttributes );
  493. if ( FAILED( hResult ) )
  494. {
  495. dwRetCode = HRESULT_CODE( hResult );
  496. break;
  497. }
  498. //
  499. // Convert to IAS attributes
  500. //
  501. for ( dwIndex = 0; dwIndex < dwInAttributeCount; dwIndex++ )
  502. {
  503. switch( pInAttributes[dwIndex].raaType )
  504. {
  505. case raatNASPort:
  506. case raatServiceType:
  507. case raatFramedProtocol:
  508. //
  509. // arap connection? it's an access-request
  510. //
  511. if ((pInAttributes[dwIndex].raaType == raatFramedProtocol) &&
  512. (pInAttributes[dwIndex].Value == (LPVOID)3))
  513. {
  514. IasRequest = IAS_REQUEST_ACCESS_REQUEST;
  515. }
  516. //
  517. // fall through
  518. //
  519. case raatFramedRouting:
  520. case raatFramedMTU:
  521. case raatFramedCompression:
  522. case raatLoginIPHost:
  523. case raatLoginService:
  524. case raatLoginTCPPort:
  525. case raatFramedIPXNetwork:
  526. case raatSessionTimeout:
  527. case raatIdleTimeout:
  528. case raatTerminationAction:
  529. case raatFramedAppleTalkLink:
  530. case raatFramedAppleTalkNetwork:
  531. case raatNASPortType:
  532. case raatPortLimit:
  533. case raatTunnelType:
  534. case raatTunnelMediumType:
  535. case raatAcctStatusType:
  536. case raatAcctDelayTime:
  537. case raatAcctInputOctets:
  538. case raatAcctOutputOctets:
  539. case raatAcctAuthentic:
  540. case raatAcctSessionTime:
  541. case raatAcctInputPackets:
  542. case raatAcctOutputPackets:
  543. case raatAcctTerminateCause:
  544. case raatAcctLinkCount:
  545. case raatFramedIPNetmask:
  546. case raatPrompt:
  547. case raatPasswordRetry:
  548. case raatARAPZoneAccess:
  549. case raatARAPSecurity:
  550. case raatAcctEventTimeStamp:
  551. (ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INTEGER;
  552. (ppInIasAttributes[dwIndex])->Value.Integer =
  553. PtrToUlong(pInAttributes[dwIndex].Value);
  554. break;
  555. case raatNASIPAddress:
  556. InetAddr = PtrToUlong(pInAttributes[dwIndex].Value);
  557. //
  558. // Fall through
  559. //
  560. case raatFramedIPAddress:
  561. (ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INET_ADDR;
  562. (ppInIasAttributes[dwIndex])->Value.InetAddr =
  563. PtrToUlong(pInAttributes[dwIndex].Value);
  564. break;
  565. case raatUserPassword:
  566. case raatMD5CHAPPassword:
  567. case raatARAPPassword:
  568. case raatEAPMessage:
  569. //
  570. // If any passwords are present then we want authentication
  571. // as well.
  572. //
  573. IasRequest = IAS_REQUEST_ACCESS_REQUEST;
  574. //
  575. // Fall thru
  576. //
  577. case raatVendorSpecific:
  578. //
  579. // Is this the MS-CHAP password ?
  580. //
  581. if ( ( pInAttributes[dwIndex].raaType == raatVendorSpecific ) &&
  582. ( pInAttributes[dwIndex].dwLength >= 8 ) )
  583. {
  584. //
  585. // Does the Vendor Id match Microsoft's ?
  586. //
  587. if ( WireToHostFormat32(
  588. (PBYTE)(pInAttributes[dwIndex].Value)) == 311 )
  589. {
  590. //
  591. // Does the vendor type match MS-CHAP password's,
  592. // change pasword V1 or V2 ?
  593. //
  594. switch( *(((PBYTE)(pInAttributes[dwIndex].Value))+4) )
  595. {
  596. //
  597. // is this is an MS-CHAP password?
  598. //
  599. case 1:
  600. case 3:
  601. case 4:
  602. //
  603. // is this is an ARAP password?
  604. //
  605. case raatARAPOldPassword:
  606. case raatARAPNewPassword:
  607. IasRequest = IAS_REQUEST_ACCESS_REQUEST;
  608. break;
  609. default:
  610. break;
  611. }
  612. }
  613. }
  614. //
  615. // Fall thru
  616. //
  617. default:
  618. if ( pInAttributes[dwIndex].raaType == raatUserName )
  619. {
  620. //
  621. // Save pointer for logging purposes
  622. //
  623. lpsUserName = (PBYTE)(pInAttributes[dwIndex].Value);
  624. }
  625. {
  626. DWORD dwLength1 = pInAttributes[dwIndex].dwLength;
  627. PBYTE pValue1 = (PBYTE)MemAllocIas( dwLength1 );
  628. if ( pValue1 == NULL )
  629. {
  630. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  631. break;
  632. }
  633. if ( raatNASIdentifier == pInAttributes[dwIndex].raaType )
  634. {
  635. pNASIdentifier = pInAttributes + dwIndex;
  636. }
  637. if ( raatCallingStationId == pInAttributes[dwIndex].raaType )
  638. {
  639. pCallingStationId = pInAttributes + dwIndex;
  640. }
  641. (ppInIasAttributes[dwIndex])->Value.itType =
  642. IASTYPE_OCTET_STRING;
  643. (ppInIasAttributes[dwIndex])->Value.OctetString.dwLength =
  644. dwLength1;
  645. (ppInIasAttributes[dwIndex])->Value.OctetString.lpValue =
  646. pValue1;
  647. CopyMemory( pValue1,
  648. (PBYTE)(pInAttributes[dwIndex].Value),
  649. dwLength1 );
  650. break;
  651. }
  652. }
  653. if ( dwRetCode != NO_ERROR )
  654. {
  655. break;
  656. }
  657. //
  658. // Set the attribute Id
  659. //
  660. (ppInIasAttributes[dwIndex])->dwId = pInAttributes[dwIndex].raaType;
  661. TRACE1( "Inserting attribute type %d",
  662. pInAttributes[dwIndex].raaType );
  663. }
  664. if ( dwRetCode != NO_ERROR )
  665. {
  666. break;
  667. }
  668. //
  669. // If accounting type of request then we need to add the
  670. // Acct-Status-Type attribute
  671. //
  672. if ( IasRequest == IAS_REQUEST_ACCOUNTING )
  673. {
  674. (ppInIasAttributes[dwIndex])->dwId = raatAcctStatusType;
  675. (ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INTEGER;
  676. switch ( RequestType )
  677. {
  678. case RAS_IAS_START_ACCOUNTING:
  679. (ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)1;
  680. break;
  681. case RAS_IAS_STOP_ACCOUNTING:
  682. (ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)2;
  683. break;
  684. case RAS_IAS_INTERIM_ACCOUNTING:
  685. (ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)3;
  686. break;
  687. case RAS_IAS_ACCOUNTING_ON:
  688. (ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)7;
  689. break;
  690. case RAS_IAS_ACCOUNTING_OFF:
  691. (ppInIasAttributes[dwIndex])->Value.Integer = (DWORD)8;
  692. break;
  693. }
  694. dwIndex++;
  695. }
  696. //
  697. // Insert Client-IP-Address and Client-Friendly-Name
  698. //
  699. if ( 0 != InetAddr )
  700. {
  701. (ppInIasAttributes[dwIndex])->dwId = 4108; // Client-IP-Address
  702. (ppInIasAttributes[dwIndex])->Value.itType = IASTYPE_INET_ADDR;
  703. (ppInIasAttributes[dwIndex])->Value.InetAddr = InetAddr;
  704. dwIndex++;
  705. TRACE( "Inserting attribute type 4108" );
  706. }
  707. else
  708. {
  709. //
  710. // Decrement the count since we added this to count
  711. // before
  712. //
  713. dwTotalInAttributeCount--;
  714. }
  715. if ( NULL != pNASIdentifier )
  716. {
  717. DWORD dwLength1 = pNASIdentifier->dwLength;
  718. PBYTE pValue1 = (PBYTE)MemAllocIas( dwLength1 );
  719. if ( pValue1 == NULL )
  720. {
  721. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  722. break;
  723. }
  724. (ppInIasAttributes[dwIndex])->dwId = 4128; // Client-Friendly-Name
  725. (ppInIasAttributes[dwIndex])->Value.itType =
  726. IASTYPE_OCTET_STRING;
  727. (ppInIasAttributes[dwIndex])->Value.OctetString.dwLength =
  728. dwLength1;
  729. (ppInIasAttributes[dwIndex])->Value.OctetString.lpValue =
  730. pValue1;
  731. CopyMemory( pValue1,
  732. (PBYTE)(pNASIdentifier->Value),
  733. dwLength1 );
  734. dwIndex++;
  735. TRACE( "Inserting attribute type 4128" );
  736. }
  737. else
  738. {
  739. //
  740. // Decrement the count since we added this to the count
  741. // before.
  742. //
  743. dwTotalInAttributeCount--;
  744. }
  745. //
  746. // process the filled attributes
  747. //
  748. hResult = DoRequest(
  749. dwTotalInAttributeCount,
  750. ppInIasAttributes,
  751. &dwOutAttributeCount,
  752. &ppOutIasAttributes,
  753. IasRequest,
  754. &IasResponse,
  755. IAS_PROTOCOL_RAS,
  756. &lFailureReason,
  757. TRUE );
  758. if ( FAILED( hResult ) )
  759. {
  760. dwRetCode = HRESULT_CODE( hResult );
  761. TRACE1( "IAS->DoRequest failed with %d", dwRetCode );
  762. break;
  763. }
  764. switch( IasResponse )
  765. {
  766. case IAS_RESPONSE_ACCESS_ACCEPT:
  767. TRACE( "IASResponse = ACCESS_ACCEPT");
  768. *lpdwResultCode = NO_ERROR;
  769. break;
  770. case IAS_RESPONSE_ACCESS_CHALLENGE:
  771. TRACE( "IASResponse = ACCESS_CHALLENGE");
  772. *lpdwResultCode = NO_ERROR;
  773. break;
  774. case IAS_RESPONSE_DISCARD_PACKET:
  775. TRACE1( "IASResponse = DISCARD_PACKET. Failurereason=0x%x",
  776. lFailureReason);
  777. *lpdwResultCode = MapIasRetCodeToRasError( lFailureReason );
  778. dwRetCode = *lpdwResultCode;
  779. break;
  780. case IAS_RESPONSE_ACCESS_REJECT:
  781. {
  782. WCHAR *lpwsSubStringArray[3];
  783. WCHAR wchInsertionString[13];
  784. WCHAR wchUserName[UNLEN+1];
  785. WCHAR wchCallerId[100];
  786. MultiByteToWideChar( CP_ACP,
  787. 0,
  788. lpsUserName,
  789. -1,
  790. wchUserName,
  791. UNLEN+1 );
  792. wsprintfW( wchInsertionString, L"%%%%%lu", lFailureReason + 0x1000 );
  793. if ( pCallingStationId != NULL )
  794. {
  795. lpwsSubStringArray[0] = wchUserName;
  796. lpwsSubStringArray[1] = wchCallerId;
  797. lpwsSubStringArray[2] = wchInsertionString;
  798. MultiByteToWideChar( CP_ACP,
  799. 0,
  800. (PBYTE)(pCallingStationId->Value),
  801. -1,
  802. wchCallerId,
  803. 100 );
  804. NtAuthLogWarning( ROUTERLOG_NTAUTH_FAILURE_EX, 3, lpwsSubStringArray);
  805. }
  806. else
  807. {
  808. lpwsSubStringArray[0] = wchUserName;
  809. lpwsSubStringArray[1] = wchInsertionString;
  810. NtAuthLogWarning( ROUTERLOG_NTAUTH_FAILURE, 2, lpwsSubStringArray );
  811. }
  812. *lpdwResultCode = MapIasRetCodeToRasError( lFailureReason );
  813. }
  814. default:
  815. TRACE2( "IASResponse = %d, FailureReason = 0x%x",
  816. IasResponse, lFailureReason );
  817. break;
  818. }
  819. if ( dwRetCode != NO_ERROR )
  820. {
  821. break;
  822. }
  823. if ( dwOutAttributeCount > 0 )
  824. {
  825. //
  826. // Convert from IAS attributes
  827. //
  828. *ppOutAttributes = RasAuthAttributeCreate( dwOutAttributeCount );
  829. if ( *ppOutAttributes == NULL )
  830. {
  831. dwRetCode = GetLastError();
  832. break;
  833. }
  834. for ( dwIndex = 0; dwIndex < dwOutAttributeCount; dwIndex++ )
  835. {
  836. IASVALUE IasValue = (ppOutIasAttributes[dwIndex])->Value;
  837. fConvertToAnsi = FALSE;
  838. switch ( IasValue.itType )
  839. {
  840. case IASTYPE_INTEGER:
  841. dwLength = sizeof( DWORD );
  842. pValue = (LPVOID) ULongToPtr(IasValue.Integer);
  843. break;
  844. case IASTYPE_BOOLEAN:
  845. dwLength = sizeof( DWORD );
  846. pValue = (LPVOID)ULongToPtr(IasValue.Boolean);
  847. break;
  848. case IASTYPE_ENUM:
  849. dwLength = sizeof( DWORD );
  850. pValue = (LPVOID)ULongToPtr(IasValue.Enumerator);
  851. break;
  852. case IASTYPE_INET_ADDR:
  853. dwLength = sizeof( DWORD );
  854. pValue = (LPVOID)ULongToPtr(IasValue.InetAddr);
  855. break;
  856. case IASTYPE_STRING:
  857. if ( NULL != IasValue.String.pszAnsi )
  858. {
  859. dwLength = strlen( IasValue.String.pszAnsi );
  860. pValue = (LPVOID)( IasValue.String.pszAnsi );
  861. }
  862. else if ( NULL != IasValue.String.pszWide )
  863. {
  864. dwLength = wcslen( IasValue.String.pszWide );
  865. pValue = (LPVOID)( IasValue.String.pszWide );
  866. fConvertToAnsi = TRUE;
  867. }
  868. else
  869. {
  870. continue;
  871. }
  872. break;
  873. case IASTYPE_OCTET_STRING:
  874. dwLength = IasValue.OctetString.dwLength;
  875. pValue = IasValue.OctetString.lpValue;
  876. break;
  877. default:
  878. continue;
  879. }
  880. dwRetCode =
  881. RasAuthAttributeInsert(
  882. dwIndex,
  883. *ppOutAttributes,
  884. (ppOutIasAttributes[dwIndex])->dwId,
  885. fConvertToAnsi,
  886. dwLength,
  887. pValue );
  888. if ( dwRetCode != NO_ERROR )
  889. {
  890. break;
  891. }
  892. TRACE1( "Received attribute %d",
  893. (ppOutIasAttributes[dwIndex])->dwId );
  894. }
  895. RasAuthAttributesPrint( g_dwTraceIdNt, TRACE_NTAUTH,
  896. *ppOutAttributes );
  897. }
  898. } while( FALSE );
  899. //
  900. // Free all the IAS attributes allocated earlier
  901. //
  902. if ( ppInIasAttributes != NULL )
  903. {
  904. if(NO_ERROR == dwRetCode)
  905. {
  906. FreeAttributes( dwTotalInAttributeCount, ppInIasAttributes );
  907. }
  908. MemFreeIas( ppInIasAttributes );
  909. }
  910. if ( ppOutIasAttributes != NULL )
  911. {
  912. FreeAttributes( dwOutAttributeCount, ppOutIasAttributes );
  913. MemFreeIas( ppOutIasAttributes );
  914. }
  915. if ( dwRetCode != NO_ERROR )
  916. {
  917. if ( *ppOutAttributes != NULL )
  918. {
  919. RasAuthAttributeDestroy( *ppOutAttributes );
  920. *ppOutAttributes = NULL;
  921. }
  922. }
  923. CoUninitialize();
  924. return( dwRetCode );
  925. }
  926. //**
  927. //
  928. // Call: RasAuthProviderAuthenticateUser
  929. //
  930. // Returns: NO_ERROR - Success
  931. // Non-zero returns - Failure
  932. //
  933. // Description:
  934. //
  935. //
  936. DWORD APIENTRY
  937. RasAuthProviderAuthenticateUser(
  938. IN RAS_AUTH_ATTRIBUTE * pInAttributes,
  939. OUT PRAS_AUTH_ATTRIBUTE * ppOutAttributes,
  940. OUT DWORD * lpdwResultCode
  941. )
  942. {
  943. *ppOutAttributes = NULL;
  944. *lpdwResultCode = NO_ERROR;
  945. TRACE("RasAuthProviderAuthenticateUser called");
  946. return( IASSendReceiveAttributes( RAS_IAS_ACCESS_REQUEST,
  947. pInAttributes,
  948. ppOutAttributes,
  949. lpdwResultCode ) );
  950. }
  951. //**
  952. //
  953. // Call: RasAuthProviderFreeAttributes
  954. //
  955. // Returns: NO_ERROR - Success
  956. // Non-zero returns - Failure
  957. //
  958. // Description:
  959. //
  960. DWORD APIENTRY
  961. RasAuthProviderFreeAttributes(
  962. IN RAS_AUTH_ATTRIBUTE * pAttributes
  963. )
  964. {
  965. RasAuthAttributeDestroy( pAttributes );
  966. return( NO_ERROR );
  967. }
  968. //**
  969. //
  970. // Call: RasAcctProviderFreeAttributes
  971. //
  972. // Returns: NO_ERROR - Success
  973. // Non-zero returns - Failure
  974. //
  975. // Description:
  976. //
  977. DWORD APIENTRY
  978. RasAcctProviderFreeAttributes(
  979. IN RAS_AUTH_ATTRIBUTE * pAttributes
  980. )
  981. {
  982. RasAuthAttributeDestroy( pAttributes );
  983. return( NO_ERROR );
  984. }