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.

1313 lines
36 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. ApiAcces.c
  5. Abstract:
  6. This module contains individual API handlers for the NetAccess APIs.
  7. SUPPORTED : NetAccessAdd, NetAccessDel, NetAccessEnum, NetAccessGetInfo,
  8. NetAccessGetUserPerms, NetAccessSetInfo.
  9. Author:
  10. Shanku Niyogi (w-shanku) 13-Mar-1991
  11. Revision History:
  12. --*/
  13. //
  14. // Access APIs are UNICODE only.
  15. //
  16. #ifndef UNICODE
  17. #define UNICODE
  18. #endif
  19. #include "xactsrvp.h"
  20. //
  21. // We do not support NetAccess apis from downlevel
  22. //
  23. #define RETURN_ACCESS_NOT_SUPPORTED \
  24. API_HANDLER_PARAMETERS_REFERENCE; \
  25. Header->Status = ERROR_NOT_SUPPORTED;
  26. #ifdef NET_ACCESS_SUPPORTED
  27. //
  28. // Declaration of descriptor strings.
  29. //
  30. STATIC const LPDESC Desc16_access_info_0 = REM16_access_info_0;
  31. STATIC const LPDESC Desc32_access_info_0 = REM32_access_info_0;
  32. STATIC const LPDESC Desc16_access_info_1 = REM16_access_info_1;
  33. STATIC const LPDESC Desc32_access_info_1 = REM32_access_info_1;
  34. STATIC const LPDESC Desc16_access_list = REM16_access_list;
  35. STATIC const LPDESC Desc32_access_list = REM32_access_list;
  36. STATIC NET_API_STATUS
  37. XsNetAccessEnumVerify (
  38. IN NET_API_STATUS ConvertStatus,
  39. IN PBYTE ConvertedEntry,
  40. IN PBYTE BaseAddress
  41. )
  42. /*++
  43. Routine Description:
  44. This function is called by XsFillEnumBuffer after each entry is
  45. converted, in order to determine whether the entry should be retained
  46. in the enum buffer or discarded.
  47. The access_info_1 entries contain a number of auxiliary structures.
  48. The limit in LanMan 2.0 for these is 64. This function makes sure that
  49. entries with more than 64 structures are not returned. Note that the
  50. number of entries is not truncated to 64; if this data is received and
  51. used for a SetInfo, 32-bit data will be irretrievably lost.
  52. Arguments:
  53. ConvertStatus - The return code from RapConvertSingleEntry.
  54. ConvertedEntry - The converted entry created by RapConvertSingleEntry.
  55. BaseAddress - A pointer to the base used to calculate offsets.
  56. Return Value:
  57. NET_API_STATUS - NERR_Success if the entry should be retained, or
  58. an error code if the entry should be discarded.
  59. --*/
  60. {
  61. PACCESS_16_INFO_1 acc = (PACCESS_16_INFO_1)ConvertedEntry;
  62. UNREFERENCED_PARAMETER(BaseAddress);
  63. //
  64. // If RapConvertSingleEntry failed, discard the entry.
  65. //
  66. if ( ConvertStatus != NERR_Success ) {
  67. return ConvertStatus;
  68. }
  69. //
  70. // If there are more than 64 entries, discard the entry.
  71. //
  72. if ( SmbGetUshort( &acc->acc1_count ) > 64 ) {
  73. IF_DEBUG(CONVERT) {
  74. NetpKdPrint(( "XsNetAccessEnumVerify: too many aux. entries\n" ));
  75. }
  76. return ERROR_MORE_DATA;
  77. } else {
  78. return NERR_Success;
  79. }
  80. }
  81. #endif // NET_ACCESS_SUPPORTED
  82. NTSTATUS
  83. XsNetAccessAdd (
  84. API_HANDLER_PARAMETERS
  85. )
  86. /*++
  87. Routine Description:
  88. This routine handles a call to NetAccessAdd.
  89. Arguments:
  90. API_HANDLER_PARAMETERS - information about the API call. See
  91. XsTypes.h for details.
  92. Return Value:
  93. NTSTATUS - STATUS_SUCCESS or reason for failure.
  94. --*/
  95. {
  96. #ifdef NET_ACCESS_SUPPORTED
  97. NET_API_STATUS status;
  98. PXS_NET_ACCESS_ADD parameters = Parameters;
  99. LPVOID buffer = NULL; // Native parameters
  100. LPBYTE stringLocation = NULL; // Conversion variables
  101. DWORD bytesRequired = 0;
  102. LPDESC longDescriptor = NULL;
  103. LPDESC longNativeDescriptor = NULL;
  104. DWORD auxDataCount;
  105. DWORD bufferSize;
  106. DWORD i;
  107. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  108. IF_DEBUG(ACCESS) {
  109. NetpKdPrint(( "XsNetAccessAdd: header at %lx, params at %lx, "
  110. "level %ld\n",
  111. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  112. }
  113. try {
  114. //
  115. // Check for errors.
  116. //
  117. if ( SmbGetUshort( &parameters->Level ) != 1 ) {
  118. Header->Status = (WORD)ERROR_INVALID_LEVEL;
  119. goto cleanup;
  120. }
  121. StructureDesc = Desc16_access_info_1;
  122. AuxStructureDesc = Desc16_access_list;
  123. //
  124. // Figure out if there is enough room in the buffer for the fixed
  125. // structure. If not, return NERR_BufTooSmall.
  126. //
  127. if ( !XsCheckBufferSize(
  128. SmbGetUshort( &parameters->BufLen ),
  129. StructureDesc,
  130. FALSE // not in native format
  131. )) {
  132. IF_DEBUG(ERRORS) {
  133. NetpKdPrint(( "XsNetAccessAdd: Buffer too small.\n" ));
  134. }
  135. Header->Status = NERR_BufTooSmall;
  136. goto cleanup;
  137. }
  138. //
  139. // Find the auxiliary data structure count, and form a long descriptor
  140. // string which can be used to do all the conversion in one pass.
  141. //
  142. auxDataCount = RapAuxDataCount(
  143. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  144. StructureDesc,
  145. Response,
  146. FALSE // not in native format
  147. );
  148. if ( auxDataCount > 64 ) {
  149. IF_DEBUG(ERRORS) {
  150. NetpKdPrint(( "XsNetAccessAdd: too many access_lists.\n" ));
  151. }
  152. Header->Status = NERR_ACFTooManyLists;
  153. goto cleanup;
  154. }
  155. longDescriptor = NetpMemoryAllocate(
  156. strlen( StructureDesc )
  157. + strlen( AuxStructureDesc ) * auxDataCount + 1 );
  158. longNativeDescriptor = NetpMemoryAllocate(
  159. strlen( Desc32_access_info_1 )
  160. + strlen( Desc32_access_list ) * auxDataCount
  161. + 1 );
  162. if (( longDescriptor == NULL ) || ( longNativeDescriptor == NULL )) {
  163. IF_DEBUG(ERRORS) {
  164. NetpKdPrint(( "XsNetAccessAdd: failed to allocate memory" ));
  165. }
  166. Header->Status = NERR_NoRoom;
  167. goto cleanup;
  168. }
  169. strcpy( longDescriptor, StructureDesc );
  170. strcpy( longNativeDescriptor, Desc32_access_info_1 );
  171. for ( i = 0; i < auxDataCount; i++ ) {
  172. strcat( longDescriptor, AuxStructureDesc );
  173. strcat( longNativeDescriptor, Desc32_access_list );
  174. }
  175. //
  176. // Figure out if there is enough room in the buffer for all this
  177. // data. If not, return NERR_BufTooSmall.
  178. //
  179. if ( !XsCheckBufferSize(
  180. SmbGetUshort( &parameters->BufLen ),
  181. longDescriptor,
  182. FALSE // not in native format
  183. )) {
  184. IF_DEBUG(ERRORS) {
  185. NetpKdPrint(( "XsNetAccessAdd: Buffer too small.\n" ));
  186. }
  187. Header->Status = NERR_BufTooSmall;
  188. goto cleanup;
  189. }
  190. //
  191. // Find out how big a buffer we need to allocate to hold the native
  192. // 32-bit version of the input data structure.
  193. //
  194. bufferSize = XsBytesForConvertedStructure(
  195. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  196. longDescriptor,
  197. longNativeDescriptor,
  198. RapToNative,
  199. TRUE
  200. );
  201. //
  202. // Allocate enough memory to hold the converted native buffer.
  203. //
  204. buffer = NetpMemoryAllocate( bufferSize );
  205. if ( buffer == NULL ) {
  206. IF_DEBUG(ERRORS) {
  207. NetpKdPrint(( "XsNetAccessAdd: failed to create buffer" ));
  208. }
  209. Header->Status = NERR_NoRoom;
  210. goto cleanup;
  211. }
  212. IF_DEBUG(ACCESS) {
  213. NetpKdPrint(( "XsNetAccessAdd: buffer of %ld bytes at %lx\n",
  214. bufferSize, buffer ));
  215. }
  216. //
  217. // Convert the buffer from 16-bit to 32-bit.
  218. //
  219. stringLocation = (LPBYTE)buffer + bufferSize;
  220. bytesRequired = 0;
  221. status = RapConvertSingleEntry(
  222. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  223. longDescriptor,
  224. TRUE,
  225. buffer,
  226. buffer,
  227. longNativeDescriptor,
  228. FALSE,
  229. &stringLocation,
  230. &bytesRequired,
  231. Response,
  232. RapToNative
  233. );
  234. if ( status != NERR_Success ) {
  235. IF_DEBUG(ERRORS) {
  236. NetpKdPrint(( "XsNetAccessAdd: RapConvertSingleEntry failed: "
  237. "%X\n", status ));
  238. }
  239. Header->Status = NERR_InternalError;
  240. goto cleanup;
  241. }
  242. //
  243. // Make the local call.
  244. //
  245. status = NetAccessAdd(
  246. NULL,
  247. (DWORD)SmbGetUshort( &parameters->Level ),
  248. buffer,
  249. NULL
  250. );
  251. if ( !XsApiSuccess( status )) {
  252. IF_DEBUG(ERRORS) {
  253. NetpKdPrint(( "XsNetAccessAdd: NetAccessAdd failed: "
  254. "%X\n", status ));
  255. }
  256. Header->Status = (WORD)status;
  257. goto cleanup;
  258. }
  259. //
  260. // There is no real return information for this API.
  261. //
  262. cleanup:
  263. } except( EXCEPTION_EXECUTE_HANDLER ) {
  264. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  265. }
  266. NetpMemoryFree( buffer );
  267. NetpMemoryFree( longDescriptor );
  268. NetpMemoryFree( longNativeDescriptor );
  269. #else // NET_ACCESS_SUPPORTED
  270. RETURN_ACCESS_NOT_SUPPORTED;
  271. #endif // NET_ACCESS_SUPPORTED
  272. return STATUS_SUCCESS;
  273. } // XsNetAccessAdd
  274. NTSTATUS
  275. XsNetAccessDel (
  276. API_HANDLER_PARAMETERS
  277. )
  278. /*++
  279. Routine Description:
  280. This routine handles a call to NetAccessDel.
  281. Arguments:
  282. API_HANDLER_PARAMETERS - information about the API call. See
  283. XsTypes.h for details.
  284. Return Value:
  285. NTSTATUS - STATUS_SUCCESS or reason for failure.
  286. --*/
  287. {
  288. #if NET_ACCESS_SUPPORTED
  289. NET_API_STATUS status;
  290. PXS_NET_ACCESS_DEL parameters = Parameters;
  291. LPTSTR nativeResource = NULL; // Native parameters
  292. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  293. IF_DEBUG(ACCESS) {
  294. NetpKdPrint(( "XsNetAccessDel: header at %lx, params at %lx, "
  295. "resource %s\n",
  296. Header, parameters, SmbGetUlong( &parameters->Resource )));
  297. }
  298. try {
  299. //
  300. // Translate parameters, check for errors.
  301. //
  302. XsConvertTextParameter(
  303. nativeResource,
  304. (LPSTR)SmbGetUlong( &parameters->Resource )
  305. );
  306. //
  307. // Make the local call.
  308. //
  309. status = NetAccessDel(
  310. NULL,
  311. nativeResource
  312. );
  313. if ( !XsApiSuccess( status )) {
  314. IF_DEBUG(ERRORS) {
  315. NetpKdPrint(( "XsNetAccessDel: NetAccessDel failed: "
  316. "%X\n", status ));
  317. }
  318. }
  319. cleanup:
  320. } except( EXCEPTION_EXECUTE_HANDLER ) {
  321. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  322. }
  323. NetpMemoryFree( nativeResource );
  324. //
  325. // Nothing to return.
  326. //
  327. Header->Status = (WORD)status;
  328. #else // NET_ACCESS_SUPPORTED
  329. RETURN_ACCESS_NOT_SUPPORTED;
  330. #endif // NET_ACCESS_SUPPORTED
  331. return STATUS_SUCCESS;
  332. } // XsNetAccessDel
  333. NTSTATUS
  334. XsNetAccessEnum (
  335. API_HANDLER_PARAMETERS
  336. )
  337. /*++
  338. Routine Description:
  339. This routine handles a call to NetAccessEnum.
  340. Arguments:
  341. API_HANDLER_PARAMETERS - information about the API call. See
  342. XsTypes.h for details.
  343. Return Value:
  344. NTSTATUS - STATUS_SUCCESS or reason for failure.
  345. --*/
  346. {
  347. #if NET_ACCESS_SUPPORTED
  348. NET_API_STATUS status;
  349. PXS_NET_ACCESS_ENUM parameters = Parameters;
  350. LPTSTR nativeBasePath = NULL; // Native parameters
  351. LPVOID outBuffer = NULL;
  352. DWORD entriesRead;
  353. DWORD totalEntries;
  354. DWORD entriesFilled = 0; // Conversion variables
  355. DWORD invalidEntries = 0;
  356. DWORD bytesRequired;
  357. LPDESC nativeStructureDesc;
  358. LPDESC nativeAuxStructureDesc;
  359. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  360. IF_DEBUG(ACCESS) {
  361. NetpKdPrint(( "XsNetAccessEnum: header at %lx, params at %lx, "
  362. "level %ld, buf size %ld\n",
  363. Header, parameters, SmbGetUshort( &parameters->Level ),
  364. SmbGetUshort( &parameters->BufLen )));
  365. }
  366. try {
  367. //
  368. // Translate parameters, and check for errors.
  369. //
  370. if ( XsWordParamOutOfRange( parameters->Level, 0, 1 )) {
  371. Header->Status = (WORD)ERROR_INVALID_LEVEL;
  372. goto cleanup;
  373. }
  374. XsConvertTextParameter(
  375. nativeBasePath,
  376. (LPSTR)SmbGetUlong( &parameters->BasePath )
  377. );
  378. //
  379. // Make the local 32-bit call.
  380. //
  381. status = NetAccessEnum(
  382. NULL,
  383. nativeBasePath,
  384. (DWORD)SmbGetUshort( &parameters->Recursive ),
  385. (DWORD)SmbGetUshort( &parameters->Level ),
  386. (LPBYTE *)&outBuffer,
  387. XsNativeBufferSize( SmbGetUshort( &parameters->BufLen )),
  388. &entriesRead,
  389. &totalEntries,
  390. NULL
  391. );
  392. if ( !XsApiSuccess( status )) {
  393. IF_DEBUG(API_ERRORS) {
  394. NetpKdPrint(( "XsNetAccessEnum: NetAccessEnum failed: %X\n",
  395. status ));
  396. }
  397. Header->Status = (WORD)status;
  398. goto cleanup;
  399. }
  400. IF_DEBUG(ACCESS) {
  401. NetpKdPrint(( "XsNetAccessEnum: received %ld entries at %lx\n",
  402. entriesRead, outBuffer ));
  403. }
  404. //
  405. // Determine descriptors based on level.
  406. //
  407. switch ( SmbGetUshort( &parameters->Level ) ) {
  408. case 0:
  409. StructureDesc = Desc16_access_info_0;
  410. nativeStructureDesc = Desc32_access_info_0;
  411. AuxStructureDesc = NULL;
  412. nativeAuxStructureDesc = NULL;
  413. case 1:
  414. StructureDesc = Desc16_access_info_1;
  415. nativeStructureDesc = Desc32_access_info_1;
  416. AuxStructureDesc = Desc16_access_list;
  417. nativeAuxStructureDesc = Desc32_access_list;
  418. }
  419. //
  420. // Do the actual conversion from the 32-bit structures to 16-bit
  421. // structures. We call XsFillAuxEnumBuffer, because there may be
  422. // auxiliary structures. In level 0, auxiliary descriptors are NULL,
  423. // and XsFillAuxEnumBuffer will automatically call XsFillEnumBuffer.
  424. //
  425. XsFillAuxEnumBuffer(
  426. outBuffer,
  427. entriesRead,
  428. nativeStructureDesc,
  429. nativeAuxStructureDesc,
  430. (LPVOID)SmbGetUlong( &parameters->Buffer ),
  431. (LPVOID)SmbGetUlong( &parameters->Buffer ),
  432. SmbGetUshort( &parameters->BufLen ),
  433. StructureDesc,
  434. AuxStructureDesc,
  435. &XsNetAccessEnumVerify,
  436. &bytesRequired,
  437. &entriesFilled,
  438. &invalidEntries
  439. );
  440. IF_DEBUG(ACCESS) {
  441. NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR,"
  442. " Entries %ld of %ld\n",
  443. outBuffer, SmbGetUlong( &parameters->Buffer ),
  444. bytesRequired, entriesFilled, totalEntries ));
  445. }
  446. //
  447. // If all the entries could not be filled, return ERROR_MORE_DATA,
  448. // and return the buffer as is. Because of the complexity of the
  449. // access structures, we'll send the data back unpacked.
  450. //
  451. if (( entriesFilled + invalidEntries ) < totalEntries ) {
  452. Header->Status = ERROR_MORE_DATA;
  453. }
  454. //
  455. // Set up the response parameters.
  456. //
  457. SmbPutUshort( &parameters->EntriesRead, (WORD)entriesFilled );
  458. SmbPutUshort( &parameters->TotalAvail,
  459. (WORD)( totalEntries - invalidEntries ));
  460. cleanup:
  461. } except( EXCEPTION_EXECUTE_HANDLER ) {
  462. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  463. }
  464. NetApiBufferFree( outBuffer );
  465. //
  466. // Determine return buffer size.
  467. //
  468. XsSetDataCount(
  469. &parameters->BufLen,
  470. StructureDesc,
  471. Header->Converter,
  472. entriesFilled,
  473. Header->Status
  474. );
  475. #else // NET_ACCESS_SUPPORTED
  476. RETURN_ACCESS_NOT_SUPPORTED;
  477. #endif // NET_ACCESS_SUPPORTED
  478. return STATUS_SUCCESS;
  479. } // XsNetAccessEnum
  480. NTSTATUS
  481. XsNetAccessGetInfo (
  482. API_HANDLER_PARAMETERS
  483. )
  484. /*++
  485. Routine Description:
  486. This routine handles a call to NetAccessGetInfo.
  487. Arguments:
  488. API_HANDLER_PARAMETERS - information about the API call. See
  489. XsTypes.h for details.
  490. Return Value:
  491. NTSTATUS - STATUS_SUCCESS or reason for failure.
  492. --*/
  493. {
  494. #if NET_ACCESS_SUPPORTED
  495. NET_API_STATUS status;
  496. PXS_NET_ACCESS_GET_INFO parameters = Parameters;
  497. LPTSTR nativeResource = NULL; // Native parameters
  498. LPVOID outBuffer = NULL;
  499. LPBYTE stringLocation = NULL; // Conversion variables
  500. DWORD bytesRequired = 0;
  501. LPDESC longDescriptor = NULL;
  502. LPDESC longNativeDescriptor = NULL;
  503. DWORD auxDataCount;
  504. DWORD i;
  505. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  506. IF_DEBUG(ACCESS) {
  507. NetpKdPrint(( "XsNetAccessGetInfo: header at %lx, "
  508. "params at %lx, level %ld\n",
  509. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  510. }
  511. try {
  512. //
  513. // Translate parameters, and check for errors.
  514. //
  515. switch ( SmbGetUshort( &parameters->Level )) {
  516. case 0:
  517. StructureDesc = Desc16_access_info_0;
  518. break;
  519. case 1:
  520. StructureDesc = Desc16_access_info_1;
  521. break;
  522. default:
  523. Header->Status = (WORD)ERROR_INVALID_LEVEL;
  524. goto cleanup;
  525. }
  526. XsConvertTextParameter(
  527. nativeResource,
  528. (LPSTR)SmbGetUlong( &parameters->Resource )
  529. );
  530. //
  531. // Make the local call.
  532. //
  533. status = NetAccessGetInfo(
  534. NULL,
  535. nativeResource,
  536. (DWORD)SmbGetUshort( &parameters->Level ),
  537. (LPBYTE *)&outBuffer
  538. );
  539. if ( !XsApiSuccess( status )) {
  540. IF_DEBUG(API_ERRORS) {
  541. NetpKdPrint(( "XsNetAccessGetInfo: NetAccessGetInfo failed: "
  542. "%X\n", status ));
  543. }
  544. Header->Status = (WORD)status;
  545. goto cleanup;
  546. }
  547. //
  548. // Use the requested level to determine the format of the 32-bit
  549. // structure we got back from NetAccessGetInfo. For a level 0 call,
  550. // the structure is described by the native descriptor string.
  551. // If the level is 1, form a long descriptor string which contains
  552. // enough copies of the auxiliary data descriptor. The format of the
  553. // 16-bit structure is stored in the transaction block - it must
  554. // also be converted to a long descriptor for level 1 calls.
  555. //
  556. switch ( SmbGetUshort( &parameters->Level ) ) {
  557. case 0:
  558. longDescriptor = NetpMemoryAllocate(
  559. strlen( Desc16_access_info_1 ) + 1 );
  560. longNativeDescriptor = NetpMemoryAllocate(
  561. strlen( Desc32_access_info_0 ) + 1 );
  562. if (( longDescriptor == NULL ) || ( longNativeDescriptor == NULL )) {
  563. IF_DEBUG(ERRORS) {
  564. NetpKdPrint(( "XsNetAccessGetInfo: failed to allocate memory" ));
  565. }
  566. Header->Status = NERR_NoRoom;
  567. goto cleanup;
  568. }
  569. strcpy( longDescriptor, Desc16_access_info_0 );
  570. strcpy( longNativeDescriptor, Desc32_access_info_0 );
  571. break;
  572. case 1:
  573. //
  574. // Find the auxiliary data count.
  575. //
  576. auxDataCount = RapAuxDataCount(
  577. (LPBYTE)outBuffer,
  578. Desc32_access_info_1,
  579. Response,
  580. TRUE // native format
  581. );
  582. //
  583. // 16-bit clients can only get 64 access list structures.
  584. //
  585. auxDataCount = ( auxDataCount > 64 ) ? 64 : auxDataCount;
  586. longDescriptor = NetpMemoryAllocate(
  587. strlen( Desc16_access_info_1 )
  588. + strlen( Desc16_access_list ) *
  589. auxDataCount + 1 );
  590. longNativeDescriptor = NetpMemoryAllocate(
  591. strlen( Desc32_access_info_1 )
  592. + strlen( Desc32_access_list ) * auxDataCount
  593. + 1 );
  594. if (( longDescriptor == NULL ) || ( longNativeDescriptor == NULL )) {
  595. IF_DEBUG(ERRORS) {
  596. NetpKdPrint(( "XsNetAccessGetInfo: failed to allocate memory" ));
  597. }
  598. Header->Status = (WORD)NERR_NoRoom;
  599. goto cleanup;
  600. }
  601. strcpy( longDescriptor, Desc16_access_info_1 );
  602. strcpy( longNativeDescriptor, Desc32_access_info_1 );
  603. for ( i = 0; i < auxDataCount; i++ ) {
  604. strcat( longDescriptor, Desc16_access_list );
  605. strcat( longNativeDescriptor, Desc32_access_list );
  606. }
  607. break;
  608. }
  609. //
  610. // Convert the structure returned by the 32-bit call to a 16-bit
  611. // structure. The last possible location for variable data is
  612. // calculated from buffer location and length.
  613. //
  614. stringLocation = (LPBYTE)( SmbGetUlong( &parameters->Buffer )
  615. + SmbGetUshort( &parameters->BufLen ) );
  616. status = RapConvertSingleEntry(
  617. outBuffer,
  618. longNativeDescriptor,
  619. FALSE,
  620. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  621. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  622. longDescriptor,
  623. TRUE,
  624. &stringLocation,
  625. &bytesRequired,
  626. Response,
  627. NativeToRap
  628. );
  629. if ( status != NERR_Success ) {
  630. IF_DEBUG(ERRORS) {
  631. NetpKdPrint(( "XsNetAccessGetInfo: RapConvertSingleEntry failed: "
  632. "%X\n", status ));
  633. }
  634. Header->Status = NERR_InternalError;
  635. goto cleanup;
  636. }
  637. IF_DEBUG(ACCESS) {
  638. NetpKdPrint(( "32-bit data at %lx, 16-bit data at %lx, %ld BR\n",
  639. outBuffer, SmbGetUlong( &parameters->Buffer ),
  640. bytesRequired ));
  641. }
  642. //
  643. // Determine return code based on the size of the buffer.
  644. //
  645. if ( !XsCheckBufferSize(
  646. SmbGetUshort( &parameters->BufLen ),
  647. StructureDesc,
  648. FALSE // not in native format
  649. )) {
  650. IF_DEBUG(ERRORS) {
  651. NetpKdPrint(( "XsNetAccessGetInfo: Buffer too small.\n" ));
  652. }
  653. Header->Status = NERR_BufTooSmall;
  654. } else if ( bytesRequired > SmbGetUshort( &parameters-> BufLen )) {
  655. IF_DEBUG(ERRORS) {
  656. NetpKdPrint(( "NetAccessGetInfo: More data available.\n" ));
  657. }
  658. Header->Status = ERROR_MORE_DATA;
  659. } else {
  660. //
  661. // Pack the response data.
  662. //
  663. Header->Converter = XsPackReturnData(
  664. (LPVOID)SmbGetUlong( &parameters->Buffer ),
  665. SmbGetUshort( &parameters->BufLen ),
  666. longDescriptor,
  667. 1
  668. );
  669. }
  670. //
  671. // Set up the response parameters.
  672. //
  673. SmbPutUshort( &parameters->TotalAvail, (WORD)bytesRequired );
  674. cleanup:
  675. } except( EXCEPTION_EXECUTE_HANDLER ) {
  676. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  677. }
  678. NetApiBufferFree( outBuffer );
  679. NetpMemoryFree( longDescriptor );
  680. NetpMemoryFree( longNativeDescriptor );
  681. NetpMemoryFree( nativeResource );
  682. //
  683. // Determine return buffer size.
  684. //
  685. XsSetDataCount(
  686. &parameters->BufLen,
  687. longDescriptor,
  688. Header->Converter,
  689. 1,
  690. Header->Status
  691. );
  692. #else // NET_ACCESS_SUPPORTED
  693. RETURN_ACCESS_NOT_SUPPORTED;
  694. #endif // NET_ACCESS_SUPPORTED
  695. return STATUS_SUCCESS;
  696. } // XsNetAccessGetInfo
  697. NTSTATUS
  698. XsNetAccessGetUserPerms (
  699. API_HANDLER_PARAMETERS
  700. )
  701. /*++
  702. Routine Description:
  703. This routine handles a call to NetAccessGetUserPerms.
  704. Arguments:
  705. API_HANDLER_PARAMETERS - information about the API call. See
  706. XsTypes.h for details.
  707. Return Value:
  708. NTSTATUS - STATUS_SUCCESS or reason for failure.
  709. --*/
  710. {
  711. #if NET_ACCESS_SUPPORTED
  712. NET_API_STATUS status;
  713. PXS_NET_ACCESS_GET_USER_PERMS parameters = Parameters;
  714. LPTSTR nativeUgName = NULL; // Native parameters
  715. LPTSTR nativeResource = NULL;
  716. DWORD userPerms;
  717. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  718. try {
  719. //
  720. // Translate parameters, check for errors.
  721. //
  722. XsConvertTextParameter(
  723. nativeUgName,
  724. (LPSTR)SmbGetUlong( &parameters->UgName )
  725. );
  726. XsConvertTextParameter(
  727. nativeResource,
  728. (LPSTR)SmbGetUlong( &parameters->Resource )
  729. );
  730. //
  731. // Make the local call.
  732. //
  733. status = NetAccessGetUserPerms(
  734. NULL,
  735. nativeUgName,
  736. nativeResource,
  737. &userPerms
  738. );
  739. if ( !XsApiSuccess( status )) {
  740. IF_DEBUG(ERRORS) {
  741. NetpKdPrint(( "XsNetAccessGetUserPerms: "
  742. "NetAccessGetUserPerms failed: %X\n",
  743. status ));
  744. }
  745. }
  746. //
  747. // Put perms into return field.
  748. //
  749. SmbPutUshort( &parameters->Perms, (WORD)userPerms );
  750. cleanup:
  751. } except( EXCEPTION_EXECUTE_HANDLER ) {
  752. status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  753. }
  754. NetpMemoryFree( nativeUgName );
  755. NetpMemoryFree( nativeResource );
  756. Header->Status = (WORD)status;
  757. #else // NET_ACCESS_SUPPORTED
  758. RETURN_ACCESS_NOT_SUPPORTED;
  759. #endif // NET_ACCESS_SUPPORTED
  760. return STATUS_SUCCESS;
  761. } // XsNetAccessGetUserPerms
  762. NTSTATUS
  763. XsNetAccessSetInfo (
  764. API_HANDLER_PARAMETERS
  765. )
  766. /*++
  767. Routine Description:
  768. This routine handles a call to NetAccessSetInfo.
  769. Arguments:
  770. API_HANDLER_PARAMETERS - information about the API call. See
  771. XsTypes.h for details.
  772. Return Value:
  773. NTSTATUS - STATUS_SUCCESS or reason for failure.
  774. --*/
  775. {
  776. #if NET_ACCESS_SUPPORTED
  777. NET_API_STATUS status;
  778. PXS_NET_ACCESS_SET_INFO parameters = Parameters;
  779. LPVOID buffer = NULL; // Native parameters
  780. LPTSTR nativeResource = NULL;
  781. DWORD accessAttr;
  782. DWORD bufferSize; // Conversion variables
  783. LPBYTE stringLocation = NULL;
  784. DWORD bytesRequired = 0;
  785. LPDESC longDescriptor = NULL;
  786. LPDESC longNativeDescriptor = NULL;
  787. DWORD auxDataCount;
  788. DWORD i;
  789. API_HANDLER_PARAMETERS_REFERENCE; // Avoid warnings
  790. IF_DEBUG(ACCESS) {
  791. NetpKdPrint(( "XsNetAccessSetInfo: header at %lx, params at %lx,"
  792. " level %ld\n",
  793. Header, parameters, SmbGetUshort( &parameters->Level ) ));
  794. }
  795. try {
  796. //
  797. // Translate parameters, and check for errors.
  798. //
  799. if ( SmbGetUshort( &parameters->Level ) != 1 ) {
  800. Header->Status = (WORD)ERROR_INVALID_LEVEL;
  801. goto cleanup;
  802. }
  803. XsConvertTextParameter(
  804. nativeResource,
  805. (LPSTR)SmbGetUlong( &parameters->Resource )
  806. );
  807. StructureDesc = Desc16_access_info_1;
  808. AuxStructureDesc = Desc16_access_list;
  809. //
  810. // The ParmNum can either be to change the whole ACL or just the auditing
  811. // attribute. Since the latter is much simpler than the former, check
  812. // for that ParmNum and process it. If not, we go through the elaborate
  813. // process of converting the whole buffer as in NetAccessAdd.
  814. //
  815. switch ( SmbGetUshort( &parameters->ParmNum )) {
  816. case ACCESS_ATTR_PARMNUM:
  817. if ( SmbGetUshort( &parameters->BufLen ) < sizeof(WORD)) {
  818. Header->Status= NERR_BufTooSmall;
  819. goto cleanup;
  820. }
  821. accessAttr = (DWORD)SmbGetUshort(
  822. (LPWORD)SmbGetUlong( &parameters->Buffer )
  823. );
  824. buffer = &accessAttr;
  825. break;
  826. case PARMNUM_ALL:
  827. //
  828. // Figure out if there is enough room in the buffer for the fixed
  829. // structure. If not, return NERR_BufTooSmall.
  830. //
  831. if ( !XsCheckBufferSize(
  832. SmbGetUshort( &parameters->BufLen ),
  833. StructureDesc,
  834. FALSE // not in native format
  835. )) {
  836. IF_DEBUG(ERRORS) {
  837. NetpKdPrint(( "XsNetAccessSetInfo: Buffer too small.\n" ));
  838. }
  839. Header->Status = NERR_BufTooSmall;
  840. goto cleanup;
  841. }
  842. //
  843. // Find the auxiliary data structure count, and form a long descriptor
  844. // string which can be used to do all the conversion in one pass.
  845. //
  846. auxDataCount = RapAuxDataCount(
  847. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  848. StructureDesc,
  849. Response,
  850. FALSE // not in native format
  851. );
  852. if ( auxDataCount > 64 ) {
  853. IF_DEBUG(ERRORS) {
  854. NetpKdPrint(( "XsNetAccessSetInfo: too many access_lists.\n" ));
  855. }
  856. Header->Status = NERR_ACFTooManyLists;
  857. goto cleanup;
  858. }
  859. longDescriptor = NetpMemoryAllocate(
  860. strlen( StructureDesc )
  861. + strlen( AuxStructureDesc ) * auxDataCount
  862. + 1 );
  863. longNativeDescriptor = NetpMemoryAllocate(
  864. strlen( Desc32_access_info_1 )
  865. + strlen( Desc32_access_list ) * auxDataCount
  866. + 1 );
  867. if (( longDescriptor == NULL ) || ( longNativeDescriptor == NULL )) {
  868. IF_DEBUG(ERRORS) {
  869. NetpKdPrint(( "XsNetAccessSetInfo: failed to allocate memory" ));
  870. }
  871. Header->Status = NERR_NoRoom;
  872. goto cleanup;
  873. }
  874. strcpy( longDescriptor, StructureDesc );
  875. strcpy( longNativeDescriptor, Desc32_access_info_1 );
  876. for ( i = 0; i < auxDataCount; i++ ) {
  877. strcat( longDescriptor, AuxStructureDesc );
  878. strcat( longNativeDescriptor, Desc32_access_list );
  879. }
  880. //
  881. // Figure out if there is enough room in the buffer for all this
  882. // data. If not, return NERR_BufTooSmall.
  883. //
  884. if ( !XsCheckBufferSize(
  885. SmbGetUshort( &parameters->BufLen ),
  886. longDescriptor,
  887. FALSE // not in native format
  888. )) {
  889. IF_DEBUG(ERRORS) {
  890. NetpKdPrint(( "XsNetAccessSetInfo: Buffer too small.\n" ));
  891. }
  892. Header->Status = NERR_BufTooSmall;
  893. goto cleanup;
  894. }
  895. //
  896. // Find out how big a buffer we need to allocate to hold the native
  897. // 32-bit version of the input data structure.
  898. //
  899. bufferSize = XsBytesForConvertedStructure(
  900. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  901. longDescriptor,
  902. longNativeDescriptor,
  903. RapToNative,
  904. TRUE
  905. );
  906. //
  907. // Allocate enough memory to hold the converted native buffer.
  908. //
  909. buffer = NetpMemoryAllocate( bufferSize );
  910. if ( buffer == NULL ) {
  911. IF_DEBUG(ERRORS) {
  912. NetpKdPrint(( "XsNetAccessSetInfo: failed to create buffer" ));
  913. }
  914. Header->Status = NERR_NoRoom;
  915. goto cleanup;
  916. }
  917. IF_DEBUG(ACCESS) {
  918. NetpKdPrint(( "XsNetAccessSetInfo: buffer of %ld bytes at %lx\n",
  919. bufferSize, buffer ));
  920. }
  921. //
  922. // Convert the buffer from 16-bit to 32-bit.
  923. //
  924. stringLocation = (LPBYTE)buffer + bufferSize;
  925. bytesRequired = 0;
  926. status = RapConvertSingleEntry(
  927. (LPBYTE)SmbGetUlong( &parameters->Buffer ),
  928. longDescriptor,
  929. TRUE,
  930. buffer,
  931. buffer,
  932. longNativeDescriptor,
  933. FALSE,
  934. &stringLocation,
  935. &bytesRequired,
  936. Response,
  937. RapToNative
  938. );
  939. if ( status != NERR_Success ) {
  940. IF_DEBUG(ERRORS) {
  941. NetpKdPrint(( "XsNetAccessSetInfo: "
  942. "RapConvertSingleEntry failed: %X\n",
  943. status ));
  944. }
  945. Header->Status = NERR_InternalError;
  946. goto cleanup;
  947. }
  948. break;
  949. }
  950. //
  951. // Make the local call.
  952. //
  953. status = NetAccessSetInfo(
  954. NULL,
  955. nativeResource,
  956. PARMNUM_BASE_INFOLEVEL + SmbGetUshort( &parameters->ParmNum ),
  957. buffer,
  958. NULL
  959. );
  960. if ( !XsApiSuccess( status )) {
  961. IF_DEBUG(ERRORS) {
  962. NetpKdPrint(( "XsNetAccessSetInfo: NetAccessSetInfo failed: "
  963. "%X\n", status ));
  964. }
  965. Header->Status = (WORD)status;
  966. goto cleanup;
  967. }
  968. //
  969. // There is no real return information for this API.
  970. //
  971. cleanup:
  972. } except( EXCEPTION_EXECUTE_HANDLER ) {
  973. Header->Status = (WORD)RtlNtStatusToDosError( GetExceptionCode() );
  974. }
  975. NetpMemoryFree( nativeResource );
  976. //
  977. // If there is a 32-bit native buffer, free it.
  978. //
  979. if ( SmbGetUshort( &parameters->ParmNum ) == PARMNUM_ALL ) {
  980. NetpMemoryFree( buffer );
  981. NetpMemoryFree( longDescriptor );
  982. NetpMemoryFree( longNativeDescriptor );
  983. }
  984. #else // NET_ACCESS_SUPPORTED
  985. RETURN_ACCESS_NOT_SUPPORTED;
  986. #endif // NET_ACCESS_SUPPORTED
  987. return STATUS_SUCCESS;
  988. } // XsNetAccessSetInfo