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.

759 lines
17 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. DSROLE_PRIMARY_DOMAIN_INFO_BASIC* pdomainInfo = NULL;
  143. DWORD dwResult = ERROR_SUCCESS;
  144. HRESULT hr = S_OK;
  145. if ((!pIniComp->_pBuffer) ||
  146. (pIniComp->_dwCurrentObject == pIniComp->_dwObjectReturned)) {
  147. if (pIniComp->_bNoMore) {
  148. //
  149. // No more objects to return
  150. //
  151. return(FALSE);
  152. }
  153. if (pIniComp->_pBuffer) {
  154. NetApiBufferFree(pIniComp->_pBuffer);
  155. pIniComp->_pBuffer = NULL;
  156. }
  157. pIniComp->_dwObjectReturned = 0;
  158. pIniComp->_dwCurrentObject = 0;
  159. pIniComp->_dwTotalObjects = 0;
  160. nasStatus = NetGroupEnum(
  161. pIniComp->szUncCompName,
  162. 2,
  163. &pIniComp->_pBuffer,
  164. MAX_PREFERRED_LENGTH,
  165. &pIniComp->_dwObjectReturned,
  166. &pIniComp->_dwTotalObjects,
  167. &pIniComp->_dwResumeHandle
  168. );
  169. if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){
  170. SetLastError(nasStatus);
  171. return(FALSE);
  172. }
  173. if (nasStatus != ERROR_MORE_DATA) {
  174. pIniComp->_bNoMore = TRUE;
  175. }
  176. pGroupInfo2 = (PGROUP_INFO_2) pIniComp->_pBuffer;
  177. if ( (!pIniComp->_dwObjectReturned)) {
  178. //
  179. // We get success code (ERROR_SUCCESS) but the buffer was NULL:
  180. // -> no global group was enumerated from the svr
  181. //
  182. return(FALSE);
  183. } else if ( (1 == pIniComp->_dwTotalObjects) &&
  184. (DOMAIN_GROUP_RID_USERS == pGroupInfo2->grpi2_group_id) ) {
  185. // check if this is the none group. Only returned by non-DCs.
  186. dwResult = DsRoleGetPrimaryDomainInformation(
  187. pIniComp->szUncCompName,
  188. DsRolePrimaryDomainInfoBasic, // InfoLevel
  189. (PBYTE*)&pdomainInfo // pBuffer
  190. );
  191. hr = HRESULT_FROM_WIN32(dwResult);
  192. BAIL_ON_FAILURE(hr);
  193. if(!( (pdomainInfo->MachineRole == DsRole_RoleBackupDomainController) ||
  194. (pdomainInfo->MachineRole == DsRole_RolePrimaryDomainController) ) ) {
  195. DsRoleFreeMemory(pdomainInfo);
  196. (pIniComp->_dwCurrentObject)++;
  197. return (FALSE);
  198. }
  199. else // it is a DC. Fall through.
  200. ;
  201. }
  202. }
  203. dwRet = BuildWinNTGroupFromGlobalGroup(
  204. hComputer,
  205. (LPBYTE)((PGROUP_INFO_2) pIniComp->_pBuffer + pIniComp->_dwCurrentObject),
  206. ppGroup
  207. );
  208. if (!dwRet) {
  209. goto error;
  210. }
  211. pIniComp->_dwCurrentObject++;
  212. if(pdomainInfo)
  213. {
  214. DsRoleFreeMemory(pdomainInfo);
  215. }
  216. return(TRUE);
  217. error:
  218. if(pdomainInfo)
  219. {
  220. DsRoleFreeMemory(pdomainInfo);
  221. }
  222. return(FALSE);
  223. }
  224. BOOL
  225. WinNTEnumLocalGroups(
  226. HANDLE hComputer,
  227. DWORD dwRequested,
  228. LPBYTE * ppBuffer,
  229. PDWORD pdwReturned
  230. )
  231. {
  232. LPWINNT_GROUP * ppGroup = NULL;
  233. DWORD i = 0;
  234. BOOL dwRet = FALSE;
  235. DWORD dwReturned = 0;
  236. DWORD dwSize = 0;
  237. LPWINNT_GROUP pBuffer = NULL;
  238. LPBYTE pEnd = NULL;
  239. BOOL fretVal = FALSE;
  240. ppGroup = (LPWINNT_GROUP *)AllocADsMem(
  241. sizeof(LPWINNT_GROUP)* dwRequested
  242. );
  243. if (!ppGroup) {
  244. return(FALSE);
  245. }
  246. for (i = 0; i < dwRequested; i++) {
  247. dwRet = WinNTComputerGetLocalGroup(
  248. hComputer,
  249. &ppGroup[i]
  250. );
  251. if (!dwRet) {
  252. break;
  253. }
  254. }
  255. dwReturned = i;
  256. dwRet = ComputeWinNTGroupDataSize(
  257. ppGroup,
  258. dwReturned,
  259. &dwSize
  260. );
  261. pBuffer = (LPWINNT_GROUP)AllocADsMem(
  262. dwSize
  263. );
  264. if (pBuffer) {
  265. fretVal = TRUE;
  266. pEnd = (LPBYTE)((LPBYTE)(pBuffer) + dwSize);
  267. for (i = 0; i < dwReturned; i++) {
  268. pEnd = CopyIniWinNTGroupToWinNTGroup(
  269. ppGroup[i],
  270. (LPBYTE)(pBuffer + i),
  271. pEnd
  272. );
  273. }
  274. }
  275. for (i = 0; i < dwReturned; i++ ) {
  276. FreeIntWinNTGroup(*(ppGroup + i));
  277. }
  278. FreeADsMem(ppGroup);
  279. //
  280. // Will correctly assign to NULL if alloc failed.
  281. //
  282. *ppBuffer = (LPBYTE)pBuffer;
  283. *pdwReturned = fretVal ? dwReturned : 0;
  284. if (!fretVal) {
  285. return(FALSE);
  286. }
  287. if (dwReturned == dwRequested){
  288. return(TRUE);
  289. }else {
  290. return(FALSE);
  291. }
  292. }
  293. BOOL
  294. WinNTComputerGetLocalGroup(
  295. HANDLE hComputer,
  296. LPWINNT_GROUP * ppGroup
  297. )
  298. {
  299. BOOL dwRet = FALSE;
  300. PINICOMPUTER pIniComp = (PINICOMPUTER)hComputer;
  301. NET_API_STATUS nasStatus = 0;
  302. LPGROUP_INFO_0 pGroupInfo0 = NULL;
  303. if ((!pIniComp->_pBuffer) ||
  304. (pIniComp->_dwCurrentObject == pIniComp->_dwObjectReturned)) {
  305. if (pIniComp->_bNoMore) {
  306. //
  307. // No more objects to return
  308. //
  309. return(FALSE);
  310. }
  311. if (pIniComp->_pBuffer) {
  312. NetApiBufferFree(pIniComp->_pBuffer);
  313. pIniComp->_pBuffer = NULL;
  314. }
  315. pIniComp->_dwObjectReturned = 0;
  316. pIniComp->_dwCurrentObject = 0;
  317. pIniComp->_dwTotalObjects = 0;
  318. nasStatus = NetLocalGroupEnum(
  319. pIniComp->szUncCompName,
  320. 0,
  321. &pIniComp->_pBuffer,
  322. MAX_PREFERRED_LENGTH,
  323. &pIniComp->_dwObjectReturned,
  324. &pIniComp->_dwTotalObjects,
  325. &pIniComp->_dwResumeHandle
  326. );
  327. if ((nasStatus != ERROR_SUCCESS) && (nasStatus != ERROR_MORE_DATA)){
  328. SetLastError(nasStatus);
  329. return(FALSE);
  330. }
  331. if (nasStatus != ERROR_MORE_DATA) {
  332. pIniComp->_bNoMore = TRUE;
  333. }
  334. pGroupInfo0 = (LPGROUP_INFO_0) pIniComp->_pBuffer;
  335. if ( (!pIniComp->_dwObjectReturned)) {
  336. //
  337. // We get success code (ERROR_SUCCESS) but the buffer was NULL:
  338. // -> no global group was enumerated from the svr
  339. //
  340. return(FALSE);
  341. }
  342. // we will never get none group as a local group
  343. }
  344. dwRet = BuildWinNTGroupFromLocalGroup(
  345. hComputer,
  346. (LPBYTE)((LPLOCALGROUP_INFO_0)pIniComp->_pBuffer + pIniComp->_dwCurrentObject),
  347. ppGroup
  348. );
  349. if (!dwRet) {
  350. goto error;
  351. }
  352. pIniComp->_dwCurrentObject++;
  353. return(TRUE);
  354. error:
  355. return(FALSE);
  356. }
  357. LPBYTE
  358. CopyIniWinNTGroupToWinNTGroup(
  359. LPWINNT_GROUP pIntGrp,
  360. LPBYTE pExtGrp,
  361. LPBYTE pEnd
  362. )
  363. {
  364. LPWSTR SourceStrings[sizeof(WINNT_GROUP)/sizeof(LPWSTR)];
  365. LPWSTR *pSourceStrings=SourceStrings;
  366. LPWINNT_GROUP pWinNTGrp = (LPWINNT_GROUP)pExtGrp;
  367. memset(SourceStrings, 0, sizeof(WINNT_GROUP));
  368. *pSourceStrings++ = pIntGrp->Parent;
  369. *pSourceStrings++ = pIntGrp->Computer;
  370. *pSourceStrings++ = pIntGrp->Domain;
  371. *pSourceStrings++ = pIntGrp->Name;
  372. pEnd = PackStrings(
  373. SourceStrings,
  374. pExtGrp,
  375. WinNTGroupStrings,
  376. pEnd
  377. );
  378. pWinNTGrp->Type = pIntGrp->Type;
  379. return pEnd;
  380. }
  381. BOOL
  382. BuildWinNTGroupFromGlobalGroup(
  383. HANDLE hComputer,
  384. LPBYTE lpBuffer,
  385. LPWINNT_GROUP * ppGroup
  386. )
  387. {
  388. LPINICOMPUTER pComputer = (LPINICOMPUTER)hComputer;
  389. LPWINNT_GROUP pGroup = NULL;
  390. PGROUP_INFO_2 pGrp = (PGROUP_INFO_2)lpBuffer;
  391. WCHAR szADsParent[MAX_PATH];
  392. LPWSTR pMemberName = NULL;
  393. DWORD cblen = 0;
  394. pGroup = (LPWINNT_GROUP)AllocADsMem(
  395. sizeof(WINNT_GROUP)
  396. );
  397. if (!pGroup) {
  398. return(FALSE);
  399. }
  400. //
  401. // Begin Global Group -> WinNT Group Mapping
  402. //
  403. pGroup->Name = AllocADsStr(pGrp->grpi2_name);
  404. pGroup->Computer = AllocADsStr(pComputer->szComputerName);
  405. pGroup->Domain = AllocADsStr(pComputer->szDomainName);
  406. if (pComputer->uGroupParent == WINNT_DOMAIN_ID) {
  407. wsprintf(
  408. szADsParent,
  409. L"%s://%s",
  410. szProviderName,
  411. pComputer->szDomainName
  412. );
  413. }else {
  414. wsprintf(
  415. szADsParent,
  416. L"%s://%s/%s",
  417. szProviderName,
  418. pComputer->szDomainName,
  419. pComputer->szComputerName
  420. );
  421. }
  422. pGroup->Parent = AllocADsStr(szADsParent);
  423. pGroup->Type = WINNT_GROUP_GLOBAL;
  424. //
  425. // End Global Group -> WinNT Group Mapping
  426. //
  427. *ppGroup = pGroup;
  428. return(TRUE);
  429. // error:
  430. return(FALSE);
  431. }
  432. BOOL
  433. BuildWinNTGroupFromLocalGroup(
  434. HANDLE hComputer,
  435. LPBYTE lpBuffer,
  436. LPWINNT_GROUP * ppGroup
  437. )
  438. {
  439. LPINICOMPUTER pComputer = (LPINICOMPUTER)hComputer;
  440. LPWINNT_GROUP pGroup = NULL;
  441. LPLOCALGROUP_INFO_0 pGrp = (LPLOCALGROUP_INFO_0)lpBuffer;
  442. WCHAR szADsParent[MAX_PATH];
  443. LPWSTR pMemberName = NULL;
  444. DWORD cblen = 0;
  445. pGroup = (LPWINNT_GROUP)AllocADsMem(
  446. sizeof(WINNT_GROUP)
  447. );
  448. if (!pGroup) {
  449. return(FALSE);
  450. }
  451. //
  452. // Begin Local Group -> WinNT Group Mapping
  453. //
  454. pGroup->Name = AllocADsStr(pGrp->lgrpi0_name);
  455. pGroup->Computer = AllocADsStr(pComputer->szComputerName);
  456. pGroup->Domain = AllocADsStr(pComputer->szDomainName);
  457. if (pComputer->uGroupParent == WINNT_DOMAIN_ID) {
  458. wsprintf(
  459. szADsParent,
  460. L"%s://%s",
  461. szProviderName,
  462. pComputer->szDomainName
  463. );
  464. }else {
  465. if (pComputer->szDomainName !=NULL) {
  466. wsprintf(
  467. szADsParent,
  468. L"%s://%s/%s",
  469. szProviderName,
  470. pComputer->szDomainName,
  471. pComputer->szComputerName
  472. );
  473. } else {
  474. // This is a case where domain is null, the
  475. // workstation service has not been started
  476. wsprintf(
  477. szADsParent,
  478. L"%s://%s",
  479. szProviderName,
  480. pComputer->szComputerName
  481. );
  482. }
  483. }
  484. pGroup->Parent = AllocADsStr(szADsParent);
  485. pGroup->Type = WINNT_GROUP_LOCAL;
  486. //
  487. // End Local Group -> WinNT Group Mapping
  488. //
  489. *ppGroup = pGroup;
  490. return(TRUE);
  491. // error:
  492. return(FALSE);
  493. }
  494. BOOL
  495. ComputeWinNTGroupDataSize(
  496. LPWINNT_GROUP * ppGroups,
  497. DWORD dwReturned,
  498. PDWORD pdwSize
  499. )
  500. {
  501. DWORD i = 0;
  502. DWORD cb = 0;
  503. LPWINNT_GROUP pGroup = NULL;
  504. for (i = 0; i < dwReturned; i++) {
  505. pGroup = *(ppGroups + i);
  506. cb += sizeof(WINNT_GROUP);
  507. if (pGroup->Parent) {
  508. cb += wcslen(pGroup->Parent)*sizeof(WCHAR) + sizeof(WCHAR);
  509. }
  510. if (pGroup->Computer) {
  511. cb += wcslen(pGroup->Computer)*sizeof(WCHAR) + sizeof(WCHAR);
  512. }
  513. if (pGroup->Domain) {
  514. cb += wcslen(pGroup->Domain)*sizeof(WCHAR) + sizeof(WCHAR);
  515. }
  516. if (pGroup->Name) {
  517. cb += wcslen(pGroup->Name)*sizeof(WCHAR) + sizeof(WCHAR);
  518. }
  519. }
  520. *pdwSize = cb;
  521. return(TRUE);
  522. }
  523. BOOL
  524. WinNTCloseComputer(
  525. HANDLE hComputer
  526. )
  527. {
  528. PINICOMPUTER pIniComputer = (PINICOMPUTER)hComputer;
  529. if (pIniComputer) {
  530. FreeIniComputer(pIniComputer);
  531. }
  532. return(TRUE);
  533. }
  534. void
  535. FreeIniComputer(
  536. PINICOMPUTER pIniComputer
  537. )
  538. {
  539. if (pIniComputer->szDomainName) {
  540. FreeADsStr(pIniComputer->szDomainName);
  541. }
  542. if (pIniComputer->szComputerName) {
  543. FreeADsStr(pIniComputer->szComputerName);
  544. }
  545. if (pIniComputer->szUncCompName) {
  546. FreeADsStr(pIniComputer->szUncCompName);
  547. }
  548. if (pIniComputer->_pBuffer) {
  549. NetApiBufferFree(pIniComputer->_pBuffer);
  550. }
  551. FreeADsMem(pIniComputer);
  552. return;
  553. }
  554. void
  555. FreeIntWinNTGroup(
  556. LPWINNT_GROUP pGroup
  557. )
  558. {
  559. if (pGroup->Parent) {
  560. FreeADsStr(pGroup->Parent);
  561. }
  562. if (pGroup->Computer) {
  563. FreeADsStr(pGroup->Computer);
  564. }
  565. if (pGroup->Domain) {
  566. FreeADsStr(pGroup->Domain);
  567. }
  568. if (pGroup->Name) {
  569. FreeADsStr(pGroup->Name);
  570. }
  571. if (pGroup) {
  572. FreeADsMem(pGroup);
  573. }
  574. return;
  575. }