Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1213 lines
25 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. api.c
  5. Abstract:
  6. This module contains exposed APIs that is used by the
  7. NetWare Control Panel Applet.
  8. Author:
  9. Yi-Hsin Sung 15-Jul-1993
  10. Revision History:
  11. ChuckC 23-Jul-93 Completed the stubs
  12. --*/
  13. #include <nwclient.h>
  14. #include <nwcanon.h>
  15. #include <validc.h>
  16. #include <nwdlg.h>
  17. #include <nwreg.h>
  18. #include <nwapi.h>
  19. #include <ntddnwfs.h>
  20. //Multi-User code merge
  21. DWORD
  22. NwpCitrixGetUserInfo(
  23. LPWSTR *ppszUserSid
  24. );
  25. //
  26. // forward declare
  27. //
  28. DWORD
  29. NwpGetCurrentUserRegKey(
  30. IN DWORD DesiredAccess,
  31. OUT HKEY *phKeyCurrentUser
  32. );
  33. DWORD
  34. NwQueryInfo(
  35. OUT PDWORD pnPrintOptions,
  36. OUT LPWSTR *ppszPreferredSrv
  37. )
  38. /*++
  39. Routine Description:
  40. This routine gets the user's preferred server and print options from
  41. the registry.
  42. Arguments:
  43. pnPrintOptions - Receives the user's print option
  44. ppszPreferredSrv - Receives the user's preferred server
  45. Return Value:
  46. Returns the appropriate Win32 error.
  47. --*/
  48. {
  49. HKEY hKeyCurrentUser = NULL;
  50. DWORD BufferSize;
  51. DWORD BytesNeeded;
  52. DWORD PrintOption;
  53. DWORD ValueType;
  54. LPWSTR PreferredServer ;
  55. DWORD err ;
  56. //
  57. // get to right place in registry and allocate dthe buffer
  58. //
  59. if (err = NwpGetCurrentUserRegKey( KEY_READ, &hKeyCurrentUser))
  60. {
  61. //
  62. // If somebody mess around with the registry and we can't find
  63. // the registry, just use the defaults.
  64. //
  65. *ppszPreferredSrv = NULL;
  66. *pnPrintOptions = NW_PRINT_OPTION_DEFAULT;
  67. return NO_ERROR;
  68. }
  69. BufferSize = sizeof(WCHAR) * (MAX_PATH + 2) ;
  70. PreferredServer = (LPWSTR) LocalAlloc(LPTR, BufferSize) ;
  71. if (!PreferredServer)
  72. return (GetLastError()) ;
  73. //
  74. // Read PreferredServer value into Buffer.
  75. //
  76. BytesNeeded = BufferSize ;
  77. err = RegQueryValueExW( hKeyCurrentUser,
  78. NW_SERVER_VALUENAME,
  79. NULL,
  80. &ValueType,
  81. (LPBYTE) PreferredServer,
  82. &BytesNeeded );
  83. if (err != NO_ERROR)
  84. {
  85. //
  86. // set to empty and carry on
  87. //
  88. PreferredServer[0] = 0;
  89. }
  90. //
  91. // Read PrintOption value into PrintOption.
  92. //
  93. BytesNeeded = sizeof(PrintOption);
  94. err = RegQueryValueExW( hKeyCurrentUser,
  95. NW_PRINTOPTION_VALUENAME,
  96. NULL,
  97. &ValueType,
  98. (LPBYTE) &PrintOption,
  99. &BytesNeeded );
  100. if (err != NO_ERROR)
  101. {
  102. //
  103. // set to default and carry on
  104. //
  105. PrintOption = NW_PRINT_OPTION_DEFAULT;
  106. }
  107. if (hKeyCurrentUser != NULL)
  108. (void) RegCloseKey(hKeyCurrentUser) ;
  109. *ppszPreferredSrv = PreferredServer ;
  110. *pnPrintOptions = PrintOption ;
  111. return NO_ERROR ;
  112. }
  113. DWORD
  114. NwSetInfoInRegistry(
  115. IN DWORD nPrintOptions,
  116. IN LPWSTR pszPreferredSrv
  117. )
  118. /*++
  119. Routine Description:
  120. This routine set the user's print option and preferred server into
  121. the registry.
  122. Arguments:
  123. nPrintOptions - Supplies the print option.
  124. pszPreferredSrv - Supplies the preferred server.
  125. Return Value:
  126. Returns the appropriate Win32 error.
  127. --*/
  128. {
  129. HKEY hKeyCurrentUser = NULL;
  130. DWORD err = NwpGetCurrentUserRegKey( KEY_SET_VALUE,
  131. &hKeyCurrentUser );
  132. if (err != NO_ERROR)
  133. return err;
  134. err = RegSetValueEx(hKeyCurrentUser,
  135. NW_SERVER_VALUENAME,
  136. 0,
  137. REG_SZ,
  138. (CONST BYTE *)pszPreferredSrv,
  139. (wcslen(pszPreferredSrv)+1) * sizeof(WCHAR)) ;
  140. if (err != NO_ERROR)
  141. {
  142. if (hKeyCurrentUser != NULL)
  143. (void) RegCloseKey(hKeyCurrentUser) ;
  144. return err;
  145. }
  146. err = RegSetValueEx(hKeyCurrentUser,
  147. NW_PRINTOPTION_VALUENAME,
  148. 0,
  149. REG_DWORD,
  150. (CONST BYTE *)&nPrintOptions,
  151. sizeof(nPrintOptions)) ;
  152. if (hKeyCurrentUser != NULL)
  153. (void) RegCloseKey(hKeyCurrentUser) ;
  154. return err;
  155. }
  156. DWORD
  157. NwQueryLogonOptions(
  158. OUT PDWORD pnLogonScriptOptions
  159. )
  160. /*++
  161. Routine Description:
  162. This routine gets the user's Logon script options from the registry.
  163. Arguments:
  164. pnLogonScriptOptions - Receives the user's Logon script options
  165. Return Value:
  166. Returns the appropriate Win32 error.
  167. --*/
  168. {
  169. HKEY hKeyCurrentUser;
  170. DWORD BytesNeeded;
  171. DWORD LogonScriptOption;
  172. DWORD ValueType;
  173. DWORD err ;
  174. //
  175. // get to right place in registry and allocate the buffer
  176. //
  177. if (err = NwpGetCurrentUserRegKey( KEY_READ, &hKeyCurrentUser))
  178. {
  179. //
  180. // If somebody mess around with the registry and we can't find
  181. // the registry, assume no.
  182. //
  183. *pnLogonScriptOptions = NW_LOGONSCRIPT_DEFAULT ;
  184. return NO_ERROR;
  185. }
  186. //
  187. // Read LogonScriptOption value into LogonScriptOption.
  188. //
  189. BytesNeeded = sizeof(LogonScriptOption);
  190. err = RegQueryValueExW( hKeyCurrentUser,
  191. NW_LOGONSCRIPT_VALUENAME,
  192. NULL,
  193. &ValueType,
  194. (LPBYTE) &LogonScriptOption,
  195. &BytesNeeded );
  196. if (err != NO_ERROR)
  197. {
  198. //
  199. // default to nothing and carry on
  200. //
  201. LogonScriptOption = NW_LOGONSCRIPT_DEFAULT;
  202. }
  203. *pnLogonScriptOptions = LogonScriptOption ;
  204. return NO_ERROR ;
  205. }
  206. DWORD
  207. NwSetLogonOptionsInRegistry(
  208. IN DWORD nLogonScriptOptions
  209. )
  210. /*++
  211. Routine Description:
  212. This routine set the logon script options in the registry.
  213. Arguments:
  214. nLogonScriptOptions - Supplies the logon options
  215. Return Value:
  216. Returns the appropriate Win32 error.
  217. --*/
  218. {
  219. HKEY hKeyCurrentUser;
  220. DWORD err = NwpGetCurrentUserRegKey( KEY_SET_VALUE,
  221. &hKeyCurrentUser );
  222. if (err != NO_ERROR)
  223. return err;
  224. err = RegSetValueEx(hKeyCurrentUser,
  225. NW_LOGONSCRIPT_VALUENAME,
  226. 0,
  227. REG_DWORD,
  228. (CONST BYTE *)&nLogonScriptOptions,
  229. sizeof(nLogonScriptOptions)) ;
  230. (void) RegCloseKey( hKeyCurrentUser );
  231. return err;
  232. }
  233. DWORD
  234. NwSetInfoInWksta(
  235. IN DWORD nPrintOption,
  236. IN LPWSTR pszPreferredSrv
  237. )
  238. /*++
  239. Routine Description:
  240. This routine notifies the workstation service and the redirector
  241. about the user's new print option and preferred server.
  242. Arguments:
  243. nPrintOptions - Supplies the print option.
  244. pszPreferredSrv - Supplies the preferred server.
  245. Return Value:
  246. Returns the appropriate Win32 error.
  247. --*/
  248. {
  249. DWORD err;
  250. RpcTryExcept {
  251. err = NwrSetInfo( NULL, nPrintOption, pszPreferredSrv );
  252. }
  253. RpcExcept(1) {
  254. err = NwpMapRpcError(RpcExceptionCode());
  255. }
  256. RpcEndExcept
  257. return err;
  258. }
  259. DWORD
  260. NwSetLogonScript(
  261. IN DWORD ScriptOptions
  262. )
  263. /*++
  264. Routine Description:
  265. This routine notifies the workstation service of login script
  266. options.
  267. Arguments:
  268. ScriptOptions - Supplies the options.
  269. Return Value:
  270. Returns the appropriate Win32 error.
  271. --*/
  272. {
  273. DWORD err;
  274. RpcTryExcept {
  275. err = NwrSetLogonScript( NULL, ScriptOptions );
  276. }
  277. RpcExcept(1) {
  278. err = NwpMapRpcError(RpcExceptionCode());
  279. }
  280. RpcEndExcept
  281. return err;
  282. }
  283. DWORD
  284. NwValidateUser(
  285. IN LPWSTR pszPreferredSrv
  286. )
  287. /*++
  288. Routine Description:
  289. This routine checks to see if the user can be authenticated on the
  290. chosen preferred server.
  291. Arguments:
  292. pszPreferredSrv - Supplies the preferred server name.
  293. Return Value:
  294. Returns the appropriate Win32 error.
  295. --*/
  296. {
  297. DWORD err;
  298. //
  299. // Don't need to validate if the preferred server is NULL or empty string
  300. //
  301. if ( ( pszPreferredSrv == NULL )
  302. || ( *pszPreferredSrv == 0 )
  303. )
  304. {
  305. return NO_ERROR;
  306. }
  307. //
  308. // See if the name contains any invalid characters
  309. //
  310. if ( !IS_VALID_SERVER_TOKEN( pszPreferredSrv, wcslen( pszPreferredSrv )))
  311. return ERROR_INVALID_NAME;
  312. RpcTryExcept {
  313. err = NwrValidateUser( NULL, pszPreferredSrv );
  314. }
  315. RpcExcept(1) {
  316. err = NwpMapRpcError( RpcExceptionCode() );
  317. }
  318. RpcEndExcept
  319. return err;
  320. }
  321. DWORD
  322. NwpGetCurrentUserRegKey(
  323. IN DWORD DesiredAccess,
  324. OUT HKEY *phKeyCurrentUser
  325. )
  326. /*++
  327. Routine Description:
  328. This routine opens the current user's registry key under
  329. \HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NWCWorkstation\Parameters
  330. Arguments:
  331. DesiredAccess - The access mask to open the key with
  332. phKeyCurrentUser - Receives the opened key handle
  333. Return Value:
  334. Returns the appropriate Win32 error.
  335. --*/
  336. {
  337. DWORD err;
  338. HKEY hkeyWksta;
  339. LPWSTR CurrentUser;
  340. //
  341. // Open HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services
  342. // \NWCWorkstation\Parameters
  343. //
  344. err = RegOpenKeyExW(
  345. HKEY_LOCAL_MACHINE,
  346. NW_WORKSTATION_REGKEY,
  347. REG_OPTION_NON_VOLATILE,
  348. KEY_READ,
  349. &hkeyWksta
  350. );
  351. if ( err ) {
  352. KdPrint(("NWPROVAU: NwGetCurrentUserRegKey open Parameters key unexpected error %lu!\n", err));
  353. return err;
  354. }
  355. // -- MultiUser code merge ----
  356. // Get the current user's SID string
  357. // DON'T look in the registry. This thread should be owned by the
  358. // user.
  359. //
  360. CurrentUser = NULL;
  361. err = NwpCitrixGetUserInfo( &CurrentUser );
  362. if ( err ) {
  363. KdPrint(("NWPROVAU: NwGetCurrentUserRegKey get CurrentUser SID unexpected error %lu!\n", err));
  364. (void) RegCloseKey( hkeyWksta );
  365. return err;
  366. }
  367. //
  368. // Get the current user's SID string.
  369. //
  370. //err = NwReadRegValue(
  371. // hkeyWksta,
  372. // NW_CURRENTUSER_VALUENAME,
  373. // &CurrentUser
  374. // );
  375. if ( err ) {
  376. KdPrint(("NWPROVAU: NwGetCurrentUserRegKey read CurrentUser value unexpected error %lu!\n", err));
  377. (void) RegCloseKey( hkeyWksta );
  378. return err;
  379. }
  380. (void) RegCloseKey( hkeyWksta );
  381. //
  382. // Open HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services
  383. // \NWCWorkstation\Parameters\Option
  384. //
  385. err = RegOpenKeyExW(
  386. HKEY_LOCAL_MACHINE,
  387. NW_WORKSTATION_OPTION_REGKEY,
  388. REG_OPTION_NON_VOLATILE,
  389. KEY_READ,
  390. &hkeyWksta
  391. );
  392. if ( err ) {
  393. KdPrint(("NWPROVAU: NwGetCurrentUserRegKey open Parameters\\Option key unexpected error %lu!\n", err));
  394. return err;
  395. }
  396. //
  397. // Open current user's key
  398. //
  399. err = RegOpenKeyExW(
  400. hkeyWksta,
  401. CurrentUser,
  402. REG_OPTION_NON_VOLATILE,
  403. DesiredAccess,
  404. phKeyCurrentUser
  405. );
  406. if ( err == ERROR_FILE_NOT_FOUND)
  407. {
  408. DWORD Disposition;
  409. //
  410. // Create <NewUser> key under NWCWorkstation\Parameters\Option
  411. //
  412. err = RegCreateKeyExW(
  413. hkeyWksta,
  414. CurrentUser,
  415. 0,
  416. WIN31_CLASS,
  417. REG_OPTION_NON_VOLATILE,
  418. DesiredAccess,
  419. NULL, // security attr
  420. phKeyCurrentUser,
  421. &Disposition
  422. );
  423. if ( err == NO_ERROR )
  424. {
  425. err = NwLibSetEverybodyPermission( *phKeyCurrentUser,
  426. KEY_SET_VALUE );
  427. if ( err != NO_ERROR )
  428. {
  429. KdPrint(("NWPROVAU: NwpSaveLogonCredential set security on Option\\%ws key unexpected error %lu!\n", CurrentUser, err));
  430. }
  431. }
  432. }
  433. if ( err ) {
  434. KdPrint(("NWPROVAU: NwGetCurrentUserRegKey open or create of Parameters\\Option\\%ws key failed %lu\n", CurrentUser, err));
  435. }
  436. (void) RegCloseKey( hkeyWksta );
  437. (void) LocalFree((HLOCAL)CurrentUser) ;
  438. return err;
  439. }
  440. DWORD
  441. NwEnumGWDevices(
  442. LPDWORD Index,
  443. LPBYTE Buffer,
  444. DWORD BufferSize,
  445. LPDWORD BytesNeeded,
  446. LPDWORD EntriesRead
  447. )
  448. /*++
  449. Routine Description:
  450. This routine enumerates the special gateway devices (redirections)
  451. that are cureently in use.
  452. Arguments:
  453. Index - Point to start enumeration. Should be zero for first call.
  454. Buffer - buffer for return data
  455. BufferSize - size of buffer in bytes
  456. BytesNeeded - number of bytes needed to return all the data
  457. EntriesRead - number of entries read
  458. Return Value:
  459. Returns the appropriate Win32 error.
  460. --*/
  461. {
  462. DWORD i, err ;
  463. LPNETRESOURCE lpNetRes = (LPNETRESOURCE) Buffer ;
  464. //
  465. // call the implementing routine on server side
  466. //
  467. RpcTryExcept {
  468. err = NwrEnumGWDevices( NULL,
  469. Index,
  470. Buffer,
  471. BufferSize,
  472. BytesNeeded,
  473. EntriesRead) ;
  474. if ( err == NO_ERROR)
  475. {
  476. //
  477. // the change the offsets into real pointers
  478. //
  479. for (i = 0; i < *EntriesRead; i++)
  480. {
  481. lpNetRes->lpLocalName =
  482. (LPWSTR) (Buffer+(DWORD_PTR)lpNetRes->lpLocalName) ;
  483. lpNetRes->lpRemoteName =
  484. (LPWSTR) (Buffer+(DWORD_PTR)lpNetRes->lpRemoteName) ;
  485. lpNetRes->lpProvider =
  486. (LPWSTR) (Buffer+(DWORD_PTR)lpNetRes->lpProvider) ;
  487. lpNetRes++ ;
  488. }
  489. }
  490. }
  491. RpcExcept(1) {
  492. err = NwpMapRpcError( RpcExceptionCode() );
  493. }
  494. RpcEndExcept
  495. return err ;
  496. }
  497. DWORD
  498. NwAddGWDevice(
  499. LPWSTR DeviceName,
  500. LPWSTR RemoteName,
  501. LPWSTR AccountName,
  502. LPWSTR Password,
  503. DWORD Flags
  504. )
  505. /*++
  506. Routine Description:
  507. This routine adds a gateway redirection.
  508. Arguments:
  509. DeviceName - the drive to redirect
  510. RemoteName - the remote network resource to redirect to
  511. Flags - supplies the options (eg. UpdateRegistry & make this sticky)
  512. Return Value:
  513. Returns the appropriate Win32 error.
  514. --*/
  515. {
  516. DWORD err;
  517. RpcTryExcept {
  518. err = NwrAddGWDevice( NULL,
  519. DeviceName,
  520. RemoteName,
  521. AccountName,
  522. Password,
  523. Flags) ;
  524. }
  525. RpcExcept(1) {
  526. err = NwpMapRpcError( RpcExceptionCode() );
  527. }
  528. RpcEndExcept
  529. return err;
  530. }
  531. DWORD
  532. NwDeleteGWDevice(
  533. LPWSTR DeviceName,
  534. DWORD Flags
  535. )
  536. /*++
  537. Routine Description:
  538. This routine deletes a gateway redirection.
  539. Arguments:
  540. DeviceName - the drive to delete
  541. Flags - supplies the options (eg. UpdateRegistry & make this sticky)
  542. Return Value:
  543. Returns the appropriate Win32 error.
  544. --*/
  545. {
  546. DWORD err;
  547. RpcTryExcept {
  548. err = NwrDeleteGWDevice(NULL, DeviceName, Flags) ;
  549. }
  550. RpcExcept(1) {
  551. err = NwpMapRpcError( RpcExceptionCode() );
  552. }
  553. RpcEndExcept
  554. return err;
  555. }
  556. DWORD
  557. NwQueryGatewayAccount(
  558. LPWSTR AccountName,
  559. DWORD AccountNameLen,
  560. LPDWORD AccountCharsNeeded,
  561. LPWSTR Password,
  562. DWORD PasswordLen,
  563. LPDWORD PasswordCharsNeeded
  564. )
  565. /*++
  566. Routine Description:
  567. Query the gateway account info. specifically, the Account name and
  568. the passeord stored as an LSA secret.
  569. Arguments:
  570. AccountName - buffer used to return account name
  571. AccountNameLen - length of buffer
  572. Password - buffer used to return account name
  573. PasswordLen - length of buffer
  574. Return Value:
  575. Returns the appropriate Win32 error.
  576. --*/
  577. {
  578. DWORD err;
  579. RpcTryExcept {
  580. if (AccountName && AccountNameLen)
  581. *AccountName = 0 ;
  582. if (Password && PasswordLen)
  583. *Password = 0 ;
  584. err = NwrQueryGatewayAccount(NULL,
  585. AccountName,
  586. AccountNameLen,
  587. AccountCharsNeeded,
  588. Password,
  589. PasswordLen,
  590. PasswordCharsNeeded) ;
  591. }
  592. RpcExcept(1) {
  593. err = NwpMapRpcError( RpcExceptionCode() );
  594. }
  595. RpcEndExcept
  596. return err;
  597. }
  598. DWORD
  599. NwSetGatewayAccount(
  600. LPWSTR AccountName,
  601. LPWSTR Password
  602. )
  603. /*++
  604. Routine Description:
  605. Set the account and password to be used for gateway access.
  606. Arguments:
  607. AccountName - the account (NULL terminated)
  608. Password - the password string (NULL terminated)
  609. Return Value:
  610. Returns the appropriate Win32 error.
  611. --*/
  612. {
  613. DWORD err;
  614. RpcTryExcept {
  615. err = NwrSetGatewayAccount( NULL,
  616. AccountName,
  617. Password);
  618. }
  619. RpcExcept(1) {
  620. err = NwpMapRpcError( RpcExceptionCode() );
  621. }
  622. RpcEndExcept
  623. return err;
  624. }
  625. DWORD
  626. NwLogonGatewayAccount(
  627. LPWSTR AccountName,
  628. LPWSTR Password,
  629. LPWSTR Server
  630. )
  631. /*++
  632. Routine Description:
  633. Logon the SYSTEM process with the specified account/password.
  634. Arguments:
  635. AccountName - the account (NULL terminated)
  636. Password - the password string (NULL terminated)
  637. Server - the server to authenticate against
  638. Return Value:
  639. Returns the appropriate Win32 error.
  640. --*/
  641. {
  642. DWORD err ;
  643. LUID SystemId = SYSTEM_LUID ;
  644. RpcTryExcept {
  645. (void) NwrLogoffUser(NULL, &SystemId);
  646. err = NwrLogonUser( NULL,
  647. &SystemId,
  648. AccountName,
  649. Password,
  650. Server,
  651. NULL,
  652. NULL,
  653. 0,
  654. NW_GATEWAY_PRINT_OPTION_DEFAULT
  655. );
  656. }
  657. RpcExcept(1) {
  658. err = NwpMapRpcError( RpcExceptionCode() );
  659. }
  660. RpcEndExcept
  661. return err ;
  662. }
  663. NTSTATUS
  664. NwGetUserNameForServer(
  665. PUNICODE_STRING ServerName,
  666. PUNICODE_STRING UserName
  667. )
  668. /*++
  669. Routine Description:
  670. Calls the redir to get the User Name used to connect to the server
  671. in question.
  672. Arguments:
  673. ServerName - the server in question
  674. UserName - used to return the user name
  675. Return Value:
  676. Returns the appropriate NTSTATUS
  677. --*/
  678. {
  679. NTSTATUS Status;
  680. WCHAR LocalUserName[NW_MAX_USERNAME_LEN];
  681. ULONG UserNameLen = sizeof(LocalUserName);
  682. OBJECT_ATTRIBUTES ObjectAttributes;
  683. UNICODE_STRING DriverName;
  684. HANDLE RdrHandle = NULL;
  685. IO_STATUS_BLOCK IoStatus;
  686. //
  687. // Initialize variables
  688. //
  689. RtlInitUnicodeString( &DriverName, DD_NWFS_DEVICE_NAME_U );
  690. InitializeObjectAttributes(
  691. &ObjectAttributes,
  692. &DriverName,
  693. 0,
  694. NULL,
  695. NULL
  696. );
  697. //
  698. // open handle to the redir
  699. //
  700. Status = NtOpenFile(
  701. &RdrHandle,
  702. FILE_LIST_DIRECTORY | SYNCHRONIZE,
  703. &ObjectAttributes,
  704. &IoStatus,
  705. FILE_SHARE_READ,
  706. 0 // open options
  707. );
  708. if (!NT_SUCCESS(Status) ||
  709. !NT_SUCCESS(IoStatus.Status) )
  710. {
  711. return( Status );
  712. }
  713. //
  714. // Call the driver to get use the user name
  715. //
  716. Status = NtFsControlFile(
  717. RdrHandle,
  718. NULL,
  719. NULL,
  720. NULL,
  721. &IoStatus,
  722. FSCTL_NWR_GET_USERNAME,
  723. ServerName->Buffer,
  724. ServerName->Length,
  725. LocalUserName,
  726. UserNameLen
  727. );
  728. NtClose(RdrHandle);
  729. if (!NT_SUCCESS(Status))
  730. {
  731. return(Status);
  732. }
  733. //
  734. // copy the info if it fits. set size required and fail otherwise.
  735. //
  736. if (UserName->MaximumLength >= IoStatus.Information)
  737. {
  738. UserName->Length = (USHORT) IoStatus.Information;
  739. RtlCopyMemory( UserName->Buffer,
  740. LocalUserName,
  741. UserNameLen );
  742. Status = STATUS_SUCCESS;
  743. }
  744. else
  745. {
  746. UserName->Length = (USHORT) IoStatus.Information;
  747. Status = STATUS_BUFFER_TOO_SMALL;
  748. }
  749. return(Status);
  750. }
  751. NTSTATUS
  752. NwEncryptChallenge(
  753. IN PUCHAR Challenge,
  754. IN ULONG ObjectId,
  755. IN OPTIONAL PUNICODE_STRING ServerName,
  756. IN OPTIONAL PUNICODE_STRING Password,
  757. OUT PUCHAR ChallengeResponse,
  758. OUT OPTIONAL PUCHAR SessionKey
  759. )
  760. /*++
  761. Routine Description:
  762. Calls the redir to encrypt a challenge
  763. Arguments:
  764. Challenge - Challenge key
  765. ObjectId - User's object ID
  766. ServerName - The server to authenticate against
  767. Password - Password supplied
  768. ChallengeResponse - Used to return the challenge response
  769. SessionKey - Used to return the session key
  770. Return Value:
  771. Returns the appropriate NTSTATUS
  772. --*/
  773. {
  774. NTSTATUS Status;
  775. OBJECT_ATTRIBUTES ObjectAttributes;
  776. UNICODE_STRING DriverName;
  777. HANDLE RdrHandle = NULL;
  778. IO_STATUS_BLOCK IoStatus;
  779. PNWR_GET_CHALLENGE_REQUEST ChallengeRequest = NULL;
  780. NWR_GET_CHALLENGE_REPLY ChallengeReply;
  781. ULONG ChallengeRequestSize;
  782. //
  783. // Initialize variables
  784. //
  785. RtlInitUnicodeString( &DriverName, DD_NWFS_DEVICE_NAME_U );
  786. InitializeObjectAttributes(
  787. &ObjectAttributes,
  788. &DriverName,
  789. 0,
  790. NULL,
  791. NULL
  792. );
  793. //
  794. // open handle to redirector
  795. //
  796. Status = NtOpenFile(
  797. &RdrHandle,
  798. FILE_LIST_DIRECTORY | SYNCHRONIZE,
  799. &ObjectAttributes,
  800. &IoStatus,
  801. FILE_SHARE_READ,
  802. 0 // open options
  803. );
  804. if (!NT_SUCCESS(Status) ||
  805. !NT_SUCCESS(IoStatus.Status) )
  806. {
  807. return( Status );
  808. }
  809. ChallengeRequestSize = sizeof(NWR_GET_CHALLENGE_REQUEST) +
  810. ((Password != NULL) ? Password->Length : 0) +
  811. ((ServerName != NULL) ? ServerName->Length : 0);
  812. ChallengeRequest = (PNWR_GET_CHALLENGE_REQUEST) RtlAllocateHeap(
  813. RtlProcessHeap(),
  814. 0,
  815. ChallengeRequestSize
  816. );
  817. if (ChallengeRequest == NULL )
  818. {
  819. Status = STATUS_INSUFFICIENT_RESOURCES;
  820. goto Cleanup;
  821. }
  822. //
  823. // Marshall the challenge request structure. Only send servername if
  824. // password has not been specified.
  825. //
  826. ChallengeRequest->ObjectId = ObjectId;
  827. ChallengeRequest->Flags = 0;
  828. //
  829. // If both password and servername are present, use the password.
  830. //
  831. if ((Password != NULL) && (Password->Length != 0))
  832. {
  833. ChallengeRequest->ServerNameorPasswordLength = Password->Length;
  834. RtlCopyMemory(
  835. ChallengeRequest->ServerNameorPassword,
  836. Password->Buffer,
  837. Password->Length
  838. );
  839. ChallengeRequest->Flags = CHALLENGE_FLAGS_PASSWORD;
  840. }
  841. else if ((ServerName != NULL) && (ServerName->Length != 0))
  842. {
  843. ChallengeRequest->ServerNameorPasswordLength = ServerName->Length;
  844. RtlCopyMemory(
  845. ChallengeRequest->ServerNameorPassword,
  846. ServerName->Buffer,
  847. ServerName->Length
  848. );
  849. ChallengeRequest->Flags = CHALLENGE_FLAGS_SERVERNAME;
  850. }
  851. RtlCopyMemory(
  852. ChallengeRequest->Challenge,
  853. Challenge,
  854. 8
  855. );
  856. //
  857. // Issue FS control to redir to get challenge response
  858. //
  859. Status = NtFsControlFile(
  860. RdrHandle,
  861. NULL,
  862. NULL,
  863. NULL,
  864. &IoStatus,
  865. FSCTL_NWR_CHALLENGE,
  866. ChallengeRequest,
  867. ChallengeRequestSize,
  868. &ChallengeReply,
  869. sizeof(ChallengeReply)
  870. );
  871. if (!NT_SUCCESS(Status) || !NT_SUCCESS(IoStatus.Status)) {
  872. goto Cleanup;
  873. }
  874. RtlCopyMemory(
  875. ChallengeResponse,
  876. ChallengeReply.Challenge,
  877. 8
  878. );
  879. if (SessionKey != NULL)
  880. {
  881. RtlCopyMemory(
  882. ChallengeResponse,
  883. ChallengeReply.Challenge,
  884. 8
  885. );
  886. }
  887. Cleanup:
  888. if (RdrHandle != NULL)
  889. {
  890. NtClose(RdrHandle);
  891. }
  892. if (ChallengeRequest != NULL)
  893. {
  894. RtlFreeHeap(
  895. RtlProcessHeap(),
  896. 0,
  897. ChallengeRequest
  898. );
  899. }
  900. return(Status);
  901. }