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.

534 lines
12 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: usrutils.cxx
  7. //
  8. // Contents: NetWare compatible UserCollection Enumeration Code
  9. //
  10. // History: 22-Mar-96 t-ptam (PatrickT) migrated from KrishnaG for NetWare
  11. //----------------------------------------------------------------------------
  12. #include "nwcompat.hxx"
  13. #pragma hdrstop
  14. USER_GROUP_ENTRY UserGroupEntry;
  15. //
  16. // This assumes that addr is an LPBYTE type.
  17. //
  18. #define WORD_ALIGN_DOWN(addr) \
  19. addr = ((LPBYTE)((DWORD)addr & ~1))
  20. DWORD UserGrpEntryStrings[]=
  21. {
  22. FIELD_OFFSET(USER_GROUP_ENTRY, Parent),
  23. FIELD_OFFSET(USER_GROUP_ENTRY, Computer),
  24. FIELD_OFFSET(USER_GROUP_ENTRY, Name),
  25. 0xFFFFFFFF
  26. };
  27. DECLARE_INFOLEVEL(UsrUt)
  28. DECLARE_DEBUG(UsrUt)
  29. #define UsrUtDebugOut(x) UsrUtInlineDebugOut x
  30. //----------------------------------------------------------------------------
  31. //
  32. // Function: NWCOMPATComputerUserOpen
  33. //
  34. // Synopsis: This function opens a handle to a INI_COMP_USER structure.
  35. //
  36. //----------------------------------------------------------------------------
  37. BOOL
  38. NWCOMPATComputerUserOpen(
  39. LPWSTR szComputerName,
  40. LPWSTR szGroupName,
  41. PHANDLE phUser
  42. )
  43. {
  44. WCHAR szTempBuffer[MAX_PATH];
  45. PINI_COMP_USER pIniCompUsr;
  46. HRESULT hr = S_OK;
  47. if (!phUser) {
  48. return(FALSE);
  49. }
  50. pIniCompUsr = (PINI_COMP_USER)AllocADsMem(
  51. sizeof(INI_COMP_USER)
  52. );
  53. if (!pIniCompUsr) {
  54. return(FALSE);
  55. }
  56. //
  57. // Fill structure's fields.
  58. //
  59. if (!(pIniCompUsr->szComputerName = AllocADsStr(szComputerName))){
  60. goto error;
  61. }
  62. if (!(pIniCompUsr->szGroupName = AllocADsStr(szGroupName))){
  63. goto error;
  64. }
  65. hr = NWApiGetBinderyHandle(
  66. &pIniCompUsr->_hConn,
  67. szComputerName
  68. );
  69. BAIL_ON_FAILURE(hr);
  70. //
  71. // Return
  72. //
  73. *phUser = (HANDLE)pIniCompUsr;
  74. return(TRUE);
  75. error:
  76. if (pIniCompUsr) {
  77. FreeIniCompUser(pIniCompUsr);
  78. }
  79. *phUser = NULL;
  80. return(FALSE);
  81. }
  82. //----------------------------------------------------------------------------
  83. //
  84. // Function: NWCOMPATComputerUserEnum
  85. //
  86. // Synopsis: This function returns a buffer which contains all the binding
  87. // informations for the requested number of objects without any
  88. // references.
  89. // It returns TRUE iff dwReturned = dwRequested.
  90. //
  91. //----------------------------------------------------------------------------
  92. BOOL
  93. NWCOMPATComputerUserEnum(
  94. HANDLE hUser,
  95. DWORD dwRequested,
  96. LPBYTE * ppBuffer,
  97. PDWORD pdwReturned
  98. )
  99. {
  100. LPUSER_GROUP_ENTRY * ppUserMembers = NULL;
  101. DWORD i = 0;
  102. BOOL dwRet = FALSE;
  103. DWORD dwReturned = 0;
  104. DWORD dwSize = 0;
  105. LPUSER_GROUP_ENTRY pBuffer = NULL;
  106. LPBYTE pEnd = NULL;
  107. //
  108. // Allocate buffer for the number of requested members.
  109. //
  110. ppUserMembers = (LPUSER_GROUP_ENTRY *)AllocADsMem(
  111. sizeof(LPUSER_GROUP_ENTRY)* dwRequested
  112. );
  113. if (!ppUserMembers) {
  114. return(FALSE);
  115. }
  116. //
  117. // Fill in ppUserMembers one by one.
  118. //
  119. for (i = 0; i < dwRequested; i++) {
  120. dwRet = NWCOMPATComputerUserGetObject(
  121. hUser,
  122. &ppUserMembers[i]
  123. );
  124. if (!dwRet) {
  125. break;
  126. }
  127. }
  128. if (dwRet) {
  129. dwReturned = i;
  130. //
  131. // Determine actual size of ppUserMembers[], ie. since each string in
  132. // USER_GROUP_ENTRY have a different length, a buffer that is going
  133. // to contain all the data without any references is unknown.
  134. //
  135. dwRet = ComputeComputerUserDataSize(
  136. ppUserMembers,
  137. dwReturned,
  138. &dwSize
  139. );
  140. pBuffer = (LPUSER_GROUP_ENTRY)AllocADsMem(
  141. dwSize
  142. );
  143. if (!pBuffer) {
  144. goto error;
  145. }
  146. pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
  147. //
  148. // Put data into pBuffer, starting from the end.
  149. //
  150. for (i = 0; i < dwReturned; i++) {
  151. pEnd = CopyIniCompUserToCompUser(
  152. ppUserMembers[i],
  153. (LPBYTE)(pBuffer + i),
  154. pEnd
  155. );
  156. }
  157. //
  158. // Clean up.
  159. //
  160. for (i = 0; i < dwReturned; i++ ) {
  161. FreeIntCompUser(*(ppUserMembers + i));
  162. }
  163. //
  164. // Return values.
  165. //
  166. *ppBuffer = (LPBYTE)pBuffer;
  167. *pdwReturned = dwReturned;
  168. }
  169. FreeADsMem(ppUserMembers);
  170. if (dwReturned == dwRequested){
  171. return(TRUE);
  172. }else {
  173. return(FALSE);
  174. }
  175. error:
  176. for (i = 0; i < dwReturned; i++ ) {
  177. FreeIntCompUser(*(ppUserMembers + i));
  178. }
  179. FreeADsMem(ppUserMembers);
  180. return(FALSE);
  181. }
  182. //----------------------------------------------------------------------------
  183. //
  184. // Function: NWCOMPATComputerUserGetObject
  185. //
  186. // Synopsis: This function returns binding information of a user (group member)
  187. // object one by one. In its first call, it builds a buffer that
  188. // contains all the UserID of the group members. Then, and in
  189. // subsequent calls, this UserID is translated into a user name.
  190. //
  191. //----------------------------------------------------------------------------
  192. BOOL
  193. NWCOMPATComputerUserGetObject(
  194. HANDLE hUser,
  195. LPUSER_GROUP_ENTRY * ppUserMember
  196. )
  197. {
  198. BOOL dwRet = FALSE;
  199. DWORD dwGroupId = 0;
  200. HRESULT hr = S_OK;
  201. PINI_COMP_USER pIniCompUsr = (PINI_COMP_USER)hUser;
  202. //
  203. // Fill buffer with User ID. NetWare returns all UserID in one call.
  204. //
  205. if (!pIniCompUsr->_pBuffer) {
  206. pIniCompUsr->_dwCurrentObject = 0;
  207. hr = NWApiUserGetGroups(
  208. pIniCompUsr->_hConn,
  209. pIniCompUsr->szGroupName,
  210. &(pIniCompUsr->_pBuffer)
  211. );
  212. BAIL_ON_FAILURE(hr);
  213. }
  214. //
  215. // Build one group member.
  216. //
  217. dwGroupId = *((LPDWORD)pIniCompUsr->_pBuffer + pIniCompUsr->_dwCurrentObject);
  218. if (dwGroupId != 0x0000) {
  219. dwRet = BuildComputerUserMember(
  220. hUser,
  221. dwGroupId,
  222. ppUserMember
  223. );
  224. if (!dwRet) {
  225. goto error;
  226. }
  227. pIniCompUsr->_dwCurrentObject++;
  228. return(TRUE);
  229. }
  230. error:
  231. return(FALSE);
  232. }
  233. //----------------------------------------------------------------------------
  234. //
  235. // Function: NWCOMPATComputerUserClose
  236. //
  237. // Synopsis: Wrapper of FreeIniCompUser.
  238. //
  239. //----------------------------------------------------------------------------
  240. BOOL
  241. NWCOMPATComputerUserClose(
  242. HANDLE hUser
  243. )
  244. {
  245. PINI_COMP_USER pIniCompUsr = (PINI_COMP_USER)hUser;
  246. if (pIniCompUsr) {
  247. FreeIniCompUser(pIniCompUsr);
  248. }
  249. return(TRUE);
  250. }
  251. //----------------------------------------------------------------------------
  252. //
  253. // Function: FreeIniCompUser
  254. //
  255. // Synopsis: Free an INI_COMP_USER structure.
  256. //
  257. //----------------------------------------------------------------------------
  258. void
  259. FreeIniCompUser(
  260. PINI_COMP_USER pIniCompUsr
  261. )
  262. {
  263. HRESULT hr = S_OK;
  264. if (pIniCompUsr) {
  265. if (pIniCompUsr->szComputerName) {
  266. FreeADsStr(pIniCompUsr->szComputerName);
  267. }
  268. if (pIniCompUsr->szGroupName) {
  269. FreeADsStr(pIniCompUsr->szGroupName);
  270. }
  271. if (pIniCompUsr->_pBuffer) {
  272. FreeADsMem(pIniCompUsr->_pBuffer);
  273. }
  274. if (pIniCompUsr->_hConn) {
  275. hr = NWApiReleaseBinderyHandle(pIniCompUsr->_hConn);
  276. }
  277. FreeADsMem(pIniCompUsr);
  278. }
  279. return;
  280. }
  281. //----------------------------------------------------------------------------
  282. //
  283. // Function: FreeIntCompUser
  284. //
  285. // Synopsis: Free a USER_GROUP_ENTRY structure.
  286. //
  287. //----------------------------------------------------------------------------
  288. void
  289. FreeIntCompUser(
  290. LPUSER_GROUP_ENTRY pCompUserMember
  291. )
  292. {
  293. if (pCompUserMember) {
  294. if (pCompUserMember->Parent) {
  295. FreeADsStr(pCompUserMember->Parent);
  296. }
  297. if (pCompUserMember->Computer) {
  298. FreeADsStr(pCompUserMember->Computer);
  299. }
  300. if (pCompUserMember->Name) {
  301. FreeADsStr(pCompUserMember->Name);
  302. }
  303. FreeADsMem(pCompUserMember);
  304. }
  305. return;
  306. }
  307. //----------------------------------------------------------------------------
  308. //
  309. // Function: ComputeComputerUserDataSize
  310. //
  311. // Synopsis: Calculate the size of a buffer that is going to store the data in
  312. // ppUserMembers without any references.
  313. //
  314. //----------------------------------------------------------------------------
  315. BOOL
  316. ComputeComputerUserDataSize(
  317. LPUSER_GROUP_ENTRY * ppUserMembers,
  318. DWORD dwReturned,
  319. PDWORD pdwSize
  320. )
  321. {
  322. DWORD i = 0;
  323. DWORD cb = 0;
  324. LPUSER_GROUP_ENTRY pMember = NULL;
  325. for (i = 0; i < dwReturned; i++) {
  326. pMember = *(ppUserMembers + i);
  327. cb += sizeof(USER_GROUP_ENTRY);
  328. if (pMember->Parent) {
  329. cb += wcslen(pMember->Parent)*sizeof(WCHAR) + sizeof(WCHAR);
  330. }
  331. if (pMember->Computer) {
  332. cb += wcslen(pMember->Computer)*sizeof(WCHAR) + sizeof(WCHAR);
  333. }
  334. if (pMember->Name) {
  335. cb += wcslen(pMember->Name)*sizeof(WCHAR) + sizeof(WCHAR);
  336. }
  337. }
  338. *pdwSize = cb;
  339. return(TRUE);
  340. }
  341. //------------------------------------------------------------------------------
  342. //
  343. // Function: CopyIniCompUserToCompUser
  344. //
  345. // Synopsis: Pack referenced data (string) into a buffer without any reference.
  346. //
  347. //------------------------------------------------------------------------------
  348. LPBYTE
  349. CopyIniCompUserToCompUser(
  350. LPUSER_GROUP_ENTRY pIntCompGrp,
  351. LPBYTE pExtCompGrp,
  352. LPBYTE pEnd
  353. )
  354. {
  355. LPWSTR SourceStrings[sizeof(USER_GROUP_ENTRY)/sizeof(LPWSTR)];
  356. LPWSTR *pSourceStrings = SourceStrings;
  357. LPUSER_GROUP_ENTRY pCompGrpMember = (LPUSER_GROUP_ENTRY)pExtCompGrp;
  358. memset(SourceStrings, 0, sizeof(USER_GROUP_ENTRY));
  359. *pSourceStrings++ = pIntCompGrp->Parent;
  360. *pSourceStrings++ = pIntCompGrp->Computer;
  361. *pSourceStrings++ = pIntCompGrp->Name;
  362. pEnd = PackStrings(
  363. SourceStrings,
  364. pExtCompGrp,
  365. UserGrpEntryStrings,
  366. pEnd
  367. );
  368. pCompGrpMember->Type = pIntCompGrp->Type;
  369. return pEnd;
  370. }
  371. //----------------------------------------------------------------------------
  372. //
  373. // Function: BuildComputerUserMember
  374. //
  375. // Synopsis: Put binding information of a group member into ppUserMember.
  376. //
  377. //----------------------------------------------------------------------------
  378. BOOL
  379. BuildComputerUserMember(
  380. HANDLE hUser,
  381. DWORD dwGroupId,
  382. LPUSER_GROUP_ENTRY * ppUserMember
  383. )
  384. {
  385. DWORD dwTempUserId = dwGroupId;
  386. HRESULT hr = S_OK;
  387. LPUSER_GROUP_ENTRY pUserMember = NULL;
  388. LPINI_COMP_USER pUser = (LPINI_COMP_USER)hUser;
  389. WCHAR szADsParent[MAX_PATH];
  390. //
  391. // Allocate one USER_GROUP_ENTRY.
  392. //
  393. pUserMember = (LPUSER_GROUP_ENTRY)AllocADsMem(
  394. sizeof(USER_GROUP_ENTRY)
  395. );
  396. if (!pUserMember) {
  397. return(FALSE);
  398. }
  399. //
  400. // Fill structure's fields.
  401. //
  402. pUserMember->Type = NWCOMPAT_USER_ID;
  403. wsprintf(
  404. szADsParent,
  405. L"%s://%s",
  406. szProviderName,
  407. pUser->szComputerName
  408. );
  409. pUserMember->Parent = AllocADsStr(szADsParent);
  410. pUserMember->Computer = AllocADsStr(pUser->szComputerName);
  411. hr = NWApiGetObjectName(
  412. pUser->_hConn,
  413. dwTempUserId,
  414. &pUserMember->Name
  415. );
  416. BAIL_ON_FAILURE(hr);
  417. //
  418. // Return.
  419. //
  420. *ppUserMember = pUserMember;
  421. return(TRUE);
  422. error:
  423. if (pUserMember) {
  424. if (pUserMember->Parent)
  425. FreeADsStr(pUserMember->Parent);
  426. if (pUserMember->Computer)
  427. FreeADsStr(pUserMember->Computer);
  428. FreeADsMem(pUserMember);
  429. }
  430. return(FALSE);
  431. }