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.

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