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.

732 lines
20 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. msv1_0.c
  5. Abstract:
  6. MSV1_0 authentication package.
  7. The name of this authentication package is:
  8. Author:
  9. Jim Kelly 11-Apr-1991
  10. Revision History:
  11. Scott Field (sfield) 15-Jan-98 Add MspNtDeriveCredential
  12. Chandana Surlu 21-Jul-96 Stolen from \\kernel\razzle3\src\security\msv1_0\msv1_0.c
  13. --*/
  14. #include <global.h>
  15. #include "msp.h"
  16. #include "nlp.h"
  17. //
  18. // LsaApCallPackage() function dispatch table
  19. //
  20. PLSA_AP_CALL_PACKAGE
  21. MspCallPackageDispatch[] = {
  22. MspLm20Challenge,
  23. MspLm20GetChallengeResponse,
  24. MspLm20EnumUsers,
  25. MspLm20GetUserInfo,
  26. MspLm20ReLogonUsers,
  27. MspLm20ChangePassword,
  28. MspLm20ChangePassword,
  29. MspLm20GenericPassthrough,
  30. MspLm20CacheLogon,
  31. MspNtSubAuth,
  32. MspNtDeriveCredential,
  33. MspLm20CacheLookup,
  34. MspSetProcessOption
  35. };
  36. ///////////////////////////////////////////////////////////////////////
  37. // //
  38. // Authentication package dispatch routines. //
  39. // //
  40. ///////////////////////////////////////////////////////////////////////
  41. NTSTATUS
  42. LsaApInitializePackage (
  43. IN ULONG AuthenticationPackageId,
  44. IN PLSA_DISPATCH_TABLE LsaDispatchTable,
  45. IN PSTRING Database OPTIONAL,
  46. IN PSTRING Confidentiality OPTIONAL,
  47. OUT PSTRING *AuthenticationPackageName
  48. )
  49. /*++
  50. Routine Description:
  51. This service is called once by the LSA during system initialization to
  52. provide the DLL a chance to initialize itself.
  53. Arguments:
  54. AuthenticationPackageId - The ID assigned to the authentication
  55. package.
  56. LsaDispatchTable - Provides the address of a table of LSA
  57. services available to authentication packages. The services
  58. of this table are ordered according to the enumerated type
  59. LSA_DISPATCH_TABLE_API.
  60. Database - This parameter is not used by this authentication package.
  61. Confidentiality - This parameter is not used by this authentication
  62. package.
  63. AuthenticationPackageName - Recieves the name of the
  64. authentication package. The authentication package is
  65. responsible for allocating the buffer that the string is in
  66. (using the AllocateLsaHeap() service) and returning its
  67. address here. The buffer will be deallocated by LSA when it
  68. is no longer needed.
  69. Return Value:
  70. STATUS_SUCCESS - Indicates the service completed successfully.
  71. --*/
  72. {
  73. PSTRING NameString;
  74. PCHAR NameBuffer;
  75. NTSTATUS Status;
  76. //
  77. // If we haven't already initialized the internals, do it now.
  78. //
  79. if (!NlpMsvInitialized) {
  80. //
  81. // Save our assigned authentication package ID.
  82. //
  83. MspAuthenticationPackageId = AuthenticationPackageId;
  84. //
  85. // Copy the LSA service dispatch table
  86. // the LsaDispatchTable is actually a LSA_SECPKG_FUNCTION_TABLE
  87. // in Win2k and beyond.
  88. //
  89. CopyMemory( &Lsa, LsaDispatchTable, sizeof( Lsa ) );
  90. //
  91. // Initialize the change password log.
  92. //
  93. MsvPaswdInitializeLog();
  94. //
  95. // Initialize netlogon
  96. //
  97. Status = NlInitialize();
  98. if ( !NT_SUCCESS( Status ) ) {
  99. SspPrint((SSP_CRITICAL,"Error from NlInitialize = %d\n", Status));
  100. return Status;
  101. }
  102. NlpMsvInitialized = TRUE;
  103. }
  104. //
  105. // Allocate and return our package name
  106. //
  107. if (ARGUMENT_PRESENT(AuthenticationPackageName))
  108. {
  109. NameBuffer = (*(Lsa.AllocateLsaHeap))(sizeof(MSV1_0_PACKAGE_NAME));
  110. if (!NameBuffer)
  111. {
  112. Status = STATUS_INSUFFICIENT_RESOURCES;
  113. SspPrint((SSP_CRITICAL, "Error from Lsa.AllocateLsaHeap\n"));
  114. return Status;
  115. }
  116. strcpy( NameBuffer, MSV1_0_PACKAGE_NAME);
  117. NameString = (*(Lsa.AllocateLsaHeap))( (ULONG)sizeof(STRING) );
  118. if (!NameString)
  119. {
  120. Status = STATUS_INSUFFICIENT_RESOURCES;
  121. SspPrint((SSP_CRITICAL, "Error from Lsa.AllocateLsaHeap\n"));
  122. return Status;
  123. }
  124. RtlInitString( NameString, NameBuffer );
  125. (*AuthenticationPackageName) = NameString;
  126. }
  127. RtlInitUnicodeString(
  128. &NlpMsv1_0PackageName,
  129. TEXT(MSV1_0_PACKAGE_NAME)
  130. );
  131. return STATUS_SUCCESS;
  132. //
  133. // Appease the compiler gods by referencing all arguments
  134. //
  135. UNREFERENCED_PARAMETER(Confidentiality);
  136. UNREFERENCED_PARAMETER(Database);
  137. }
  138. NTSTATUS
  139. LsaApCallPackage (
  140. IN PLSA_CLIENT_REQUEST ClientRequest,
  141. IN PVOID ProtocolSubmitBuffer,
  142. IN PVOID ClientBufferBase,
  143. IN ULONG SubmitBufferLength,
  144. OUT PVOID *ProtocolReturnBuffer,
  145. OUT PULONG ReturnBufferLength,
  146. OUT PNTSTATUS ProtocolStatus
  147. )
  148. /*++
  149. Routine Description:
  150. This routine is the dispatch routine for
  151. LsaCallAuthenticationPackage().
  152. Arguments:
  153. ClientRequest - Is a pointer to an opaque data structure
  154. representing the client's request.
  155. ProtocolSubmitBuffer - Supplies a protocol message specific to
  156. the authentication package.
  157. ClientBufferBase - Provides the address within the client
  158. process at which the protocol message was resident.
  159. This may be necessary to fix-up any pointers within the
  160. protocol message buffer.
  161. SubmitBufferLength - Indicates the length of the submitted
  162. protocol message buffer.
  163. ProtocolReturnBuffer - Is used to return the address of the
  164. protocol buffer in the client process. The authentication
  165. package is responsible for allocating and returning the
  166. protocol buffer within the client process. This buffer is
  167. expected to have been allocated with the
  168. AllocateClientBuffer() service.
  169. The format and semantics of this buffer are specific to the
  170. authentication package.
  171. ReturnBufferLength - Receives the length (in bytes) of the
  172. returned protocol buffer.
  173. ProtocolStatus - Assuming the services completion is
  174. STATUS_SUCCESS, this parameter will receive completion status
  175. returned by the specified authentication package. The list
  176. of status values that may be returned are authentication
  177. package specific.
  178. Return Status:
  179. STATUS_SUCCESS - The call was made to the authentication package.
  180. The ProtocolStatus parameter must be checked to see what the
  181. completion status from the authentication package is.
  182. STATUS_QUOTA_EXCEEDED - This error indicates that the return
  183. buffer could not could not be allocated because the client
  184. does not have sufficient quota.
  185. --*/
  186. {
  187. ULONG MessageType;
  188. #if _WIN64
  189. SECPKG_CALL_INFO CallInfo;
  190. #endif // _WIN64
  191. //
  192. // Get the messsage type from the protocol submit buffer.
  193. //
  194. if ( SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE) ) {
  195. return STATUS_INVALID_PARAMETER;
  196. }
  197. MessageType =
  198. (ULONG) *((PMSV1_0_PROTOCOL_MESSAGE_TYPE)(ProtocolSubmitBuffer));
  199. if ( MessageType >=
  200. (sizeof(MspCallPackageDispatch)/sizeof(MspCallPackageDispatch[0])) ) {
  201. return STATUS_INVALID_PARAMETER;
  202. }
  203. #if _WIN64
  204. if( ClientRequest != (PLSA_CLIENT_REQUEST)(-1) )
  205. {
  206. //
  207. // Only supported CallPackage level for WOW64 callers is password change.
  208. //
  209. if (!LsaFunctions->GetCallInfo(&CallInfo))
  210. {
  211. return STATUS_INTERNAL_ERROR;
  212. }
  213. if ( (CallInfo.Attributes & SECPKG_CALL_WOWCLIENT) &&
  214. ((CallInfo.Attributes & SECPKG_CALL_IN_PROC) == 0))
  215. {
  216. switch (MessageType)
  217. {
  218. case MsV1_0ChangePassword:
  219. case MsV1_0GenericPassthrough:
  220. {
  221. break;
  222. }
  223. default:
  224. {
  225. return STATUS_NOT_SUPPORTED;
  226. }
  227. }
  228. }
  229. }
  230. #endif // _WIN64
  231. //
  232. // Allow the dispatch routines to only set the return buffer information
  233. // on success conditions.
  234. //
  235. *ProtocolReturnBuffer = NULL;
  236. *ReturnBufferLength = 0;
  237. //
  238. // Call the appropriate routine for this message.
  239. //
  240. return (*(MspCallPackageDispatch[MessageType]))(
  241. ClientRequest,
  242. ProtocolSubmitBuffer,
  243. ClientBufferBase,
  244. SubmitBufferLength,
  245. ProtocolReturnBuffer,
  246. ReturnBufferLength,
  247. ProtocolStatus ) ;
  248. }
  249. NTSTATUS
  250. LsaApCallPackageUntrusted (
  251. IN PLSA_CLIENT_REQUEST ClientRequest,
  252. IN PVOID ProtocolSubmitBuffer,
  253. IN PVOID ClientBufferBase,
  254. IN ULONG SubmitBufferLength,
  255. OUT PVOID *ProtocolReturnBuffer,
  256. OUT PULONG ReturnBufferLength,
  257. OUT PNTSTATUS ProtocolStatus
  258. )
  259. /*++
  260. Routine Description:
  261. This routine is the dispatch routine for
  262. LsaCallAuthenticationPackage() for untrusted clients.
  263. Arguments:
  264. ClientRequest - Is a pointer to an opaque data structure
  265. representing the client's request.
  266. ProtocolSubmitBuffer - Supplies a protocol message specific to
  267. the authentication package.
  268. ClientBufferBase - Provides the address within the client
  269. process at which the protocol message was resident.
  270. This may be necessary to fix-up any pointers within the
  271. protocol message buffer.
  272. SubmitBufferLength - Indicates the length of the submitted
  273. protocol message buffer.
  274. ProtocolReturnBuffer - Is used to return the address of the
  275. protocol buffer in the client process. The authentication
  276. package is responsible for allocating and returning the
  277. protocol buffer within the client process. This buffer is
  278. expected to have been allocated with the
  279. AllocateClientBuffer() service.
  280. The format and semantics of this buffer are specific to the
  281. authentication package.
  282. ReturnBufferLength - Receives the length (in bytes) of the
  283. returned protocol buffer.
  284. ProtocolStatus - Assuming the services completion is
  285. STATUS_SUCCESS, this parameter will receive completion status
  286. returned by the specified authentication package. The list
  287. of status values that may be returned are authentication
  288. package specific.
  289. Return Status:
  290. STATUS_SUCCESS - The call was made to the authentication package.
  291. The ProtocolStatus parameter must be checked to see what the
  292. completion status from the authentication package is.
  293. STATUS_QUOTA_EXCEEDED - This error indicates that the return
  294. buffer could not could not be allocated because the client
  295. does not have sufficient quota.
  296. --*/
  297. {
  298. ULONG MessageType;
  299. NTSTATUS Status;
  300. #if _WIN64
  301. SECPKG_CALL_INFO CallInfo;
  302. #endif // _WIN64
  303. //
  304. // Get the messsage type from the protocol submit buffer.
  305. //
  306. if ( SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE) ) {
  307. return STATUS_INVALID_PARAMETER;
  308. }
  309. MessageType =
  310. (ULONG) *((PMSV1_0_PROTOCOL_MESSAGE_TYPE)(ProtocolSubmitBuffer));
  311. if ( MessageType >=
  312. (sizeof(MspCallPackageDispatch)/sizeof(MspCallPackageDispatch[0])) ) {
  313. return STATUS_INVALID_PARAMETER;
  314. }
  315. //
  316. // Allow an service to call the DeriveCredential function if the
  317. // request specifies the same logon id as the service.
  318. //
  319. if ((MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType == MsV1_0DeriveCredential)
  320. {
  321. PMSV1_0_DERIVECRED_REQUEST DeriveCredRequest;
  322. SECPKG_CLIENT_INFO ClientInfo;
  323. LUID SystemId = SYSTEM_LUID;
  324. Status = LsaFunctions->GetClientInfo(&ClientInfo);
  325. if(!NT_SUCCESS(Status))
  326. {
  327. return Status;
  328. }
  329. if ( SubmitBufferLength < sizeof(MSV1_0_DERIVECRED_REQUEST) ) {
  330. return STATUS_INVALID_PARAMETER;
  331. }
  332. DeriveCredRequest = (PMSV1_0_DERIVECRED_REQUEST) ProtocolSubmitBuffer;
  333. if(!RtlEqualLuid(&ClientInfo.LogonId, &DeriveCredRequest->LogonId))
  334. {
  335. return STATUS_ACCESS_DENIED;
  336. }
  337. if(RtlEqualLuid(&ClientInfo.LogonId, &SystemId))
  338. {
  339. return STATUS_ACCESS_DENIED;
  340. }
  341. }
  342. //
  343. // Allow an untrusted client to call the SetProcessOption function if
  344. // the DISABLE_FORCE_GUEST or ALLOW_OLD_PASSWORD option is set.
  345. //
  346. if ((MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType == MsV1_0SetProcessOption)
  347. {
  348. PMSV1_0_SETPROCESSOPTION_REQUEST ProcessOptionRequest;
  349. ULONG ValidOptions;
  350. if ( SubmitBufferLength < sizeof(MSV1_0_SETPROCESSOPTION_REQUEST) ) {
  351. return STATUS_INVALID_PARAMETER;
  352. }
  353. ProcessOptionRequest = (PMSV1_0_SETPROCESSOPTION_REQUEST) ProtocolSubmitBuffer;
  354. ValidOptions = MSV1_0_OPTION_DISABLE_FORCE_GUEST |
  355. MSV1_0_OPTION_ALLOW_OLD_PASSWORD |
  356. MSV1_0_OPTION_TRY_CACHE_FIRST ;
  357. if( ProcessOptionRequest->ProcessOptions & ~ValidOptions )
  358. {
  359. return STATUS_ACCESS_DENIED;
  360. }
  361. }
  362. //
  363. // let DeriveCredential and SetProcessOption requests through if the caller is a service.
  364. //
  365. if ((MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType == MsV1_0DeriveCredential ||
  366. (MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType == MsV1_0SetProcessOption ||
  367. (MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType == MsV1_0ChangeCachedPassword
  368. )
  369. {
  370. BOOL IsMember = FALSE;
  371. PSID pServiceSid = NULL;
  372. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  373. Status = LsaFunctions->ImpersonateClient();
  374. if (NT_SUCCESS(Status))
  375. {
  376. if (AllocateAndInitializeSid( &siaNtAuthority,
  377. 1,
  378. SECURITY_SERVICE_RID,
  379. 0, 0, 0, 0, 0, 0, 0,
  380. &pServiceSid ))
  381. {
  382. if (!CheckTokenMembership(NULL, pServiceSid, &IsMember))
  383. {
  384. IsMember = FALSE;
  385. }
  386. FreeSid(pServiceSid);
  387. }
  388. RevertToSelf();
  389. }
  390. else
  391. {
  392. return Status;
  393. }
  394. if (!IsMember)
  395. {
  396. return STATUS_ACCESS_DENIED;
  397. }
  398. }
  399. //
  400. // Untrusted clients are only allowed to call a few of the functions.
  401. //
  402. if ((MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0ChangePassword &&
  403. (MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0DeriveCredential &&
  404. (MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0SetProcessOption &&
  405. (MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0Lm20ChallengeRequest &&
  406. (MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0ChangeCachedPassword
  407. ) {
  408. return STATUS_ACCESS_DENIED;
  409. }
  410. #if _WIN64
  411. //
  412. // Only supported CallPackage level for WOW64 callers is password change.
  413. //
  414. if (!LsaFunctions->GetCallInfo(&CallInfo))
  415. {
  416. return STATUS_INTERNAL_ERROR;
  417. }
  418. if ((CallInfo.Attributes & SECPKG_CALL_WOWCLIENT)
  419. &&
  420. ((MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0ChangePassword))
  421. {
  422. return STATUS_NOT_SUPPORTED;
  423. }
  424. #endif // _WIN64
  425. //
  426. // Allow the dispatch routines to only set the return buffer information
  427. // on success conditions.
  428. //
  429. *ProtocolReturnBuffer = NULL;
  430. *ReturnBufferLength = 0;
  431. //
  432. // Call the appropriate routine for this message.
  433. //
  434. return (*(MspCallPackageDispatch[MessageType]))(
  435. ClientRequest,
  436. ProtocolSubmitBuffer,
  437. ClientBufferBase,
  438. SubmitBufferLength,
  439. ProtocolReturnBuffer,
  440. ReturnBufferLength,
  441. ProtocolStatus ) ;
  442. }
  443. NTSTATUS
  444. LsaApCallPackagePassthrough (
  445. IN PLSA_CLIENT_REQUEST ClientRequest,
  446. IN PVOID ProtocolSubmitBuffer,
  447. IN PVOID ClientBufferBase,
  448. IN ULONG SubmitBufferLength,
  449. OUT PVOID *ProtocolReturnBuffer,
  450. OUT PULONG ReturnBufferLength,
  451. OUT PNTSTATUS ProtocolStatus
  452. )
  453. /*++
  454. Routine Description:
  455. This routine is the dispatch routine for
  456. LsaCallAuthenticationPackage() for passthrough logon requests.
  457. Arguments:
  458. ClientRequest - Is a pointer to an opaque data structure
  459. representing the client's request.
  460. ProtocolSubmitBuffer - Supplies a protocol message specific to
  461. the authentication package.
  462. ClientBufferBase - Provides the address within the client
  463. process at which the protocol message was resident.
  464. This may be necessary to fix-up any pointers within the
  465. protocol message buffer.
  466. SubmitBufferLength - Indicates the length of the submitted
  467. protocol message buffer.
  468. ProtocolReturnBuffer - Is used to return the address of the
  469. protocol buffer in the client process. The authentication
  470. package is responsible for allocating and returning the
  471. protocol buffer within the client process. This buffer is
  472. expected to have been allocated with the
  473. AllocateClientBuffer() service.
  474. The format and semantics of this buffer are specific to the
  475. authentication package.
  476. ReturnBufferLength - Receives the length (in bytes) of the
  477. returned protocol buffer.
  478. ProtocolStatus - Assuming the services completion is
  479. STATUS_SUCCESS, this parameter will receive completion status
  480. returned by the specified authentication package. The list
  481. of status values that may be returned are authentication
  482. package specific.
  483. Return Status:
  484. STATUS_SUCCESS - The call was made to the authentication package.
  485. The ProtocolStatus parameter must be checked to see what the
  486. completion status from the authentication package is.
  487. STATUS_QUOTA_EXCEEDED - This error indicates that the return
  488. buffer could not could not be allocated because the client
  489. does not have sufficient quota.
  490. --*/
  491. {
  492. ULONG MessageType;
  493. //
  494. // Get the messsage type from the protocol submit buffer.
  495. //
  496. if ( SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE) ) {
  497. return STATUS_INVALID_PARAMETER;
  498. }
  499. MessageType =
  500. (ULONG) *((PMSV1_0_PROTOCOL_MESSAGE_TYPE)(ProtocolSubmitBuffer));
  501. if ( MessageType >=
  502. (sizeof(MspCallPackageDispatch)/sizeof(MspCallPackageDispatch[0])) ) {
  503. return STATUS_INVALID_PARAMETER;
  504. }
  505. //
  506. // clients are only allowed to call the SubAuthLogon function.
  507. //
  508. if ((MSV1_0_PROTOCOL_MESSAGE_TYPE) MessageType != MsV1_0SubAuth) {
  509. return STATUS_ACCESS_DENIED;
  510. }
  511. //
  512. // Allow the dispatch routines to only set the return buffer information
  513. // on success conditions.
  514. //
  515. *ProtocolReturnBuffer = NULL;
  516. *ReturnBufferLength = 0;
  517. //
  518. // Call the appropriate routine for this message.
  519. //
  520. return (*(MspCallPackageDispatch[MessageType]))(
  521. ClientRequest,
  522. ProtocolSubmitBuffer,
  523. ClientBufferBase,
  524. SubmitBufferLength,
  525. ProtocolReturnBuffer,
  526. ReturnBufferLength,
  527. ProtocolStatus ) ;
  528. }