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.

754 lines
16 KiB

  1. #include "winnt.hxx"
  2. #pragma hdrstop
  3. WINNT_GROUP WinNTGroup;
  4. //
  5. // This assumes that addr is an LPBYTE type.
  6. //
  7. #define WORD_ALIGN_DOWN(addr) \
  8. addr = ((LPBYTE)((DWORD_PTR)addr & ~1))
  9. DWORD WinNTGroupStrings[]=
  10. {
  11. FIELD_OFFSET(WINNT_GROUP, Parent),
  12. FIELD_OFFSET(WINNT_GROUP, Computer),
  13. FIELD_OFFSET(WINNT_GROUP, Domain),
  14. FIELD_OFFSET(WINNT_GROUP, Name),
  15. 0xFFFFFFFF
  16. };
  17. BOOL
  18. WinNTComputerOpen(
  19. LPWSTR szDomainName,
  20. LPWSTR szComputerName,
  21. ULONG uGroupParent,
  22. PHANDLE phComputer
  23. )
  24. {
  25. WCHAR szTempBuffer[MAX_PATH];
  26. PINICOMPUTER pIniComputer;
  27. HRESULT hr;
  28. if (!phComputer || (szComputerName == NULL) ) {
  29. return(FALSE);
  30. }
  31. pIniComputer = (PINICOMPUTER)AllocADsMem(
  32. sizeof(INICOMPUTER)
  33. );
  34. if (!pIniComputer) {
  35. return(FALSE);
  36. }
  37. hr = MakeUncName(
  38. szComputerName,
  39. szTempBuffer
  40. );
  41. BAIL_ON_FAILURE(hr);
  42. if (!(pIniComputer->szUncCompName = AllocADsStr(szTempBuffer))){
  43. goto error;
  44. }
  45. if (szDomainName != NULL) {
  46. if (!(pIniComputer->szDomainName = AllocADsStr(szDomainName))) {
  47. goto error;
  48. }
  49. }
  50. if (!(pIniComputer->szComputerName = AllocADsStr(szComputerName))){
  51. goto error;
  52. }
  53. pIniComputer->uGroupParent = uGroupParent;
  54. *phComputer = (HANDLE)pIniComputer;
  55. return(TRUE);
  56. error:
  57. if (pIniComputer) {
  58. FreeIniComputer(pIniComputer);
  59. }
  60. *phComputer = NULL;
  61. return(FALSE);
  62. }
  63. BOOL
  64. WinNTEnumGlobalGroups(
  65. HANDLE hComputer,
  66. DWORD dwRequested,
  67. LPBYTE * ppBuffer,
  68. PDWORD pdwReturned
  69. )
  70. {
  71. LPWINNT_GROUP * ppGroup = NULL;
  72. DWORD i = 0;
  73. BOOL dwRet = FALSE;
  74. DWORD dwReturned = 0;
  75. DWORD dwSize = 0;
  76. LPWINNT_GROUP pBuffer = NULL;
  77. LPBYTE pEnd = NULL;
  78. BOOL retVal = FALSE;
  79. ppGroup = (LPWINNT_GROUP *)AllocADsMem(
  80. sizeof(LPWINNT_GROUP)* dwRequested
  81. );
  82. if (!ppGroup) {
  83. return(FALSE);
  84. }
  85. for (i = 0; i < dwRequested; i++) {
  86. dwRet = WinNTComputerGetGlobalGroup(
  87. hComputer,
  88. &ppGroup[i]
  89. );
  90. if (!dwRet) {
  91. break;
  92. }
  93. }
  94. dwReturned = i;
  95. dwRet = ComputeWinNTGroupDataSize(
  96. ppGroup,
  97. dwReturned,
  98. &dwSize
  99. );
  100. pBuffer = (LPWINNT_GROUP)AllocADsMem(
  101. dwSize
  102. );
  103. if (pBuffer) {
  104. retVal = TRUE;
  105. pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
  106. for (i = 0; i < dwReturned; i++) {
  107. pEnd = CopyIniWinNTGroupToWinNTGroup(
  108. ppGroup[i],
  109. (LPBYTE)(pBuffer + i),
  110. pEnd
  111. );
  112. }
  113. }
  114. for (i = 0; i < dwReturned; i++ ) {
  115. FreeIntWinNTGroup(*(ppGroup + i));
  116. }
  117. FreeADsMem(ppGroup);
  118. //
  119. // Will assign to NULL correctly if alloc failed.
  120. //
  121. *ppBuffer = (LPBYTE)pBuffer;
  122. *pdwReturned = retVal ? dwReturned : 0;
  123. if (!retVal) {
  124. return(FALSE);
  125. }
  126. if (dwReturned == dwRequested){
  127. return(TRUE);
  128. }else {
  129. return(FALSE);
  130. }
  131. }
  132. BOOL
  133. WinNTComputerGetGlobalGroup(
  134. HANDLE hComputer,
  135. LPWINNT_GROUP * ppGroup
  136. )
  137. {
  138. BOOL dwRet = FALSE;
  139. PINICOMPUTER pIniComp = (PINICOMPUTER)hComputer;
  140. NET_API_STATUS nasStatus = 0;
  141. GROUP_INFO_2 *pGroupInfo2 = NULL;
  142. LPSERVER_INFO_101 lpServerInfo =NULL;
  143. HRESULT hr = S_OK;
  144. if ((!pIniComp->_pBuffer) ||
  145. (pIniComp->_dwCurrentObject == pIniComp->_dwObjectReturned)) {
  146. if (pIniComp->_bNoMore) {
  147. //
  148. // No more objects to return
  149. //
  150. return(FALSE);
  151. }
  152. if (pIniComp->_pBuffer) {
  153. NetApiBufferFree(pIniComp->_pBuffer);
  154. pIniComp->_pBuffer = NULL;
  155. }
  156. pIniComp->_dwObjectReturned = 0;
  157. pIniComp->_dwCurrentObject = 0;
  158. pIniComp->_dwTotalObjects = 0;
  159. nasStatus = NetGroupEnum(
  160. pIniComp->szUncCompName,
  161. 2,
  162. &pIniComp->_pBuffer,
  163. MAX_PREFERRED_LENGTH,
  164. &pIniComp->_dwObjectReturned,
  165. &pIniComp->_dwTotalObjects,
  166. &pIniComp->_dwResumeHandle
  167. );
  168. if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){
  169. SetLastError(nasStatus);
  170. return(FALSE);
  171. }
  172. if (nasStatus != ERROR_MORE_DATA) {
  173. pIniComp->_bNoMore = TRUE;
  174. }
  175. pGroupInfo2 = (PGROUP_INFO_2) pIniComp->_pBuffer;
  176. if ( (!pIniComp->_dwObjectReturned)) {
  177. //
  178. // We get success code (ERROR_SUCCESS) but the buffer was NULL:
  179. // -> no global group was enumerated from the svr
  180. //
  181. return(FALSE);
  182. } else if ( (1 == pIniComp->_dwTotalObjects) &&
  183. (DOMAIN_GROUP_RID_USERS == pGroupInfo2->grpi2_group_id) ) {
  184. // check if this is the none group. Only returned by non-DCs.
  185. nasStatus = NetServerGetInfo(
  186. pIniComp->szUncCompName,
  187. 101,
  188. (LPBYTE *)&lpServerInfo
  189. );
  190. hr = HRESULT_FROM_WIN32(nasStatus);
  191. BAIL_ON_FAILURE(hr);
  192. if(!( (lpServerInfo->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
  193. (lpServerInfo->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) ) ) {
  194. NetApiBufferFree(lpServerInfo);
  195. (pIniComp->_dwCurrentObject)++;
  196. return (FALSE);
  197. }
  198. else // it is a DC. Fall through.
  199. ;
  200. }
  201. }
  202. dwRet = BuildWinNTGroupFromGlobalGroup(
  203. hComputer,
  204. (LPBYTE)((PGROUP_INFO_2) pIniComp->_pBuffer + pIniComp->_dwCurrentObject),
  205. ppGroup
  206. );
  207. if (!dwRet) {
  208. goto error;
  209. }
  210. pIniComp->_dwCurrentObject++;
  211. if(lpServerInfo)
  212. NetApiBufferFree(lpServerInfo);
  213. return(TRUE);
  214. error:
  215. if(lpServerInfo)
  216. NetApiBufferFree(lpServerInfo);
  217. return(FALSE);
  218. }
  219. BOOL
  220. WinNTEnumLocalGroups(
  221. HANDLE hComputer,
  222. DWORD dwRequested,
  223. LPBYTE * ppBuffer,
  224. PDWORD pdwReturned
  225. )
  226. {
  227. LPWINNT_GROUP * ppGroup = NULL;
  228. DWORD i = 0;
  229. BOOL dwRet = FALSE;
  230. DWORD dwReturned = 0;
  231. DWORD dwSize = 0;
  232. LPWINNT_GROUP pBuffer = NULL;
  233. LPBYTE pEnd = NULL;
  234. BOOL fretVal = FALSE;
  235. ppGroup = (LPWINNT_GROUP *)AllocADsMem(
  236. sizeof(LPWINNT_GROUP)* dwRequested
  237. );
  238. if (!ppGroup) {
  239. return(FALSE);
  240. }
  241. for (i = 0; i < dwRequested; i++) {
  242. dwRet = WinNTComputerGetLocalGroup(
  243. hComputer,
  244. &ppGroup[i]
  245. );
  246. if (!dwRet) {
  247. break;
  248. }
  249. }
  250. dwReturned = i;
  251. dwRet = ComputeWinNTGroupDataSize(
  252. ppGroup,
  253. dwReturned,
  254. &dwSize
  255. );
  256. pBuffer = (LPWINNT_GROUP)AllocADsMem(
  257. dwSize
  258. );
  259. if (pBuffer) {
  260. fretVal = TRUE;
  261. pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
  262. for (i = 0; i < dwReturned; i++) {
  263. pEnd = CopyIniWinNTGroupToWinNTGroup(
  264. ppGroup[i],
  265. (LPBYTE)(pBuffer + i),
  266. pEnd
  267. );
  268. }
  269. }
  270. for (i = 0; i < dwReturned; i++ ) {
  271. FreeIntWinNTGroup(*(ppGroup + i));
  272. }
  273. FreeADsMem(ppGroup);
  274. //
  275. // Will correctly assign to NULL if alloc failed.
  276. //
  277. *ppBuffer = (LPBYTE)pBuffer;
  278. *pdwReturned = fretVal ? dwReturned : 0;
  279. if (!fretVal) {
  280. return(FALSE);
  281. }
  282. if (dwReturned == dwRequested){
  283. return(TRUE);
  284. }else {
  285. return(FALSE);
  286. }
  287. }
  288. BOOL
  289. WinNTComputerGetLocalGroup(
  290. HANDLE hComputer,
  291. LPWINNT_GROUP * ppGroup
  292. )
  293. {
  294. BOOL dwRet = FALSE;
  295. PINICOMPUTER pIniComp = (PINICOMPUTER)hComputer;
  296. NET_API_STATUS nasStatus = 0;
  297. LPGROUP_INFO_0 pGroupInfo0 = NULL;
  298. if ((!pIniComp->_pBuffer) ||
  299. (pIniComp->_dwCurrentObject == pIniComp->_dwObjectReturned)) {
  300. if (pIniComp->_bNoMore) {
  301. //
  302. // No more objects to return
  303. //
  304. return(FALSE);
  305. }
  306. if (pIniComp->_pBuffer) {
  307. NetApiBufferFree(pIniComp->_pBuffer);
  308. pIniComp->_pBuffer = NULL;
  309. }
  310. pIniComp->_dwObjectReturned = 0;
  311. pIniComp->_dwCurrentObject = 0;
  312. pIniComp->_dwTotalObjects = 0;
  313. nasStatus = NetLocalGroupEnum(
  314. pIniComp->szUncCompName,
  315. 0,
  316. &pIniComp->_pBuffer,
  317. MAX_PREFERRED_LENGTH,
  318. &pIniComp->_dwObjectReturned,
  319. &pIniComp->_dwTotalObjects,
  320. &pIniComp->_dwResumeHandle
  321. );
  322. if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){
  323. SetLastError(nasStatus);
  324. return(FALSE);
  325. }
  326. if (nasStatus != ERROR_MORE_DATA) {
  327. pIniComp->_bNoMore = TRUE;
  328. }
  329. pGroupInfo0 = (LPGROUP_INFO_0) pIniComp->_pBuffer;
  330. if ( (!pIniComp->_dwObjectReturned)) {
  331. //
  332. // We get success code (ERROR_SUCCESS) but the buffer was NULL:
  333. // -> no global group was enumerated from the svr
  334. //
  335. return(FALSE);
  336. }
  337. // we will never get none group as a local group
  338. }
  339. dwRet = BuildWinNTGroupFromLocalGroup(
  340. hComputer,
  341. (LPBYTE)((LPLOCALGROUP_INFO_0)pIniComp->_pBuffer + pIniComp->_dwCurrentObject),
  342. ppGroup
  343. );
  344. if (!dwRet) {
  345. goto error;
  346. }
  347. pIniComp->_dwCurrentObject++;
  348. return(TRUE);
  349. error:
  350. return(FALSE);
  351. }
  352. LPBYTE
  353. CopyIniWinNTGroupToWinNTGroup(
  354. LPWINNT_GROUP pIntGrp,
  355. LPBYTE pExtGrp,
  356. LPBYTE pEnd
  357. )
  358. {
  359. LPWSTR SourceStrings[sizeof(WINNT_GROUP)/sizeof(LPWSTR)];
  360. LPWSTR *pSourceStrings=SourceStrings;
  361. LPWINNT_GROUP pWinNTGrp = (LPWINNT_GROUP)pExtGrp;
  362. memset(SourceStrings, 0, sizeof(WINNT_GROUP));
  363. *pSourceStrings++ = pIntGrp->Parent;
  364. *pSourceStrings++ = pIntGrp->Computer;
  365. *pSourceStrings++ = pIntGrp->Domain;
  366. *pSourceStrings++ = pIntGrp->Name;
  367. pEnd = PackStrings(
  368. SourceStrings,
  369. pExtGrp,
  370. WinNTGroupStrings,
  371. pEnd
  372. );
  373. pWinNTGrp->Type = pIntGrp->Type;
  374. return pEnd;
  375. }
  376. BOOL
  377. BuildWinNTGroupFromGlobalGroup(
  378. HANDLE hComputer,
  379. LPBYTE lpBuffer,
  380. LPWINNT_GROUP * ppGroup
  381. )
  382. {
  383. LPINICOMPUTER pComputer = (LPINICOMPUTER)hComputer;
  384. LPWINNT_GROUP pGroup = NULL;
  385. PGROUP_INFO_2 pGrp = (PGROUP_INFO_2)lpBuffer;
  386. WCHAR szADsParent[MAX_PATH];
  387. LPWSTR pMemberName = NULL;
  388. DWORD cblen = 0;
  389. pGroup = (LPWINNT_GROUP)AllocADsMem(
  390. sizeof(WINNT_GROUP)
  391. );
  392. if (!pGroup) {
  393. return(FALSE);
  394. }
  395. //
  396. // Begin Global Group -> WinNT Group Mapping
  397. //
  398. pGroup->Name = AllocADsStr(pGrp->grpi2_name);
  399. pGroup->Computer = AllocADsStr(pComputer->szComputerName);
  400. pGroup->Domain = AllocADsStr(pComputer->szDomainName);
  401. if (pComputer->uGroupParent == WINNT_DOMAIN_ID) {
  402. wsprintf(
  403. szADsParent,
  404. L"%s://%s",
  405. szProviderName,
  406. pComputer->szDomainName
  407. );
  408. }else {
  409. wsprintf(
  410. szADsParent,
  411. L"%s://%s/%s",
  412. szProviderName,
  413. pComputer->szDomainName,
  414. pComputer->szComputerName
  415. );
  416. }
  417. pGroup->Parent = AllocADsStr(szADsParent);
  418. pGroup->Type = WINNT_GROUP_GLOBAL;
  419. //
  420. // End Global Group -> WinNT Group Mapping
  421. //
  422. *ppGroup = pGroup;
  423. return(TRUE);
  424. // error:
  425. return(FALSE);
  426. }
  427. BOOL
  428. BuildWinNTGroupFromLocalGroup(
  429. HANDLE hComputer,
  430. LPBYTE lpBuffer,
  431. LPWINNT_GROUP * ppGroup
  432. )
  433. {
  434. LPINICOMPUTER pComputer = (LPINICOMPUTER)hComputer;
  435. LPWINNT_GROUP pGroup = NULL;
  436. LPLOCALGROUP_INFO_0 pGrp = (LPLOCALGROUP_INFO_0)lpBuffer;
  437. WCHAR szADsParent[MAX_PATH];
  438. LPWSTR pMemberName = NULL;
  439. DWORD cblen = 0;
  440. pGroup = (LPWINNT_GROUP)AllocADsMem(
  441. sizeof(WINNT_GROUP)
  442. );
  443. if (!pGroup) {
  444. return(FALSE);
  445. }
  446. //
  447. // Begin Local Group -> WinNT Group Mapping
  448. //
  449. pGroup->Name = AllocADsStr(pGrp->lgrpi0_name);
  450. pGroup->Computer = AllocADsStr(pComputer->szComputerName);
  451. pGroup->Domain = AllocADsStr(pComputer->szDomainName);
  452. if (pComputer->uGroupParent == WINNT_DOMAIN_ID) {
  453. wsprintf(
  454. szADsParent,
  455. L"%s://%s",
  456. szProviderName,
  457. pComputer->szDomainName
  458. );
  459. }else {
  460. if (pComputer->szDomainName !=NULL) {
  461. wsprintf(
  462. szADsParent,
  463. L"%s://%s/%s",
  464. szProviderName,
  465. pComputer->szDomainName,
  466. pComputer->szComputerName
  467. );
  468. } else {
  469. // This is a case where domain is null, the
  470. // workstation service has not been started
  471. wsprintf(
  472. szADsParent,
  473. L"%s://%s",
  474. szProviderName,
  475. pComputer->szComputerName
  476. );
  477. }
  478. }
  479. pGroup->Parent = AllocADsStr(szADsParent);
  480. pGroup->Type = WINNT_GROUP_LOCAL;
  481. //
  482. // End Local Group -> WinNT Group Mapping
  483. //
  484. *ppGroup = pGroup;
  485. return(TRUE);
  486. // error:
  487. return(FALSE);
  488. }
  489. BOOL
  490. ComputeWinNTGroupDataSize(
  491. LPWINNT_GROUP * ppGroups,
  492. DWORD dwReturned,
  493. PDWORD pdwSize
  494. )
  495. {
  496. DWORD i = 0;
  497. DWORD cb = 0;
  498. LPWINNT_GROUP pGroup = NULL;
  499. for (i = 0; i < dwReturned; i++) {
  500. pGroup = *(ppGroups + i);
  501. cb += sizeof(WINNT_GROUP);
  502. if (pGroup->Parent) {
  503. cb += wcslen(pGroup->Parent)*sizeof(WCHAR) + sizeof(WCHAR);
  504. }
  505. if (pGroup->Computer) {
  506. cb += wcslen(pGroup->Computer)*sizeof(WCHAR) + sizeof(WCHAR);
  507. }
  508. if (pGroup->Domain) {
  509. cb += wcslen(pGroup->Domain)*sizeof(WCHAR) + sizeof(WCHAR);
  510. }
  511. if (pGroup->Name) {
  512. cb += wcslen(pGroup->Name)*sizeof(WCHAR) + sizeof(WCHAR);
  513. }
  514. }
  515. *pdwSize = cb;
  516. return(TRUE);
  517. }
  518. BOOL
  519. WinNTCloseComputer(
  520. HANDLE hComputer
  521. )
  522. {
  523. PINICOMPUTER pIniComputer = (PINICOMPUTER)hComputer;
  524. if (pIniComputer) {
  525. FreeIniComputer(pIniComputer);
  526. }
  527. return(TRUE);
  528. }
  529. void
  530. FreeIniComputer(
  531. PINICOMPUTER pIniComputer
  532. )
  533. {
  534. if (pIniComputer->szDomainName) {
  535. FreeADsStr(pIniComputer->szDomainName);
  536. }
  537. if (pIniComputer->szDomainName) {
  538. FreeADsStr(pIniComputer->szComputerName);
  539. }
  540. if (pIniComputer->szUncCompName) {
  541. FreeADsStr(pIniComputer->szUncCompName);
  542. }
  543. if (pIniComputer->_pBuffer) {
  544. NetApiBufferFree(pIniComputer->_pBuffer);
  545. }
  546. FreeADsMem(pIniComputer);
  547. return;
  548. }
  549. void
  550. FreeIntWinNTGroup(
  551. LPWINNT_GROUP pGroup
  552. )
  553. {
  554. if (pGroup->Parent) {
  555. FreeADsStr(pGroup->Parent);
  556. }
  557. if (pGroup->Computer) {
  558. FreeADsStr(pGroup->Computer);
  559. }
  560. if (pGroup->Domain) {
  561. FreeADsStr(pGroup->Domain);
  562. }
  563. if (pGroup->Name) {
  564. FreeADsStr(pGroup->Name);
  565. }
  566. if (pGroup) {
  567. FreeADsMem(pGroup);
  568. }
  569. return;
  570. }