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.

798 lines
27 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: getuser.cpp
  7. //
  8. // Contents: implementation of CGetUser
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "GetUser.h"
  14. #include "util.h"
  15. #include "wrapper.h"
  16. #ifdef _DEBUG
  17. #undef THIS_FILE
  18. static char THIS_FILE[]=__FILE__;
  19. #define new DEBUG_NEW
  20. #endif
  21. const TCHAR c_szSep[] = TEXT("\\");
  22. //////////////////////////////////////////////////////////////////////
  23. // CGetUser Class
  24. //////////////////////////////////////////////////////////////////////
  25. //////////////////////////////////////////////////////////////////////
  26. // Construction/Destruction
  27. //////////////////////////////////////////////////////////////////////
  28. CTypedPtrArray<CPtrArray, PWSCE_ACCOUNTINFO> CGetUser::m_aKnownAccounts;
  29. BOOL IsDomainAccountSid( PSID pSid )
  30. {
  31. if ( pSid == NULL ) {
  32. return(FALSE);
  33. }
  34. if ( !IsValidSid(pSid) ) {
  35. return(FALSE);
  36. }
  37. PISID ISid = (PISID)pSid;
  38. if ( ISid->IdentifierAuthority.Value[5] != 5 ||
  39. ISid->IdentifierAuthority.Value[0] != 0 ||
  40. ISid->IdentifierAuthority.Value[1] != 0 ||
  41. ISid->IdentifierAuthority.Value[2] != 0 ||
  42. ISid->IdentifierAuthority.Value[3] != 0 ||
  43. ISid->IdentifierAuthority.Value[4] != 0 ) {
  44. //
  45. // this is not a account from account domain
  46. //
  47. return(FALSE);
  48. }
  49. if ( ISid->SubAuthorityCount == 0 ||
  50. ISid->SubAuthority[0] != SECURITY_NT_NON_UNIQUE ) {
  51. return(FALSE);
  52. }
  53. return(TRUE);
  54. }
  55. /*------------------------------------------------------------------------------------------------------------
  56. CGetUser::GetAccountType
  57. Synopsis: Returns the type of the user account. Call this function with a NULL to remove saved
  58. account name information.
  59. Arguments: [pszName] - The account name old NT4 format
  60. Returns: One of the enumerated Sid types.
  61. ------------------------------------------------------------------------------------------------------------*/
  62. SID_NAME_USE
  63. CGetUser::GetAccountType(LPCTSTR pszName)
  64. {
  65. if(!pszName){
  66. // Delete the whole list.
  67. for(int i = 0; i < m_aKnownAccounts.GetSize(); i++){
  68. PWSCE_ACCOUNTINFO pAccount = m_aKnownAccounts[i];
  69. if(pAccount){
  70. if(pAccount->pszName){
  71. LocalFree(pAccount->pszName);
  72. }
  73. LocalFree(pAccount);
  74. }
  75. }
  76. m_aKnownAccounts.RemoveAll();
  77. return SidTypeUnknown;
  78. }
  79. // Check to see if we've already got the account.
  80. for(int i = 0; i < m_aKnownAccounts.GetSize(); i++){
  81. if( !lstrcmpi( m_aKnownAccounts[i]->pszName, pszName) ){
  82. return m_aKnownAccounts[i]->sidType;
  83. }
  84. }
  85. PSID sid = NULL;
  86. LPTSTR pszDomain = NULL;
  87. DWORD cbSid = 0,
  88. cbRefDomain = 0;
  89. SID_NAME_USE type = SidTypeUnknown;
  90. LookupAccountName(
  91. NULL,
  92. pszName,
  93. sid,
  94. &cbSid,
  95. NULL,
  96. &cbRefDomain,
  97. &type
  98. );
  99. if(cbSid){
  100. sid = (PSID)LocalAlloc(0, cbSid);
  101. if(!sid){
  102. return SidTypeUnknown;
  103. }
  104. pszDomain = (LPTSTR)LocalAlloc(0, (cbRefDomain + 1) * sizeof(TCHAR));
  105. if(!pszDomain){
  106. cbRefDomain = 0;
  107. }
  108. type = SidTypeUser;
  109. if( LookupAccountName(
  110. NULL,
  111. pszName,
  112. sid,
  113. &cbSid,
  114. pszDomain,
  115. &cbRefDomain,
  116. &type
  117. ) ){
  118. //
  119. // Add the account name to the list.
  120. //
  121. PWSCE_ACCOUNTINFO pNew = (PWSCE_ACCOUNTINFO)LocalAlloc(0, sizeof(WSCE_ACCOUNTINFO));
  122. if(pNew){
  123. pNew->pszName = (LPTSTR)LocalAlloc(0, (lstrlen( pszName ) + 1) * sizeof(TCHAR));
  124. if(!pNew->pszName){
  125. LocalFree(pNew);
  126. LocalFree(sid);
  127. if ( pszDomain ) {
  128. LocalFree(pszDomain);
  129. }
  130. return SidTypeUnknown;
  131. }
  132. // This is a safe usage.
  133. lstrcpy(pNew->pszName, pszName);
  134. pNew->sidType = type;
  135. m_aKnownAccounts.Add(pNew);
  136. }
  137. }
  138. LocalFree(sid);
  139. if(pszDomain){
  140. LocalFree(pszDomain);
  141. }
  142. }
  143. return type;
  144. }
  145. CGetUser::CGetUser()
  146. {
  147. m_pszServerName = NULL;
  148. m_pNameList = NULL;
  149. }
  150. CGetUser::~CGetUser()
  151. {
  152. PSCE_NAME_LIST p;
  153. while(m_pNameList) {
  154. p=m_pNameList;
  155. m_pNameList = m_pNameList->Next;
  156. LocalFree(p->Name);
  157. LocalFree(p);
  158. }
  159. }
  160. BOOL CGetUser::Create(HWND hwnd, DWORD nShowFlag)
  161. {
  162. if( m_pNameList ) {
  163. return FALSE;
  164. }
  165. HRESULT hr = S_OK;
  166. IDsObjectPicker *pDsObjectPicker;
  167. BOOL bRet = TRUE;
  168. PSCE_NAME_LIST pName;
  169. BOOL bDC = IsDomainController( m_pszServerName );
  170. BOOL bHasADsPath;
  171. //
  172. // Initialize and get the Object picker interface.
  173. //
  174. hr = CoInitialize(NULL);
  175. if (!SUCCEEDED(hr)) {
  176. return FALSE;
  177. }
  178. // This is a safe usage.
  179. hr = CoCreateInstance(
  180. CLSID_DsObjectPicker,
  181. NULL,
  182. CLSCTX_INPROC_SERVER,
  183. IID_IDsObjectPicker,
  184. (void **) &pDsObjectPicker
  185. );
  186. if(!SUCCEEDED(hr)){
  187. CoUninitialize();
  188. return FALSE;
  189. }
  190. #define SCE_SCOPE_INDEX_DOMAIN 0
  191. #define SCE_SCOPE_INDEX_DIRECTORY 1
  192. #define SCE_SCOPE_INDEX_LOCAL 2
  193. #define SCE_SCOPE_INDEX_ROOT 3 //Raid #522908, 2/23/2002, yanggao
  194. #define SCE_SCOPE_INDEX_EXUP 4
  195. #define SCE_NUM_SCOPE_INDICES 5
  196. DSOP_SCOPE_INIT_INFO aScopes[SCE_NUM_SCOPE_INDICES];
  197. DSOP_SCOPE_INIT_INFO aScopesUsed[SCE_NUM_SCOPE_INDICES];
  198. ZeroMemory(aScopes, sizeof(aScopes));
  199. ZeroMemory(aScopesUsed, sizeof(aScopesUsed));
  200. DWORD dwDownLevel = 0, dwUpLevel = 0;
  201. //
  202. // Users
  203. //
  204. if (nShowFlag & SCE_SHOW_USERS ) {
  205. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_USERS;
  206. dwUpLevel |= DSOP_FILTER_USERS ;
  207. }
  208. if( nShowFlag & SCE_SHOW_LOCALGROUPS ){
  209. dwUpLevel |= DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  210. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS | DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  211. if (nShowFlag & SCE_SHOW_COMPUTER ) //Raid #477428, Yanggao
  212. {
  213. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  214. dwUpLevel |= DSOP_FILTER_COMPUTERS ;
  215. }
  216. }
  217. if( nShowFlag & SCE_SHOW_BUILTIN ){
  218. dwUpLevel |= DSOP_FILTER_BUILTIN_GROUPS;
  219. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS | DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  220. } else {
  221. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS;
  222. }
  223. //
  224. // Built in groups.
  225. //
  226. if (nShowFlag & SCE_SHOW_GROUPS ) {
  227. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS | DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS;
  228. dwUpLevel |= DSOP_FILTER_BUILTIN_GROUPS;
  229. }
  230. //
  231. // Domain groups.
  232. //
  233. if( nShowFlag & (SCE_SHOW_GROUPS | SCE_SHOW_DOMAINGROUPS | SCE_SHOW_ALIASES | SCE_SHOW_GLOBAL) ){
  234. if( !(nShowFlag & SCE_SHOW_LOCALONLY)){
  235. dwUpLevel |= DSOP_FILTER_UNIVERSAL_GROUPS_SE
  236. | DSOP_FILTER_GLOBAL_GROUPS_SE
  237. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  238. } else if(bDC){
  239. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_AUTHENTICATED_USER;
  240. dwUpLevel |= DSOP_FILTER_GLOBAL_GROUPS_SE
  241. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  242. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  243. }
  244. if (nShowFlag & SCE_SHOW_COMPUTER ) //Raid #477428, Yanggao
  245. {
  246. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  247. dwUpLevel |= DSOP_FILTER_COMPUTERS ;
  248. }
  249. }
  250. //
  251. //
  252. // principal well known sids.
  253. //
  254. if( (!(nShowFlag & SCE_SHOW_LOCALONLY) &&
  255. nShowFlag & SCE_SHOW_GROUPS &&
  256. nShowFlag & SCE_SHOW_USERS) ||
  257. nShowFlag & SCE_SHOW_WELLKNOWN ){
  258. /*
  259. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_CREATOR_OWNER
  260. | DSOP_DOWNLEVEL_FILTER_CREATOR_GROUP
  261. | DSOP_DOWNLEVEL_FILTER_INTERACTIVE
  262. | DSOP_DOWNLEVEL_FILTER_SYSTEM
  263. | DSOP_DOWNLEVEL_FILTER_AUTHENTICATED_USER
  264. | DSOP_DOWNLEVEL_FILTER_WORLD
  265. | DSOP_DOWNLEVEL_FILTER_ANONYMOUS
  266. | DSOP_DOWNLEVEL_FILTER_BATCH
  267. | DSOP_DOWNLEVEL_FILTER_DIALUP
  268. | DSOP_DOWNLEVEL_FILTER_NETWORK
  269. | DSOP_DOWNLEVEL_FILTER_SERVICE
  270. | DSOP_DOWNLEVEL_FILTER_TERMINAL_SERVER
  271. | DSOP_DOWNLEVEL_FILTER_LOCAL_SERVICE
  272. | DSOP_DOWNLEVEL_FILTER_NETWORK_SERVICE
  273. | DSOP_DOWNLEVEL_FILTER_REMOTE_LOGON;
  274. */
  275. dwDownLevel |= DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS;
  276. dwUpLevel |= DSOP_FILTER_WELL_KNOWN_PRINCIPALS;
  277. }
  278. DSOP_INIT_INFO InitInfo;
  279. ZeroMemory(&InitInfo, sizeof(InitInfo));
  280. //
  281. // Other attributes that we need object picker to return to use.
  282. //
  283. PCWSTR aAttributes[] = { L"groupType",
  284. L"objectSid" };
  285. InitInfo.cAttributesToFetch = 2;
  286. InitInfo.apwzAttributeNames = aAttributes;
  287. //
  288. // First Item we want to view is the local computer.
  289. //
  290. aScopes[SCE_SCOPE_INDEX_LOCAL].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  291. aScopes[SCE_SCOPE_INDEX_LOCAL].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  292. aScopes[SCE_SCOPE_INDEX_LOCAL].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  293. aScopes[SCE_SCOPE_INDEX_LOCAL].FilterFlags.Uplevel.flBothModes = dwUpLevel;
  294. aScopes[SCE_SCOPE_INDEX_LOCAL].FilterFlags.flDownlevel = dwDownLevel;
  295. //
  296. // Flags for the domain we're joined to.
  297. //
  298. aScopes[SCE_SCOPE_INDEX_DOMAIN].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  299. aScopes[SCE_SCOPE_INDEX_DOMAIN].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  300. aScopes[SCE_SCOPE_INDEX_DOMAIN].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE | DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT
  301. |DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS |DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS; //Raid #626152, Yanggao
  302. //
  303. // May need to differentiate native & mixed modes on non-DCs.
  304. //
  305. if (nShowFlag & SCE_SHOW_DIFF_MODE_OFF_DC && !bDC) {
  306. aScopes[SCE_SCOPE_INDEX_DOMAIN].FilterFlags.Uplevel.flNativeModeOnly = dwUpLevel;
  307. aScopes[SCE_SCOPE_INDEX_DOMAIN].FilterFlags.Uplevel.flMixedModeOnly =
  308. ( dwUpLevel & (~( DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE )) );
  309. } else {
  310. aScopes[SCE_SCOPE_INDEX_DOMAIN].FilterFlags.Uplevel.flBothModes = dwUpLevel;
  311. }
  312. aScopes[SCE_SCOPE_INDEX_DOMAIN].FilterFlags.flDownlevel = dwDownLevel;
  313. //
  314. // Next set flags for other scope items. Everything same, only not show builtin and local groups
  315. //
  316. aScopes[SCE_SCOPE_INDEX_DIRECTORY].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  317. aScopes[SCE_SCOPE_INDEX_DIRECTORY].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  318. aScopes[SCE_SCOPE_INDEX_DIRECTORY].FilterFlags.Uplevel.flBothModes = dwUpLevel; //Raid #516311, 2/23/2002, yanggao
  319. aScopes[SCE_SCOPE_INDEX_DIRECTORY].FilterFlags.flDownlevel = dwDownLevel;
  320. aScopes[SCE_SCOPE_INDEX_DIRECTORY].FilterFlags.flDownlevel |= DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS |
  321. DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  322. aScopes[SCE_SCOPE_INDEX_DIRECTORY].flType = DSOP_SCOPE_TYPE_WORKGROUP
  323. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  324. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE
  325. | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  326. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  327. //Root forest
  328. aScopes[SCE_SCOPE_INDEX_ROOT].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  329. aScopes[SCE_SCOPE_INDEX_ROOT].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  330. aScopes[SCE_SCOPE_INDEX_ROOT].FilterFlags.Uplevel.flBothModes = dwUpLevel;
  331. aScopes[SCE_SCOPE_INDEX_ROOT].FilterFlags.flDownlevel = dwDownLevel;
  332. aScopes[SCE_SCOPE_INDEX_ROOT].FilterFlags.flDownlevel |= DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS |
  333. DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  334. aScopes[SCE_SCOPE_INDEX_ROOT].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  335. //Entire forest
  336. aScopes[SCE_SCOPE_INDEX_EXUP].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  337. aScopes[SCE_SCOPE_INDEX_EXUP].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  338. aScopes[SCE_SCOPE_INDEX_EXUP].FilterFlags.Uplevel.flBothModes = dwUpLevel;
  339. aScopes[SCE_SCOPE_INDEX_EXUP].FilterFlags.flDownlevel = dwDownLevel;
  340. aScopes[SCE_SCOPE_INDEX_EXUP].FilterFlags.flDownlevel |= DSOP_DOWNLEVEL_FILTER_EXCLUDE_BUILTIN_GROUPS |
  341. DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  342. aScopes[SCE_SCOPE_INDEX_EXUP].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  343. //
  344. // Show each scope's information or not.
  345. //
  346. InitInfo.cDsScopeInfos = 0;
  347. //Root and Entire forest
  348. //These five memcpy() is a safe usage. aScopesUsed and aScopes are both defined locally.
  349. //Below 5 memcpy usages are safe usages.
  350. memcpy(&aScopesUsed[InitInfo.cDsScopeInfos],&aScopes[SCE_SCOPE_INDEX_ROOT],sizeof(DSOP_SCOPE_INIT_INFO));
  351. InitInfo.cDsScopeInfos++;
  352. memcpy(&aScopesUsed[InitInfo.cDsScopeInfos],&aScopes[SCE_SCOPE_INDEX_EXUP],sizeof(DSOP_SCOPE_INIT_INFO));
  353. InitInfo.cDsScopeInfos++;
  354. if (nShowFlag & SCE_SHOW_SCOPE_LOCAL) {
  355. memcpy(&aScopesUsed[InitInfo.cDsScopeInfos],&aScopes[SCE_SCOPE_INDEX_LOCAL],sizeof(DSOP_SCOPE_INIT_INFO));
  356. InitInfo.cDsScopeInfos++;
  357. }
  358. if (nShowFlag & SCE_SHOW_SCOPE_DOMAIN) {
  359. memcpy(&aScopesUsed[InitInfo.cDsScopeInfos],&aScopes[SCE_SCOPE_INDEX_DOMAIN],sizeof(DSOP_SCOPE_INIT_INFO));
  360. InitInfo.cDsScopeInfos++;
  361. }
  362. if (nShowFlag & SCE_SHOW_SCOPE_DIRECTORY) {
  363. memcpy(&aScopesUsed[InitInfo.cDsScopeInfos],&aScopes[SCE_SCOPE_INDEX_DIRECTORY],sizeof(DSOP_SCOPE_INIT_INFO));
  364. InitInfo.cDsScopeInfos++;
  365. }
  366. ASSERT(InitInfo.cDsScopeInfos > 0);
  367. //
  368. // Initialize and display the object picker.
  369. //
  370. InitInfo.cbSize = sizeof(InitInfo);
  371. InitInfo.aDsScopeInfos = aScopesUsed;
  372. InitInfo.flOptions = ((nShowFlag & SCE_SHOW_SINGLESEL) ? 0:DSOP_FLAG_MULTISELECT);
  373. if( (nShowFlag & SCE_SHOW_SCOPE_LOCAL) && bDC ) //Raid #462447, Yang Gao, 8/30/2001.
  374. {
  375. InitInfo.flOptions = InitInfo.flOptions | DSOP_FLAG_SKIP_TARGET_COMPUTER_DC_CHECK;
  376. }
  377. InitInfo.pwzTargetComputer = m_pszServerName;
  378. hr = pDsObjectPicker->Initialize(&InitInfo);
  379. if( FAILED(hr) ){
  380. CoUninitialize();
  381. return FALSE;
  382. }
  383. IDataObject *pdo = NULL;
  384. hr = pDsObjectPicker->InvokeDialog(hwnd, &pdo);
  385. while (SUCCEEDED(hr) && pdo) { // FALSE LOOP
  386. //
  387. // The user pressed OK. Prepare clipboard dataformat from the object picker.
  388. //
  389. STGMEDIUM stgmedium =
  390. {
  391. TYMED_HGLOBAL,
  392. NULL
  393. };
  394. CLIPFORMAT cf = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  395. FORMATETC formatetc =
  396. {
  397. cf,
  398. NULL,
  399. DVASPECT_CONTENT,
  400. -1,
  401. TYMED_HGLOBAL
  402. };
  403. hr = pdo->GetData(&formatetc, &stgmedium);
  404. if ( FAILED(hr) ) {
  405. bRet = FALSE;
  406. pdo->Release();
  407. pdo = NULL;
  408. break;
  409. }
  410. //
  411. // Lock the selection list.
  412. //
  413. PDS_SELECTION_LIST pDsSelList =
  414. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  415. ULONG i;
  416. ULONG iLen = 0;
  417. BOOL fFromSID = FALSE;
  418. PWSTR pSIDBuf = NULL;
  419. LSA_HANDLE hLsa = NULL;
  420. //
  421. // Enumerate through all selections.
  422. //
  423. PSID pSid = NULL;
  424. for (i = 0; i < pDsSelList->cItems && bRet; i++) {
  425. LPTSTR pszCur = pDsSelList->aDsSelection[i].pwzADsPath;
  426. fFromSID = FALSE;
  427. //make sure getting local wellknown account name.
  428. VARIANT* pSidArray = pDsSelList->aDsSelection[i].pvarFetchedAttributes + 1;
  429. pSid = NULL;
  430. if( NULL != pSidArray && (VT_ARRAY | VT_UI1) == V_VT(pSidArray)
  431. && SUCCEEDED(SafeArrayAccessData(V_ARRAY(pSidArray), &pSid)) )
  432. {
  433. if ( IsValidSid(pSid) )
  434. {
  435. if( !hLsa )
  436. {
  437. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  438. //LSA_HANDLE hLsa;
  439. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  440. if( SCESTATUS_SUCCESS != LsaOpenPolicy(
  441. NULL, &ObjectAttributes,
  442. MAXIMUM_ALLOWED,//POLICY_ALL_ACCESS,
  443. &hLsa
  444. ) )
  445. {
  446. SafeArrayUnaccessData(V_ARRAY(pSidArray));
  447. bRet = FALSE;
  448. break;
  449. }
  450. }
  451. PLSA_TRANSLATED_NAME pTranslatedName = NULL;
  452. PLSA_REFERENCED_DOMAIN_LIST pReferencedDomains = NULL;
  453. if( SCESTATUS_SUCCESS == LsaLookupSids(hLsa, 1, &pSid,
  454. &pReferencedDomains, &pTranslatedName) &&
  455. pTranslatedName->Use == SidTypeWellKnownGroup )
  456. {
  457. if( pSIDBuf )
  458. {
  459. long nsize = (wcslen(pSIDBuf)+1)*sizeof(WCHAR);
  460. if( nsize < (long)(pTranslatedName->Name.Length+sizeof(WCHAR)) )
  461. {
  462. pSIDBuf = (PWSTR)LocalReAlloc(pSIDBuf, pTranslatedName->Name.Length+sizeof(WCHAR), LMEM_MOVEABLE);
  463. nsize = pTranslatedName->Name.Length+sizeof(WCHAR);
  464. }
  465. ZeroMemory(pSIDBuf, nsize);
  466. }
  467. else
  468. {
  469. pSIDBuf = (PWSTR)LocalAlloc(LPTR, pTranslatedName->Name.Length+sizeof(WCHAR));
  470. }
  471. if( pSIDBuf )
  472. {
  473. wcsncpy(pSIDBuf, pTranslatedName->Name.Buffer, pTranslatedName->Name.Length/sizeof(WCHAR));
  474. fFromSID = TRUE;
  475. }
  476. else
  477. {
  478. if( pTranslatedName )
  479. {
  480. LsaFreeMemory(pTranslatedName);
  481. }
  482. if( pReferencedDomains )
  483. {
  484. LsaFreeMemory(pReferencedDomains);
  485. }
  486. SafeArrayUnaccessData(V_ARRAY(pSidArray));
  487. bRet = FALSE;
  488. break;
  489. }
  490. }
  491. if( pTranslatedName )
  492. {
  493. LsaFreeMemory(pTranslatedName);
  494. }
  495. if( pReferencedDomains )
  496. {
  497. LsaFreeMemory(pReferencedDomains);
  498. }
  499. }
  500. SafeArrayUnaccessData(V_ARRAY(pSidArray));
  501. }
  502. bHasADsPath = TRUE;
  503. int iPath = 0;
  504. //
  505. // Se if this is a valid string. If the string isn't empty or NULL then use it
  506. // with the full path, we will figure out later wiether we need to strip the prefix.
  507. //
  508. if (pszCur && *pszCur && !fFromSID )
  509. {
  510. //
  511. // Create name with one path.
  512. //
  513. iLen = lstrlen(pszCur);
  514. while (iLen) {
  515. if ( pszCur[iLen] == L'/' ) {
  516. if (iPath) {
  517. iLen++;
  518. iPath -= iLen;
  519. break;
  520. }
  521. iPath = iLen;
  522. }
  523. iLen--;
  524. }
  525. pszCur += iLen;
  526. }
  527. else
  528. {
  529. //
  530. // Use just the name then.
  531. //
  532. bHasADsPath = FALSE;
  533. if( fFromSID )
  534. {
  535. pszCur = pSIDBuf;
  536. }
  537. else
  538. {
  539. pszCur = pDsSelList->aDsSelection[i].pwzName;
  540. if (!pszCur || !(*pszCur)) {
  541. continue;
  542. }
  543. }
  544. }
  545. iLen = lstrlen(pszCur);
  546. if (iLen) {
  547. //
  548. // Allocate and copy the user name.
  549. //
  550. LPTSTR pszNew = (LPTSTR)LocalAlloc( LMEM_FIXED, (iLen + 1) * sizeof(TCHAR));
  551. if (!pszNew) {
  552. bRet = FALSE;
  553. break;
  554. }
  555. // This is an safe usage. pszCur is a trusted source string and is validated.
  556. lstrcpy(pszNew, pszCur);
  557. if (bHasADsPath)
  558. {
  559. if (iPath) {
  560. //
  561. // Set forward slash to back slash.
  562. //
  563. pszNew[iPath] = L'\\';
  564. }
  565. ULONG uAttributes;
  566. //
  567. // Bug 395424:
  568. //
  569. // Obsel passes attributes in VT_I4 on DCs and in VT_UI4 on other systems
  570. // Need to check both to properly detect built-ins, etc.
  571. //
  572. if (V_VT(pDsSelList->aDsSelection[i].pvarFetchedAttributes) == VT_UI4) {
  573. uAttributes = V_UI4(pDsSelList->aDsSelection[i].pvarFetchedAttributes);
  574. } else if (V_VT(pDsSelList->aDsSelection[i].pvarFetchedAttributes) == VT_I4) {
  575. uAttributes = static_cast<ULONG>(V_I4(pDsSelList->aDsSelection[i].pvarFetchedAttributes));
  576. }
  577. //
  578. // Determine if the name we recieved is group.
  579. // The type and value of pDsSelList->aDsSelection[i].pvarFetchedAttributes
  580. // may change in the future release by Object Picker. Therefore,
  581. // the following code should change accordingly.
  582. //
  583. if ( (V_VT(pDsSelList->aDsSelection[i].pvarFetchedAttributes) == VT_UI4) ||
  584. (V_VT(pDsSelList->aDsSelection[i].pvarFetchedAttributes) == VT_I4 ))
  585. {
  586. //
  587. // Determine if it is a built-in group. We don't want
  588. // built-in groups to have a prefix.
  589. //
  590. if ( uAttributes & 0x1 &&
  591. V_ISARRAY(pDsSelList->aDsSelection[i].pvarFetchedAttributes + 1) )
  592. {
  593. // This is an safe usage. pszCur is a trusted source string and is validated.
  594. // iPath is less than iLen.
  595. lstrcpy( pszNew, &(pszCur[iPath + 1]) );
  596. }
  597. else if ( uAttributes & 0x4 &&
  598. V_ISARRAY(pDsSelList->aDsSelection[i].pvarFetchedAttributes + 1) )
  599. {
  600. //
  601. // It's a group, but we have to check the sids account type. If it's
  602. // not in the domain accounts authority then we can assume it's a built-in sid
  603. //
  604. PVOID pvData = NULL;
  605. hr = SafeArrayAccessData( V_ARRAY(pDsSelList->aDsSelection[i].pvarFetchedAttributes + 1), &pvData); //Raid #prefast
  606. if (SUCCEEDED(hr) ) {
  607. if ( IsValidSid( (PSID)pvData ) && !IsDomainAccountSid( (PSID)pvData ) )
  608. {
  609. // This is an safe usage. pszCur is a trusted source string and is validated.
  610. // iPath is less than iLen.
  611. lstrcpy(pszNew, &(pszCur[iPath + 1]) );
  612. }
  613. hr = SafeArrayUnaccessData( V_ARRAY(pDsSelList->aDsSelection[i].pvarFetchedAttributes + 1) );
  614. }
  615. }
  616. }
  617. else if(V_VT(pDsSelList->aDsSelection[i].pvarFetchedAttributes) == VT_EMPTY)
  618. {
  619. LPTSTR pszTemp = pDsSelList->aDsSelection[i].pwzClass;
  620. //
  621. // Determine if it is a well-known account. We don't want
  622. // well-known account to have a prefix.
  623. // Prefast warning 400: Yields unexpected results in non-English locales. Comments: They are not localizable.
  624. if (_wcsicmp(pszTemp, _T("user")) && _wcsicmp(pszTemp, _T("computer"))) //Raid #477428, Yanggao
  625. {
  626. // This is an safe usage. pszCur is a trusted source string and is validated.
  627. // iPath is less than iLen.
  628. lstrcpy( pszNew, &(pszCur[iPath + 1]) );
  629. }
  630. }
  631. }
  632. //
  633. // Make sure we don't already have this name in the list.
  634. //
  635. pName = m_pNameList;
  636. while (pName) {
  637. if (!lstrcmpi(pName->Name, pszNew)) {
  638. LocalFree(pszNew);
  639. pszNew = NULL;
  640. break;
  641. }
  642. pName = pName->Next;
  643. }
  644. if ( !pszNew ) {
  645. //
  646. // Don;t do anything because this name already exists.
  647. //
  648. continue;
  649. }
  650. //
  651. // New entry in list.
  652. //
  653. pName = (PSCE_NAME_LIST) LocalAlloc(LPTR,sizeof(SCE_NAME_LIST));
  654. if ( !pName ) {
  655. LocalFree(pszNew);
  656. bRet = FALSE;
  657. break;
  658. }
  659. ZeroMemory(pName, sizeof(SCE_NAME_LIST));
  660. //GetAccountType(pszNew);
  661. pName->Name = pszNew;
  662. pName->Next = m_pNameList;
  663. m_pNameList = pName;
  664. }
  665. }
  666. GlobalUnlock(stgmedium.hGlobal);
  667. ReleaseStgMedium(&stgmedium);
  668. pdo->Release();
  669. if(hLsa)
  670. {
  671. LsaClose(hLsa);
  672. }
  673. if(pSIDBuf)
  674. {
  675. LocalFree(pSIDBuf);
  676. }
  677. break;
  678. }
  679. pDsObjectPicker->Release();
  680. CoUninitialize();
  681. if (!bRet) {
  682. //
  683. // If we had an error somewhere clean up.
  684. //
  685. pName = m_pNameList;
  686. while (pName) {
  687. if (pName->Name) {
  688. LocalFree(pName->Name);
  689. }
  690. m_pNameList = pName->Next;
  691. LocalFree(pName);
  692. pName = m_pNameList;
  693. }
  694. m_pNameList = NULL;
  695. }
  696. return bRet;
  697. }
  698. PSCE_NAME_LIST CGetUser::GetUsers()
  699. {
  700. return m_pNameList;
  701. }