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.

768 lines
23 KiB

  1. /*++
  2. Copyright (c) 1991-92 Microsoft Corporation
  3. Module Name:
  4. logonapi.c
  5. Abstract:
  6. This module contains the Netlogon API RPC client stubs.
  7. Author:
  8. Cliff Van Dyke (CliffV) 27-Jun-1991
  9. [Environment:]
  10. User Mode - Win32
  11. Revision History:
  12. 27-Jun-1991 CliffV
  13. Created
  14. --*/
  15. //
  16. // INCLUDES
  17. //
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <rpc.h>
  21. #include <ntrpcp.h> // needed by rpcasync.h
  22. #include <rpcasync.h> // I_RpcExceptionFilter
  23. #include <logon_c.h>// includes lmcons.h, lmaccess.h, netlogon.h, ssi.h, windef.h
  24. #include <crypt.h> // Encryption routines.
  25. #include <debuglib.h> // IF_DEBUG()
  26. #include <lmerr.h> // NERR_ and ERROR_ equates.
  27. #include <netdebug.h> // NetpKdPrint
  28. NET_API_STATUS NET_API_FUNCTION
  29. I_NetLogonUasLogon (
  30. IN LPWSTR UserName,
  31. IN LPWSTR Workstation,
  32. OUT PNETLOGON_VALIDATION_UAS_INFO *ValidationInformation
  33. )
  34. /*++
  35. Routine Description:
  36. This function is called by the XACT server when processing a
  37. I_NetWkstaUserLogon XACT SMB. This feature allows a UAS client to
  38. logon to a SAM domain controller.
  39. Arguments:
  40. UserName -- Account name of the user logging on.
  41. Workstation -- The workstation from which the user is logging on.
  42. ValidationInformation -- Returns the requested validation
  43. information.
  44. Return Value:
  45. NERR_SUCCESS if there was no error. Otherwise, the error code is
  46. returned.
  47. --*/
  48. {
  49. NET_API_STATUS NetStatus;
  50. LPWSTR ServerName = NULL; // Not supported remotely
  51. //
  52. // Do the RPC call with an exception handler since RPC will raise an
  53. // exception if anything fails. It is up to us to figure out what
  54. // to do once the exception is raised.
  55. //
  56. RpcTryExcept {
  57. *ValidationInformation = NULL; // Force RPC to allocate
  58. //
  59. // Call RPC version of the API.
  60. //
  61. NetStatus = NetrLogonUasLogon(
  62. (LPWSTR) ServerName,
  63. UserName,
  64. Workstation,
  65. ValidationInformation );
  66. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  67. NetStatus = RpcExceptionCode();
  68. } RpcEndExcept;
  69. IF_DEBUG( LOGON ) {
  70. NetpKdPrint(("NetrLogonUasLogon rc = %lu 0x%lx\n",
  71. NetStatus, NetStatus));
  72. }
  73. return NetStatus;
  74. }
  75. NET_API_STATUS
  76. I_NetLogonUasLogoff (
  77. IN LPWSTR UserName,
  78. IN LPWSTR Workstation,
  79. OUT PNETLOGON_LOGOFF_UAS_INFO LogoffInformation
  80. )
  81. /*++
  82. Routine Description:
  83. This function is called by the XACT server when processing a
  84. I_NetWkstaUserLogoff XACT SMB. This feature allows a UAS client to
  85. logoff from a SAM domain controller. The request is authenticated,
  86. the entry is removed for this user from the logon session table
  87. maintained by the Netlogon service for NetLogonEnum, and logoff
  88. information is returned to the caller.
  89. The server portion of I_NetLogonUasLogoff (in the Netlogon service)
  90. compares the user name and workstation name specified in the
  91. LogonInformation with the user name and workstation name from the
  92. impersonation token. If they don't match, I_NetLogonUasLogoff fails
  93. indicating the access is denied.
  94. Group SECURITY_LOCAL is refused access to this function. Membership
  95. in SECURITY_LOCAL implies that this call was made locally and not
  96. through the XACT server.
  97. The Netlogon service cannot be sure that this function was called by
  98. the XACT server. Therefore, the Netlogon service will not simply
  99. delete the entry from the logon session table. Rather, the logon
  100. session table entry will be marked invisible outside of the Netlogon
  101. service (i.e., it will not be returned by NetLogonEnum) until a valid
  102. LOGON_WKSTINFO_RESPONSE is received for the entry. The Netlogon
  103. service will immediately interrogate the client (as described above
  104. for LOGON_WKSTINFO_RESPONSE) and temporarily increase the
  105. interrogation frequency to at least once a minute. The logon session
  106. table entry will reappear as soon as a function of interrogation if
  107. this isn't a true logoff request.
  108. Arguments:
  109. UserName -- Account name of the user logging off.
  110. Workstation -- The workstation from which the user is logging
  111. off.
  112. LogoffInformation -- Returns the requested logoff information.
  113. Return Value:
  114. The Net status code.
  115. --*/
  116. {
  117. NET_API_STATUS NetStatus;
  118. LPWSTR ServerName = NULL; // Not supported remotely
  119. //
  120. // Do the RPC call with an exception handler since RPC will raise an
  121. // exception if anything fails. It is up to us to figure out what
  122. // to do once the exception is raised.
  123. //
  124. RpcTryExcept {
  125. //
  126. // Call RPC version of the API.
  127. //
  128. NetStatus = NetrLogonUasLogoff(
  129. (LPWSTR) ServerName,
  130. UserName,
  131. Workstation,
  132. LogoffInformation );
  133. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  134. NetStatus = RpcExceptionCode();
  135. } RpcEndExcept;
  136. IF_DEBUG( LOGON ) {
  137. NetpKdPrint(("NetrLogonUasLogoff rc = %lu 0x%lx\n",
  138. NetStatus, NetStatus));
  139. }
  140. return NetStatus;
  141. }
  142. NTSTATUS
  143. I_NetLogonSamLogon (
  144. IN LPWSTR LogonServer OPTIONAL,
  145. IN LPWSTR ComputerName OPTIONAL,
  146. IN PNETLOGON_AUTHENTICATOR Authenticator OPTIONAL,
  147. OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator OPTIONAL,
  148. IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
  149. IN LPBYTE LogonInformation,
  150. IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
  151. OUT LPBYTE * ValidationInformation,
  152. OUT PBOOLEAN Authoritative
  153. )
  154. /*++
  155. Routine Description:
  156. This function is called by an NT client to process an interactive or
  157. network logon. This function passes a domain name, user name and
  158. credentials to the Netlogon service and returns information needed to
  159. build a token. It is called in three instances:
  160. * It is called by the LSA's MSV1_0 authentication package for any
  161. NT system that has LanMan installed. The MSV1_0 authentication
  162. package calls SAM directly if LanMan is not installed. In this
  163. case, this function is a local function and requires the caller
  164. to have SE_TCB privilege. The local Netlogon service will
  165. either handle this request directly (validating the request with
  166. the local SAM database) or will forward this request to the
  167. appropriate domain controller as documented in sections 2.4 and
  168. 2.5.
  169. * It is called by a Netlogon service on a workstation to a DC in
  170. the Primary Domain of the workstation as documented in section
  171. 2.4. In this case, this function uses a secure channel set up
  172. between the two Netlogon services.
  173. * It is called by a Netlogon service on a DC to a DC in a trusted
  174. domain as documented in section 2.5. In this case, this
  175. function uses a secure channel set up between the two Netlogon
  176. services.
  177. The Netlogon service validates the specified credentials. If they
  178. are valid, adds an entry for this LogonId, UserName, and Workstation
  179. into the logon session table. The entry is added to the logon
  180. session table only in the domain defining the specified user's
  181. account.
  182. This service is also used to process a re-logon request.
  183. Arguments:
  184. LogonServer -- Supplies the name of the logon server to process
  185. this logon request. This field should be null to indicate
  186. this is a call from the MSV1_0 authentication package to the
  187. local Netlogon service.
  188. ComputerName -- Name of the machine making the call. This field
  189. should be null to indicate this is a call from the MSV1_0
  190. authentication package to the local Netlogon service.
  191. Authenticator -- supplied by the client. This field should be
  192. null to indicate this is a call from the MSV1_0
  193. authentication package to the local Netlogon service.
  194. ReturnAuthenticator -- Receives an authenticator returned by the
  195. server. This field should be null to indicate this is a call
  196. from the MSV1_0 authentication package to the local Netlogon
  197. service.
  198. LogonLevel -- Specifies the level of information given in
  199. LogonInformation.
  200. LogonInformation -- Specifies the description for the user
  201. logging on.
  202. ValidationLevel -- Specifies the level of information returned in
  203. ValidationInformation. Must be NetlogonValidationSamInformation.
  204. ValidationInformation -- Returns the requested validation
  205. information.
  206. Authoritative -- Returns whether the status returned is an
  207. authoritative status which should be returned to the original
  208. caller. If not, this logon request may be tried again on another
  209. domain controller. This parameter is returned regardless of the
  210. status code.
  211. Return Value:
  212. STATUS_SUCCESS: if there was no error.
  213. STATUS_NO_LOGON_SERVERS -- Either Pass-thru authentication or
  214. Trusted Domain Authentication could not contact the requested
  215. Domain Controller.
  216. STATUS_INVALID_INFO_CLASS -- Either LogonLevel or ValidationLevel is
  217. invalid.
  218. STATUS_INVALID_PARAMETER -- Another Parameter is invalid.
  219. STATUS_ACCESS_DENIED -- The caller does not have access to call this
  220. API.
  221. STATUS_NO_SUCH_USER -- Indicates that the user specified in
  222. LogonInformation does not exist. This status should not be returned
  223. to the originally caller. It should be mapped to STATUS_LOGON_FAILURE.
  224. STATUS_WRONG_PASSWORD -- Indicates that the password information in
  225. LogonInformation was incorrect. This status should not be returned
  226. to the originally caller. It should be mapped to STATUS_LOGON_FAILURE.
  227. STATUS_INVALID_LOGON_HOURES -- The user is not authorized to logon
  228. at this time.
  229. STATUS_INVALID_WORKSTATION -- The user is not authorized to logon
  230. from the specified workstation.
  231. STATUS_PASSWORD_EXPIRED -- The password for the user has expired.
  232. STATUS_ACCOUNT_DISABLED -- The user's account has been disabled.
  233. .
  234. .
  235. .
  236. --*/
  237. {
  238. NTSTATUS Status = STATUS_SUCCESS;
  239. NETLOGON_LEVEL RpcLogonInformation;
  240. NETLOGON_VALIDATION RpcValidationInformation;
  241. //
  242. // Do the RPC call with an exception handler since RPC will raise an
  243. // exception if anything fails. It is up to us to figure out what
  244. // to do once the exception is raised.
  245. //
  246. RpcTryExcept {
  247. //
  248. // Call RPC version of the API.
  249. //
  250. RpcLogonInformation.LogonInteractive =
  251. (PNETLOGON_INTERACTIVE_INFO) LogonInformation;
  252. RpcValidationInformation.ValidationSam = NULL;
  253. Status = NetrLogonSamLogon(
  254. LogonServer,
  255. ComputerName,
  256. Authenticator,
  257. ReturnAuthenticator,
  258. LogonLevel,
  259. &RpcLogonInformation,
  260. ValidationLevel,
  261. &RpcValidationInformation,
  262. Authoritative );
  263. *ValidationInformation = (LPBYTE)
  264. RpcValidationInformation.ValidationSam;
  265. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  266. *Authoritative = TRUE;
  267. Status = I_RpcMapWin32Status(RpcExceptionCode());
  268. } RpcEndExcept;
  269. IF_DEBUG( LOGON ) {
  270. NetpKdPrint(("I_NetLogonSamLogon rc = %lu 0x%lx\n", Status, Status));
  271. }
  272. return Status;
  273. }
  274. NTSTATUS
  275. I_NetLogonSamLogonWithFlags (
  276. IN LPWSTR LogonServer OPTIONAL,
  277. IN LPWSTR ComputerName OPTIONAL,
  278. IN PNETLOGON_AUTHENTICATOR Authenticator OPTIONAL,
  279. OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator OPTIONAL,
  280. IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
  281. IN LPBYTE LogonInformation,
  282. IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
  283. OUT LPBYTE * ValidationInformation,
  284. OUT PBOOLEAN Authoritative,
  285. IN OUT PULONG ExtraFlags
  286. )
  287. /*++
  288. Routine Description:
  289. Flag version of I_NetLogonSamLogon.
  290. Arguments:
  291. Same as I_NetLogonSamLogon except:
  292. * ExtraFlags - Passes and returns a DWORD. For later expansion.
  293. Return Value:
  294. Same as I_NetLogonSamLogon.
  295. --*/
  296. {
  297. NTSTATUS Status = STATUS_SUCCESS;
  298. NETLOGON_LEVEL RpcLogonInformation;
  299. NETLOGON_VALIDATION RpcValidationInformation;
  300. //
  301. // Do the RPC call with an exception handler since RPC will raise an
  302. // exception if anything fails. It is up to us to figure out what
  303. // to do once the exception is raised.
  304. //
  305. RpcTryExcept {
  306. //
  307. // Call RPC version of the API.
  308. //
  309. RpcLogonInformation.LogonInteractive =
  310. (PNETLOGON_INTERACTIVE_INFO) LogonInformation;
  311. RpcValidationInformation.ValidationSam = NULL;
  312. Status = NetrLogonSamLogonWithFlags(
  313. LogonServer,
  314. ComputerName,
  315. Authenticator,
  316. ReturnAuthenticator,
  317. LogonLevel,
  318. &RpcLogonInformation,
  319. ValidationLevel,
  320. &RpcValidationInformation,
  321. Authoritative,
  322. ExtraFlags );
  323. *ValidationInformation = (LPBYTE)
  324. RpcValidationInformation.ValidationSam;
  325. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  326. *Authoritative = TRUE;
  327. Status = I_RpcMapWin32Status(RpcExceptionCode());
  328. } RpcEndExcept;
  329. IF_DEBUG( LOGON ) {
  330. NetpKdPrint(("I_NetLogonSamLogonWithFlags rc = %lu 0x%lx\n", Status, Status));
  331. }
  332. return Status;
  333. }
  334. NTSTATUS
  335. I_NetLogonSamLogonEx (
  336. IN PVOID ContextHandle,
  337. IN LPWSTR LogonServer OPTIONAL,
  338. IN LPWSTR ComputerName OPTIONAL,
  339. IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
  340. IN LPBYTE LogonInformation,
  341. IN NETLOGON_VALIDATION_INFO_CLASS ValidationLevel,
  342. OUT LPBYTE * ValidationInformation,
  343. OUT PBOOLEAN Authoritative,
  344. IN OUT PULONG ExtraFlags,
  345. OUT PBOOLEAN RpcFailed
  346. )
  347. /*++
  348. Routine Description:
  349. Concurrent API version of I_NetLogonSamLogon.
  350. Arguments:
  351. Same as I_NetLogonSamLogon except:
  352. * No authenticator parameters.
  353. * Context Handle parameter
  354. * ExtraFlags - Passes and returns a DWORD. For later expansion.
  355. Return Value:
  356. Same as I_NetLogonSamLogon.
  357. --*/
  358. {
  359. NTSTATUS Status = STATUS_SUCCESS;
  360. NETLOGON_LEVEL RpcLogonInformation;
  361. NETLOGON_VALIDATION RpcValidationInformation;
  362. *RpcFailed = FALSE;
  363. //
  364. // Do the RPC call with an exception handler since RPC will raise an
  365. // exception if anything fails. It is up to us to figure out what
  366. // to do once the exception is raised.
  367. //
  368. RpcTryExcept {
  369. //
  370. // Call RPC version of the API.
  371. //
  372. RpcLogonInformation.LogonInteractive =
  373. (PNETLOGON_INTERACTIVE_INFO) LogonInformation;
  374. RpcValidationInformation.ValidationSam = NULL;
  375. Status = NetrLogonSamLogonEx(
  376. ContextHandle,
  377. LogonServer,
  378. ComputerName,
  379. LogonLevel,
  380. &RpcLogonInformation,
  381. ValidationLevel,
  382. &RpcValidationInformation,
  383. Authoritative,
  384. ExtraFlags );
  385. *ValidationInformation = (LPBYTE)
  386. RpcValidationInformation.ValidationSam;
  387. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  388. *Authoritative = TRUE;
  389. *RpcFailed = TRUE;
  390. Status = I_RpcMapWin32Status(RpcExceptionCode());
  391. } RpcEndExcept;
  392. IF_DEBUG( LOGON ) {
  393. NetpKdPrint(("I_NetLogonSamLogonEx rc = %lu 0x%lx\n", Status, Status));
  394. }
  395. return Status;
  396. }
  397. NTSTATUS NET_API_FUNCTION
  398. I_NetLogonSamLogoff (
  399. IN LPWSTR LogonServer OPTIONAL,
  400. IN LPWSTR ComputerName OPTIONAL,
  401. IN PNETLOGON_AUTHENTICATOR Authenticator OPTIONAL,
  402. OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator OPTIONAL,
  403. IN NETLOGON_LOGON_INFO_CLASS LogonLevel,
  404. IN LPBYTE LogonInformation
  405. )
  406. /*++
  407. Routine Description:
  408. This function is called by an NT client to process an interactive
  409. logoff. It is not called for the network logoff case since the
  410. Netlogon service does not maintain any context for network logons.
  411. This function does the following. It authenticates the request. It
  412. updates the logon statistics in the SAM database on whichever machine
  413. or domain defines this user account. It updates the logon session
  414. table in the primary domain of the machine making the request. And
  415. it returns logoff information to the caller.
  416. This function is called in same scenarios that I_NetLogonSamLogon is
  417. called:
  418. * It is called by the LSA's MSV1_0 authentication package to
  419. support LsaApLogonTerminated. In this case, this function is a
  420. local function and requires the caller to have SE_TCB privilege.
  421. The local Netlogon service will either handle this request
  422. directly (if LogonDomainName indicates this request was
  423. validated locally) or will forward this request to the
  424. appropriate domain controller as documented in sections 2.4 and
  425. 2.5.
  426. * It is called by a Netlogon service on a workstation to a DC in
  427. the Primary Domain of the workstation as documented in section
  428. 2.4. In this case, this function uses a secure channel set up
  429. between the two Netlogon services.
  430. * It is called by a Netlogon service on a DC to a DC in a trusted
  431. domain as documented in section 2.5. In this case, this
  432. function uses a secure channel set up between the two Netlogon
  433. services.
  434. When this function is a remote function, it is sent to the DC over a
  435. NULL session.
  436. Arguments:
  437. LogonServer -- Supplies the name of the logon server which logged
  438. this user on. This field should be null to indicate this is
  439. a call from the MSV1_0 authentication package to the local
  440. Netlogon service.
  441. ComputerName -- Name of the machine making the call. This field
  442. should be null to indicate this is a call from the MSV1_0
  443. authentication package to the local Netlogon service.
  444. Authenticator -- supplied by the client. This field should be
  445. null to indicate this is a call from the MSV1_0
  446. authentication package to the local Netlogon service.
  447. ReturnAuthenticator -- Receives an authenticator returned by the
  448. server. This field should be null to indicate this is a call
  449. from the MSV1_0 authentication package to the local Netlogon
  450. service.
  451. LogonLevel -- Specifies the level of information given in
  452. LogonInformation.
  453. LogonInformation -- Specifies the logon domain name, logon Id,
  454. user name and workstation name of the user logging off.
  455. Return Value:
  456. --*/
  457. {
  458. NTSTATUS Status = STATUS_SUCCESS;
  459. NETLOGON_LEVEL RpcLogonInformation;
  460. //
  461. // Do the RPC call with an exception handler since RPC will raise an
  462. // exception if anything fails. It is up to us to figure out what
  463. // to do once the exception is raised.
  464. //
  465. RpcTryExcept {
  466. //
  467. // Call RPC version of the API.
  468. //
  469. RpcLogonInformation.LogonInteractive =
  470. (PNETLOGON_INTERACTIVE_INFO) LogonInformation;
  471. Status = NetrLogonSamLogoff(
  472. LogonServer,
  473. ComputerName,
  474. Authenticator,
  475. ReturnAuthenticator,
  476. LogonLevel,
  477. &RpcLogonInformation );
  478. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  479. Status = I_RpcMapWin32Status(RpcExceptionCode());
  480. } RpcEndExcept;
  481. IF_DEBUG( LOGON ) {
  482. NetpKdPrint(("I_NetLogonSamLogoff rc = %lu 0x%lx\n", Status, Status));
  483. }
  484. return Status;
  485. }
  486. NTSTATUS NET_API_FUNCTION
  487. I_NetLogonSendToSam (
  488. IN LPWSTR PrimaryName OPTIONAL,
  489. IN LPWSTR ComputerName,
  490. IN PNETLOGON_AUTHENTICATOR Authenticator,
  491. OUT PNETLOGON_AUTHENTICATOR ReturnAuthenticator,
  492. IN LPBYTE OpaqueBuffer,
  493. IN ULONG OpaqueBufferSize
  494. )
  495. /*++
  496. Routine Description:
  497. This function sends an opaque buffer from SAM on a BDC to SAM on the PDC.
  498. The original use of this routine will be to allow the BDC to forward user
  499. account password changes to the PDC.
  500. Arguments:
  501. PrimaryName -- Computer name of the PDC to remote the call to.
  502. ComputerName -- Name of the machine making the call.
  503. Authenticator -- supplied by the client.
  504. ReturnAuthenticator -- Receives an authenticator returned by the
  505. server.
  506. OpaqueBuffer - Buffer to be passed to the SAM service on the PDC.
  507. The buffer will be encrypted on the wire.
  508. OpaqueBufferSize - Size (in bytes) of OpaqueBuffer.
  509. Return Value:
  510. STATUS_SUCCESS: Message successfully sent to PDC
  511. STATUS_NO_MEMORY: There is not enough memory to complete the operation
  512. STATUS_NO_SUCH_DOMAIN: DomainName does not correspond to a hosted domain
  513. STATUS_NO_LOGON_SERVERS: PDC is not currently available
  514. STATUS_NOT_SUPPORTED: PDC does not support this operation
  515. --*/
  516. {
  517. NTSTATUS Status = STATUS_SUCCESS;
  518. //
  519. // Do the RPC call with an exception handler since RPC will raise an
  520. // exception if anything fails. It is up to us to figure out what
  521. // to do once the exception is raised.
  522. //
  523. RpcTryExcept {
  524. //
  525. // Call RPC version of the API.
  526. //
  527. Status = NetrLogonSendToSam(
  528. PrimaryName,
  529. ComputerName,
  530. Authenticator,
  531. ReturnAuthenticator,
  532. OpaqueBuffer,
  533. OpaqueBufferSize );
  534. } RpcExcept( I_RpcExceptionFilter(RpcExceptionCode()) ) {
  535. Status = I_RpcMapWin32Status(RpcExceptionCode());
  536. } RpcEndExcept;
  537. IF_DEBUG( LOGON ) {
  538. NetpKdPrint(("I_NetLogonSendToSam rc = %lu 0x%lx\n", Status, Status));
  539. }
  540. return Status;
  541. }