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.

963 lines
28 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. rxaccess.c
  5. Abstract:
  6. Contains down-level remoted NetAccess routines:
  7. RxNetAccessAdd
  8. RxNetAccessDel
  9. RxNetAccessEnum
  10. RxNetAccessGetInfo
  11. RxNetAccessGetUserPerms
  12. RxNetAccessSetInfo
  13. (GetAccessDescriptors)
  14. (MapResourceName)
  15. Author:
  16. Richard Firth (rfirth) 20-May-1991
  17. Environment:
  18. Win-32/flat address space
  19. Notes:
  20. Routines in this module assume that caller-supplied parameters have
  21. already been verified. No effort is made to further check the veracity
  22. of parms. Any actions causing exceptions must be trapped at a higher
  23. level. This applies to ALL parameters - strings, pointers, buffers, etc.
  24. Revision History:
  25. 20-May-1991 RFirth
  26. Created
  27. 13-Sep-1991 JohnRo
  28. Use correct typedef for descriptors (LPDESC, not LPTSTR).
  29. Made changes as suggested by PC-LINT.
  30. 16-Sep-1991 JohnRo
  31. Use DBGSTATIC for nonexported routines.
  32. 25-Sep-1991 JohnRo
  33. Correct UNICODE use. (Use POSSIBLE_WCSSIZE() for LPWSTR types.)
  34. Fixed MIPS build error.
  35. 21-Nov-1991 JohnRo
  36. Removed NT dependencies to reduce recompiles.
  37. 05-Dec-1991 RFirth
  38. Enum returns in TotalEntries (or EntriesLeft) the number of items to
  39. be enumerated BEFORE this call. Used to be number left after this call
  40. 07-Feb-1992 JohnRo
  41. Avoid compiler warnings.
  42. Use NetApiBufferAllocate() instead of private version.
  43. 11-Jan-1993 JohnRo
  44. Made changes suggested by PC-LINT 5.0
  45. 30-Apr-1993 JohnRo
  46. Fix NET_API_FUNCTION references. (NetAccess routines are just #define'd
  47. as RxNetAccess routines in lmaccess.h, so we need NET_API_FUNCTION here
  48. too!)
  49. --*/
  50. #include <nt.h>
  51. #include <ntrtl.h>
  52. #include "downlevl.h"
  53. #include <lmaccess.h>
  54. // Don't complain about "unneeded" includes of these files:
  55. /*lint -efile(764,rxaccess.h) */
  56. /*lint -efile(766,rxaccess.h) */
  57. #include "rxaccess.h"
  58. #include <lmuse.h>
  59. //
  60. // local prototypes
  61. //
  62. DBGSTATIC void
  63. GetAccessDescriptors(
  64. IN DWORD Level,
  65. OUT LPDESC* pDesc16,
  66. OUT LPDESC* pDesc32,
  67. OUT LPDESC* pDescSmb,
  68. OUT LPDWORD pDataSize
  69. );
  70. DBGSTATIC
  71. BOOL
  72. MapResourceName(
  73. IN LPTSTR LocalName,
  74. OUT LPTSTR RemoteName
  75. );
  76. //
  77. // routines
  78. //
  79. NET_API_STATUS NET_API_FUNCTION
  80. RxNetAccessAdd(
  81. IN LPCWSTR ServerName,
  82. IN DWORD Level,
  83. IN LPBYTE Buffer,
  84. OUT LPDWORD ParmError OPTIONAL
  85. )
  86. /*++
  87. Routine Description:
  88. Add a user account to a remote down-level server database. Buffer contains
  89. an ACCESS_INFO_1 structure followed by a list of ACCESS_LIST structures
  90. Assumes:
  91. 1. all parameters already verified at higher level
  92. Arguments:
  93. ServerName - at which server to perform this request
  94. Level - of information being supplied. Must be 1
  95. Buffer - pointer to user's buffer containing ACCESS_INFO_1 struct
  96. ParmError - optional pointer to place to deposit parameter error
  97. Return Value:
  98. NET_API_STATUS:
  99. Success - NERR_Success
  100. Failure - ERROR_INVALID_PARAMETER
  101. One of the fields in the ACCESS_INFO_1 structure may blow
  102. a down-level limit
  103. --*/
  104. {
  105. NET_API_STATUS rc;
  106. DWORD badparm;
  107. DWORD buflen;
  108. DWORD count;
  109. DWORD len;
  110. PACCESS_LIST aclptr;
  111. TCHAR mappedName[MAX_PATH];
  112. LPACCESS_INFO_1 infoPtr = NULL;
  113. //
  114. // set up default for ParmError and probe writability if value given
  115. //
  116. if (ParmError == NULL) {
  117. ParmError = &badparm;
  118. }
  119. *ParmError = PARM_ERROR_UNKNOWN;
  120. //
  121. // Don't allow null servername
  122. //
  123. if ( ServerName == NULL || *ServerName == L'\0' ) {
  124. return(NERR_InvalidComputer);
  125. }
  126. //
  127. // Down-level servers only support 1 level of Add information - 1. If this
  128. // isn't it then throw out this request without further ado
  129. //
  130. if (Level != 1) {
  131. return ERROR_INVALID_LEVEL;
  132. }
  133. //
  134. // calculate the size of the buffer we are passing in (32-bit size)
  135. //
  136. //
  137. // How to calculate the maximum for the resource name (PATHLEN?)
  138. // try to blow up a down-level server by submitting eg 4K string
  139. //
  140. buflen = sizeof(ACCESS_INFO_1); // fixed part
  141. len = POSSIBLE_STRLEN(((ACCESS_INFO_1*)Buffer)->acc1_resource_name);
  142. if (!len) {
  143. *ParmError = ACCESS_RESOURCE_NAME_INFOLEVEL;
  144. return ERROR_INVALID_PARAMETER;
  145. }
  146. buflen += len;
  147. //
  148. // loop through the list of ACLs, checking the user/group name against the
  149. // down-level limit
  150. //
  151. //
  152. // STRSIZE returns the number of characters, so all
  153. // we need is count * sizeof(16-bit ACCESS_LIST structure) + sizeof(16-bit
  154. // ACCESS_INFO_1 structure) + STRSIZE(resource name)
  155. //
  156. aclptr = (PACCESS_LIST)(Buffer + sizeof(ACCESS_INFO_1));
  157. for (count = ((ACCESS_INFO_1*)Buffer)->acc1_count; count; --count) {
  158. buflen += sizeof(ACCESS_LIST); // fixed part of access list
  159. if (len = POSSIBLE_STRLEN(aclptr->acl_ugname)) {
  160. if (len > LM20_UNLEN) {
  161. *ParmError = ACCESS_ACCESS_LIST_INFOLEVEL;
  162. return ERROR_INVALID_PARAMETER;
  163. }
  164. }
  165. }
  166. //
  167. // if we need to map the resource name then we have to create a new buffer
  168. // for the access list
  169. //
  170. if (MapResourceName(((LPACCESS_INFO_1)Buffer)->acc1_resource_name, mappedName)) {
  171. infoPtr = (LPACCESS_INFO_1)NetpMemoryAllocate(buflen);
  172. if (infoPtr == NULL) {
  173. return ERROR_NOT_ENOUGH_MEMORY;
  174. }
  175. RtlMoveMemory(infoPtr, Buffer, buflen);
  176. infoPtr->acc1_resource_name = mappedName;
  177. Buffer = (LPBYTE)infoPtr;
  178. }
  179. rc = RxRemoteApi(API_WAccessAdd, // API #
  180. (LPWSTR) ServerName, // where it will run
  181. REMSmb_NetAccessAdd_P, // parameter descriptor
  182. REM16_access_info_1, // Data descriptor/16-bit
  183. REM32_access_info_1, // Data descriptor/32-bit
  184. REMSmb_access_info_1, // Data descriptor/SMB
  185. REM16_access_list, // Aux descriptor/16-bit
  186. REM32_access_list, // Aux descriptor/32-bit
  187. REMSmb_access_list, // Aux descriptor/SMB
  188. FALSE, // this call needs user to be logged on
  189. 1, // level. Since there's only 1 push immediate
  190. Buffer, // caller's share_info_1 struct
  191. buflen // parameter supplied by us
  192. );
  193. //
  194. // if we mapped the resource name free up the buffer
  195. //
  196. if (infoPtr) {
  197. NetpMemoryFree(infoPtr);
  198. }
  199. //
  200. // we didn't expect to get any data in return. Just pass the return
  201. // code back to our caller
  202. //
  203. return rc;
  204. }
  205. //NET_API_STATUS
  206. //RxNetAccessCheck(
  207. // )
  208. //{
  209. // /** CANNOT BE REMOTED **/
  210. //}
  211. NET_API_STATUS NET_API_FUNCTION
  212. RxNetAccessDel(
  213. IN LPCWSTR ServerName,
  214. IN LPCWSTR ResourceName
  215. )
  216. /*++
  217. Routine Description:
  218. Remotely delete a resource's Access Control List entry from a down-level
  219. server database. The caller must have Admin privilege to successfully
  220. execute this routine
  221. Arguments:
  222. ServerName - at which server to perform this request
  223. ResourceName- name of thing to delete
  224. Return Value:
  225. NET_API_STATUS:
  226. Success = NERR_Success
  227. Failure =
  228. --*/
  229. {
  230. TCHAR mappedName[MAX_PATH];
  231. //
  232. // Don't allow null servername
  233. //
  234. if ( ServerName == NULL || *ServerName == L'\0' ) {
  235. return(NERR_InvalidComputer);
  236. }
  237. //
  238. // The ResourceName parameter must be a non-NUL(L) string
  239. //
  240. if (!VALID_STRING(ResourceName)) {
  241. return ERROR_INVALID_PARAMETER;
  242. }
  243. if (MapResourceName((LPWSTR)ResourceName, mappedName)) {
  244. ResourceName = mappedName;
  245. }
  246. return RxRemoteApi(API_WAccessDel, // API #
  247. (LPWSTR) ServerName, // where it will run
  248. REMSmb_NetAccessDel_P, // parameter descriptor
  249. NULL, // Data descriptor/16-bit
  250. NULL, // Data descriptor/32-bit
  251. NULL, // Data descriptor/SMB
  252. NULL, // Aux descriptor/16-bit
  253. NULL, // Aux descriptor/32-bit
  254. NULL, // Aux descriptor/SMB
  255. FALSE, // this call needs user to be logged on
  256. ResourceName
  257. );
  258. }
  259. NET_API_STATUS NET_API_FUNCTION
  260. RxNetAccessEnum(
  261. IN LPCWSTR ServerName,
  262. IN LPCWSTR BasePath,
  263. IN DWORD Recursive,
  264. IN DWORD Level,
  265. OUT LPBYTE* Buffer,
  266. IN DWORD PrefMaxLen,
  267. OUT LPDWORD EntriesRead,
  268. OUT LPDWORD EntriesLeft,
  269. IN OUT LPDWORD ResumeHandle OPTIONAL
  270. )
  271. /*++
  272. Routine Description:
  273. Retrieves access info from a remote down-level server
  274. NOTE: Assumes that calling routine (NetAccessEnum) has validated the
  275. caller's pointers: Buffer, EntriesRead and EntriesLeft are all
  276. valid, writable pointers
  277. Arguments:
  278. ServerName - at which server to perform this request
  279. BasePath - for the resource(s)
  280. Recursive - flag: 0 = return information only for resources identified
  281. in BasePath. !0 = return information for all resources under
  282. BasePath
  283. Level - of information requested. Must be zero
  284. Buffer - pointer to place to store pointer to returned buffer
  285. PrefMaxLen - caller's preferred maximum buffer size
  286. EntriesRead - pointer to returned number of enum elements in buffer
  287. EntriesLeft - pointer to returned total enum elements available to the caller
  288. ResumeHandle- optional pointer to handle for resuming interrupted searches
  289. Return Value:
  290. NET_API_STATUS:
  291. Success = NERR_Success
  292. Failure =
  293. --*/
  294. {
  295. NET_API_STATUS rc;
  296. LPDESC pDesc16;
  297. LPDESC pDesc32;
  298. LPDESC pDescSmb;
  299. LPBYTE ourbuf;
  300. DWORD infolen, entries_read, total_avail;
  301. TCHAR mappedName[MAX_PATH];
  302. UNREFERENCED_PARAMETER(PrefMaxLen);
  303. //
  304. // Don't allow null servername
  305. //
  306. if ( ServerName == NULL || *ServerName == L'\0' ) {
  307. return(NERR_InvalidComputer);
  308. }
  309. //
  310. // Set the number of entries read and total available to sensible defaults.
  311. // Side effect of testing writability of supplied parameters
  312. //
  313. *Buffer = NULL;
  314. *EntriesRead = 0;
  315. *EntriesLeft = 0;
  316. //
  317. // Check for invalid parameters.
  318. // NB Assumes that DWORD is unsigned
  319. // NB Assume that calling routine (ie NetAccessEnum) has validated the
  320. // caller's pointers
  321. // Ensure that:
  322. // Level is not >1
  323. // ResumeHandle is NULL or a pointer to NULL
  324. //
  325. if (!NULL_REFERENCE(ResumeHandle)) {
  326. return ERROR_INVALID_PARAMETER;
  327. }
  328. if (Level > 1) {
  329. return ERROR_INVALID_LEVEL;
  330. }
  331. //
  332. // Decide which descriptors to use, based on the Level parameter
  333. //
  334. GetAccessDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen);
  335. //
  336. // allocate the buffer in which to return the enumerated info, using the
  337. // supplied size criteria. If we fail then return the error code to the
  338. // caller
  339. //
  340. ourbuf = NULL;
  341. if (MapResourceName((LPWSTR)BasePath, mappedName)) {
  342. BasePath = mappedName;
  343. }
  344. rc = RxRemoteApi(API_WAccessEnum, // API number
  345. (LPWSTR) ServerName, // where it will run
  346. REMSmb_NetAccessEnum_P, // parameter descriptor
  347. pDesc16, // Data descriptor/16-bit
  348. pDesc32, // Data descriptor/32-bit
  349. pDescSmb, // Data descriptor/SMB
  350. REM16_access_list, // Aux descriptor/16-bit
  351. REM32_access_list, // Aux descriptor/32-bit
  352. REMSmb_access_list, // Aux descriptor/SMB
  353. ALLOCATE_RESPONSE,
  354. BasePath, // where to start
  355. Recursive, // get tree or not
  356. Level, // level parameter
  357. &ourbuf,
  358. 65535,
  359. &entries_read, // pointer to entries read variable
  360. &total_avail // pointer to total entries variable
  361. );
  362. if (rc) {
  363. if (ourbuf != NULL) {
  364. (void) NetApiBufferFree(ourbuf);
  365. }
  366. } else {
  367. *Buffer = ourbuf;
  368. *EntriesRead = entries_read;
  369. *EntriesLeft = total_avail;
  370. }
  371. return rc;
  372. }
  373. NET_API_STATUS NET_API_FUNCTION
  374. RxNetAccessGetInfo(
  375. IN LPCWSTR ServerName,
  376. IN LPCWSTR ResourceName,
  377. IN DWORD Level,
  378. OUT LPBYTE* Buffer
  379. )
  380. /*++
  381. Routine Description:
  382. Retrieves access information about a specific resource from a remote
  383. down-level server
  384. Arguments:
  385. ServerName - at which server to perform this request
  386. ResourceName- name of resource we are trying to get info for
  387. Level - of information required: 0 or 1
  388. Buffer - pointer to place to store address of buffer containing
  389. requested information
  390. Return Value:
  391. NET_API_STATUS:
  392. Success = NERR_Success
  393. Failure = ERROR_INVALID_LEVEL
  394. Specified Level parameter can not be accepted
  395. ERROR_INVALID_PARAMETER
  396. ResourceName or Buffer not valid
  397. --*/
  398. {
  399. NET_API_STATUS rc;
  400. LPDESC pDesc16; // pointer to 16-bit info descriptor for RxRemoteApi
  401. LPDESC pDesc32; // pointer to 32-bit info descriptor for RxRemoteApi
  402. LPDESC pDescSmb; // pointer to SMB info descriptor for RxRemoteApi
  403. LPDESC pAuxDesc16; // pointer to 16-bit aux info descriptor for RxRemoteApi
  404. LPDESC pAuxDesc32; // pointer to 32-bit aux info descriptor for RxRemoteApi
  405. LPDESC pAuxDescSmb; // pointer to SMB aux info descriptor for RxRemoteApi
  406. LPBYTE ourbuf; // buffer we allocate, fill, and give to the caller
  407. DWORD total_avail; // 32-bit total available if supplied buffer too small
  408. DWORD infolen; // 32-bit place to store size of required buffer
  409. TCHAR mappedName[MAX_PATH];
  410. //
  411. // Don't allow null servername
  412. //
  413. if ( ServerName == NULL || *ServerName == L'\0' ) {
  414. return(NERR_InvalidComputer);
  415. }
  416. //
  417. // Perform parameter validity checks:
  418. // Level must be in range 0 <= Level <= 1
  419. // ResourceName must be non-NULL pointer to non-NULL string
  420. // Buffer must be non-NULL pointer
  421. // NB. Assumes DWORD unsigned
  422. //
  423. if (Level > 1) {
  424. return ERROR_INVALID_LEVEL;
  425. }
  426. if (NULL_REFERENCE(ResourceName) || !Buffer) {
  427. return ERROR_INVALID_PARAMETER;
  428. }
  429. //
  430. // set Buffer to default value and catch any bad address errors
  431. //
  432. *Buffer = NULL;
  433. //
  434. // Work out the descriptor and buffer size requirements based on the
  435. // requested level
  436. //
  437. GetAccessDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen);
  438. if (Level == 1) {
  439. pAuxDesc16 = REM16_access_list;
  440. pAuxDesc32 = REM32_access_list;
  441. pAuxDescSmb = REMSmb_access_list;
  442. } else {
  443. pAuxDesc16 = NULL;
  444. pAuxDesc32 = NULL;
  445. pAuxDescSmb = NULL;
  446. }
  447. //
  448. // get a better way to allocate the buffer length
  449. //
  450. infolen = 4096;
  451. //
  452. // allocate a buffer size required to fit in 1 structure at info level
  453. // requested. If the allocation fails then return the error
  454. //
  455. if (rc = NetApiBufferAllocate(infolen, (LPVOID *) &ourbuf)) {
  456. return rc;
  457. }
  458. if (MapResourceName((LPWSTR)ResourceName, mappedName)) {
  459. ResourceName = mappedName;
  460. }
  461. rc = RxRemoteApi(API_WAccessGetInfo,
  462. (LPWSTR) ServerName, // where it will happen
  463. REMSmb_NetAccessGetInfo_P, // parameter descriptor
  464. pDesc16, // Data descriptor/16-bit
  465. pDesc32, // Data descriptor/32-bit
  466. pDescSmb, // Data descriptor/SMB
  467. pAuxDesc16, // Aux descriptor/16-bit
  468. pAuxDesc32, // Aux descriptor/32-bit
  469. pAuxDescSmb, // Aux descriptor/SMB
  470. FALSE, // this call needs user to be logged on
  471. ResourceName, // pointer to thing to get info on
  472. Level, // level of info
  473. ourbuf, // pointer to buffer sourced by us
  474. infolen, // size of our sourced buffer
  475. &total_avail // pointer to total available
  476. );
  477. //
  478. // If the remote NetShareGetInfo call succeeded then give the returned
  479. // buffer to the caller
  480. //
  481. if (rc == NERR_Success) {
  482. *Buffer = ourbuf;
  483. } else {
  484. //
  485. // if we didn't record a success then free the buffer previously allocated
  486. //
  487. (void) NetApiBufferFree(ourbuf);
  488. }
  489. return rc;
  490. }
  491. NET_API_STATUS NET_API_FUNCTION
  492. RxNetAccessGetUserPerms(
  493. IN LPCWSTR ServerName,
  494. IN LPCWSTR UserName,
  495. IN LPCWSTR ResourceName,
  496. OUT LPDWORD Perms
  497. )
  498. /*++
  499. Routine Description:
  500. Retrieves the access information for a particular resource for a
  501. specified user or group
  502. Arguments:
  503. ServerName - at which server to perform this request
  504. UserName - name of user or group which can access resource
  505. ResourceName- name of resource to get information for
  506. Perms - pointer to place to store permissions
  507. Return Value:
  508. NET_API_STATUS:
  509. Success = NERR_Success
  510. Failure = ERROR_INVALID_PARAMETER
  511. (return code from remoted NetAccessGetUserPerms)
  512. --*/
  513. {
  514. TCHAR mappedName[MAX_PATH];
  515. //
  516. // Don't allow null servername
  517. //
  518. if ( ServerName == NULL || *ServerName == L'\0' ) {
  519. return(NERR_InvalidComputer);
  520. }
  521. //
  522. // set *Perms to default value and verify writability of Perms
  523. //
  524. *Perms = 0;
  525. //
  526. // Perform parameter validity checks:
  527. // UserName must be non-NULL pointer to non-NULL string
  528. // ResourceName must be non-NULL pointer to non-NULL string
  529. // Perms must be non-NULL pointer
  530. //
  531. if (!VALID_STRING(UserName) || !VALID_STRING(ResourceName)) {
  532. return ERROR_INVALID_PARAMETER;
  533. }
  534. if (MapResourceName( (LPWSTR) ResourceName, mappedName)) {
  535. ResourceName = mappedName;
  536. }
  537. return RxRemoteApi(API_WAccessGetUserPerms, // API #
  538. (LPWSTR) ServerName, // where it will run
  539. REMSmb_NetAccessGetUserPerms_P, // parameter descriptor
  540. NULL, // Data descriptor/16-bit
  541. NULL, // Data descriptor/32-bit
  542. NULL, // Data descriptor/SMB
  543. NULL, // Aux descriptor/16-bit
  544. NULL, // Aux descriptor/32-bit
  545. NULL, // Aux descriptor/SMB
  546. FALSE, // this call needs user to be logged on
  547. UserName, // for whom the bells toll
  548. ResourceName, // pointer to thing to get info on
  549. Perms // pointer to returned permissions
  550. );
  551. }
  552. NET_API_STATUS NET_API_FUNCTION
  553. RxNetAccessSetInfo(
  554. IN LPCWSTR ServerName,
  555. IN LPCWSTR ResourceName,
  556. IN DWORD Level,
  557. IN LPBYTE Buffer,
  558. OUT LPDWORD ParmError OPTIONAL
  559. )
  560. /*++
  561. Routine Description:
  562. Changes the access control information for a resource at a specific
  563. down-level remote server
  564. Arguments:
  565. ServerName - at which server to perform this request
  566. ResourceName- name of resource to change access information
  567. Level - level of information buffer being supplied
  568. - 1 or ACCESS_ATTR_INFOLEVEL
  569. Buffer - pointer to buffer containing information
  570. ParmError - optional pointer to place to store parameter error
  571. Return Value:
  572. NET_API_STATUS:
  573. Success = NERR_Success
  574. Failure =
  575. --*/
  576. {
  577. DWORD parmnum;
  578. TCHAR mappedName[MAX_PATH];
  579. UNREFERENCED_PARAMETER(ParmError);
  580. //
  581. // Don't allow null servername
  582. //
  583. if ( ServerName == NULL || *ServerName == L'\0' ) {
  584. return(NERR_InvalidComputer);
  585. }
  586. //
  587. // Perform parameter validity checks:
  588. // Level must be 1 or 1002
  589. // ResourceName must be non-NULL pointer to non-NULL string
  590. // Buffer must be non-NULL
  591. // ParmNum must be in range
  592. // NB. Does not assume that DWORD is unsigned
  593. //
  594. if ((Level != 1) && (Level != ACCESS_ATTR_INFOLEVEL)) {
  595. return ERROR_INVALID_LEVEL;
  596. }
  597. if (!VALID_STRING(ResourceName) || !Buffer) {
  598. return ERROR_INVALID_PARAMETER;
  599. }
  600. //
  601. // convert the NT level information to down-level. Level must be 1 at down-
  602. // level server. ParmNum can be PARMNUM_ALL (0) or ACCESS_ATTR_PARMNUM (2)
  603. // Note that the size of the data being passed to the down-level server will
  604. // be calculated in RxRemoteApi. We do not need to pass in a valid buffer
  605. // length, although the parameter string (REMSmb_NetAccessSetInfo_P) has a
  606. // 'T' descriptor saying this is what the server is getting. We just need
  607. // a place-holder on the stack, hence 0
  608. //
  609. parmnum = (Level == 1) ? PARMNUM_ALL : ACCESS_ATTR_PARMNUM;
  610. if (MapResourceName( (LPWSTR) ResourceName, mappedName)) {
  611. ResourceName = mappedName;
  612. }
  613. return RxRemoteApi(
  614. API_WAccessSetInfo, // API #
  615. (LPWSTR) ServerName, // where it will run
  616. REMSmb_NetAccessSetInfo_P, // parameter descriptor
  617. REM16_access_info_1_setinfo, // Data descriptor/16-bit
  618. REM32_access_info_1_setinfo, // Data descriptor/32-bit
  619. REMSmb_access_info_1_setinfo, // Data descriptor/SMB
  620. REM16_access_list, // Aux descriptor/16-bit
  621. REM32_access_list, // Aux descriptor/32-bit
  622. REMSmb_access_list, // Aux descriptor/SMB
  623. FALSE, // this call needs user to be logged on
  624. ResourceName, // pointer to thing to set info on
  625. 1, // level of info
  626. Buffer, // pointer to buffer sourced by caller
  627. 0, // size of our buffer IGNORED!
  628. //
  629. // in this case, the field index and parm num are the
  630. // same value
  631. //
  632. MAKE_PARMNUM_PAIR(parmnum, parmnum)
  633. );
  634. }
  635. DBGSTATIC void
  636. GetAccessDescriptors(
  637. IN DWORD level,
  638. OUT LPDESC* pDesc16,
  639. OUT LPDESC* pDesc32,
  640. OUT LPDESC* pDescSmb,
  641. OUT LPDWORD pDataSize
  642. )
  643. /*++
  644. Routine Description:
  645. A routinette to return pointers to the 16- and 32-bit access info
  646. structure descriptor strings for each level (0, 1). Also returns
  647. the size of the 16-bit structure
  648. Arguments:
  649. level - of information to be returned
  650. pDesc16 - pointer to returned 16-bit descriptor string
  651. pDesc32 - pointer to returned 32-bit descriptor string
  652. pDescSmb - pointer to returned SMB descriptor string
  653. pDataSize - pointer to returned size of 16-bit structure
  654. Return Value:
  655. None.
  656. --*/
  657. {
  658. switch (level) {
  659. case 0:
  660. *pDesc16 = REM16_access_info_0;
  661. *pDesc32 = REM32_access_info_0;
  662. *pDescSmb = REMSmb_access_info_0;
  663. *pDataSize = sizeof(ACCESS_INFO_0);
  664. break;
  665. case 1:
  666. *pDesc16 = REM16_access_info_1;
  667. *pDesc32 = REM32_access_info_1;
  668. *pDescSmb = REMSmb_access_info_1;
  669. *pDataSize = sizeof(ACCESS_INFO_1);
  670. break;
  671. #if DBG
  672. //
  673. // just to be completely paranoid...
  674. //
  675. default:
  676. NetpKdPrint(("%s.%u Unknown Level parameter: %u\n", __FILE__, __LINE__, level));
  677. #endif
  678. }
  679. }
  680. DBGSTATIC
  681. BOOL
  682. MapResourceName(
  683. IN LPTSTR LocalName,
  684. OUT LPTSTR RemoteName
  685. )
  686. /*++
  687. Routine Description:
  688. Maps a local resource name to the remote name. Only applies to resource
  689. names which start with a drive specification "[A-Z]:" and then only if
  690. the drive letter specifies a remoted drive
  691. ASSUMES: RemoteName is large enough to hold the mapped name
  692. Arguments:
  693. LocalName - pointer to name of local resource specification
  694. RemoteName - pointer to buffer which will receive mapped resource name
  695. Return Value:
  696. BOOL
  697. TRUE - name was mapped
  698. FALSE - name not mapped
  699. --*/
  700. {
  701. TCHAR driveName[3];
  702. NET_API_STATUS status;
  703. LPUSE_INFO_0 lpUse;
  704. LPTSTR resourceName;
  705. BOOL mapped;
  706. DWORD i;
  707. if (LocalName[1] != TCHAR_COLON) {
  708. (VOID) STRCPY(RemoteName, LocalName);
  709. return FALSE;
  710. }
  711. driveName[0] = LocalName[0];
  712. driveName[1] = TCHAR_COLON;
  713. driveName[2] = TCHAR_EOS;
  714. //
  715. // map the local drive name to the UNC name. If NetUseGetInfo returns
  716. // any error, then don't map
  717. //
  718. status = NetUseGetInfo(NULL, driveName, 0, (LPBYTE*)(LPVOID)&lpUse);
  719. if (status == NERR_Success) {
  720. (VOID) STRCPY(RemoteName, lpUse->ui0_remote);
  721. resourceName = LocalName + 2;
  722. //
  723. // if the rest of the resource name does not start with a path
  724. // separator (it should!) then add one
  725. //
  726. if (!IS_PATH_SEPARATOR(*resourceName) && *resourceName) {
  727. (VOID) STRCAT(RemoteName, (LPTSTR) TEXT("\\"));
  728. }
  729. (VOID) NetApiBufferFree((LPBYTE)lpUse);
  730. mapped = TRUE;
  731. } else {
  732. *RemoteName = TCHAR_EOS;
  733. resourceName = LocalName;
  734. mapped = FALSE;
  735. }
  736. //
  737. // concatenate the rest of the resource name to the UNC. If NetUseGetInfo
  738. // failed then the UNC is a NULL string and the rest of the resource name
  739. // is LocalName
  740. //
  741. (VOID) STRCAT(RemoteName, resourceName);
  742. //
  743. // strip trailing path separators
  744. //
  745. for (i = STRLEN(RemoteName) - 1; IS_PATH_SEPARATOR(RemoteName[i]); --i) {
  746. ;
  747. }
  748. RemoteName[i+1] = TCHAR_EOS;
  749. return mapped;
  750. }