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.

665 lines
19 KiB

  1. #include "schema.h"
  2. #pragma hdrstop
  3. #include "initguid.h"
  4. #include "iadmw.h"
  5. #include "schemini.hxx"
  6. #if _IIS_6_0
  7. #include "..\adsiis\globdata.cxx"
  8. #elif _IIS_5_1
  9. #include "..\adsiis\iis51\globdata.cxx"
  10. #else
  11. #error "Neither _IIS_6_0 nor _IIS_5_1 is defined"
  12. #endif
  13. #define DEFAULT_TIMEOUT_VALUE 30000
  14. HRESULT SetAdminACL(IMSAdminBase * pAdminBase);
  15. DWORD
  16. GetPrincipalSID (
  17. LPTSTR Principal,
  18. PSID *Sid,
  19. BOOL *pbWellKnownSID
  20. );
  21. MetaHandle::MetaHandle(IMSAdminBasePtr _pmb) : pmb(_pmb) {
  22. if (pmb)
  23. pmb->AddRef();
  24. h = 0;
  25. }
  26. MetaHandle::~MetaHandle() {
  27. if (pmb) {
  28. if (h)
  29. pmb->CloseKey(h);
  30. pmb->Release();
  31. }
  32. }
  33. struct WideStrMapEntry {
  34. LPWSTR m_str;
  35. void *m_data;
  36. };
  37. class WideStrMap {
  38. WideStrMapEntry *map;
  39. int count;
  40. int mapSize;
  41. public:
  42. WideStrMap();
  43. ~WideStrMap();
  44. BOOL CheckSpace();
  45. BOOL Add(LPWSTR str, void *data);
  46. void *Find(LPWSTR str);
  47. void *operator[] (LPWSTR str);
  48. };
  49. WideStrMap::WideStrMap() {
  50. count = 0;
  51. mapSize = 64;
  52. map = (WideStrMapEntry *)malloc(sizeof(WideStrMapEntry) * mapSize);
  53. }
  54. WideStrMap::~WideStrMap() {
  55. free(map);
  56. }
  57. BOOL WideStrMap::CheckSpace() {
  58. if (count < mapSize)
  59. return TRUE;
  60. mapSize += 32;
  61. if ((map = (WideStrMapEntry *)realloc(map, sizeof(WideStrMapEntry)*mapSize)) == NULL)
  62. return FALSE;
  63. return TRUE;
  64. }
  65. BOOL WideStrMap::Add(LPWSTR str, void *data) {
  66. if (!CheckSpace())
  67. return FALSE;
  68. map[count].m_str = str;
  69. map[count].m_data = data;
  70. count++;
  71. return TRUE;
  72. }
  73. void *WideStrMap::Find(LPWSTR str) {
  74. for (int i=0; i < count; i++) {
  75. if (!_wcsicmp(str, map[i].m_str))
  76. return map[i].m_data;
  77. }
  78. return NULL;
  79. }
  80. void *WideStrMap::operator[] (LPWSTR str) {
  81. return Find(str);
  82. }
  83. #if 0
  84. struct PropValue {
  85. DWORD dwMetaID;
  86. DWORD dwSynID;
  87. DWORD dwMetaType;
  88. DWORD dwFlags;
  89. BOOL fMultiValued;
  90. DWORD dwMask;
  91. DWORD dwMetaFlags;
  92. DWORD dwUserGroup;
  93. };
  94. #endif
  95. void InitPropValue(PropValue *pv, PROPERTYINFO *pi) {
  96. pv->dwSynID = pi->dwSyntaxId;
  97. pv->dwMetaID = pi->dwMetaID;
  98. pv->dwPropID = pi->dwPropID;
  99. pv->dwMaxRange = (DWORD)pi->lMaxRange;
  100. pv->dwMinRange = (DWORD)pi->lMinRange;
  101. switch(pi->dwSyntaxId) {
  102. case IIS_SYNTAX_ID_DWORD:
  103. case IIS_SYNTAX_ID_BOOL:
  104. case IIS_SYNTAX_ID_BOOL_BITMASK:
  105. pv->dwMetaType = DWORD_METADATA;
  106. break;
  107. case IIS_SYNTAX_ID_STRING:
  108. pv->dwMetaType = STRING_METADATA;
  109. break;
  110. case IIS_SYNTAX_ID_EXPANDSZ:
  111. pv->dwMetaType = EXPANDSZ_METADATA;
  112. break;
  113. case IIS_SYNTAX_ID_MIMEMAP:
  114. case IIS_SYNTAX_ID_MULTISZ:
  115. pv->dwMetaType = MULTISZ_METADATA;
  116. break;
  117. case IIS_SYNTAX_ID_NTACL:
  118. case IIS_SYNTAX_ID_IPSECLIST:
  119. pv->dwMetaType = BINARY_METADATA;
  120. break;
  121. }
  122. pv->dwFlags = pi->dwFlags;
  123. pv->fMultiValued = pi->fMultiValued;
  124. pv->dwMask = pi->dwMask;
  125. pv->dwMetaFlags = pi->dwMetaFlags;
  126. pv->dwUserGroup = pi->dwUserGroup;
  127. }
  128. // struct __declspec(__uuid()
  129. static char asciiBuf[2048];
  130. BOOL DataForSyntaxID(PROPERTYINFO *pp, METADATA_RECORD *mdr) {
  131. static DWORD value=0;
  132. WCHAR *ptr;
  133. int i;
  134. switch(pp->dwSyntaxId) {
  135. case IIS_SYNTAX_ID_BOOL:
  136. case IIS_SYNTAX_ID_BOOL_BITMASK:
  137. case IIS_SYNTAX_ID_DWORD:
  138. mdr->dwMDDataType = DWORD_METADATA;
  139. mdr->dwMDDataLen = sizeof(DWORD);
  140. mdr->pbMDData = (unsigned char *)&(pp->dwDefault);
  141. break;
  142. case IIS_SYNTAX_ID_STRING:
  143. mdr->dwMDDataType = STRING_METADATA;
  144. mdr->dwMDDataLen = (wcslen(pp->szDefault)+1)*2;
  145. mdr->pbMDData = (unsigned char *)pp->szDefault;
  146. break;
  147. case IIS_SYNTAX_ID_EXPANDSZ:
  148. mdr->dwMDDataType = EXPANDSZ_METADATA;
  149. mdr->dwMDDataLen = (wcslen(pp->szDefault)+1)*2;
  150. mdr->pbMDData = (unsigned char *)pp->szDefault;
  151. break;
  152. case IIS_SYNTAX_ID_MIMEMAP:
  153. case IIS_SYNTAX_ID_MULTISZ:
  154. //
  155. // Note, ALL multisz types must have an extra \0 in the table.
  156. //
  157. mdr->dwMDDataType = MULTISZ_METADATA;
  158. ptr = pp->szDefault;
  159. do {
  160. ptr += wcslen(ptr)+1;
  161. } while (*ptr != 0);
  162. mdr->dwMDDataLen = DIFF((char *)ptr - (char *)pp->szDefault)+2;
  163. mdr->pbMDData = (unsigned char *)pp->szDefault;
  164. break;
  165. case IIS_SYNTAX_ID_IPSECLIST:
  166. case IIS_SYNTAX_ID_NTACL:
  167. case IIS_SYNTAX_ID_BINARY:
  168. mdr->dwMDDataType = BINARY_METADATA;
  169. mdr->dwMDDataLen = 0;
  170. mdr->pbMDData = NULL;
  171. break;
  172. default:
  173. mdr->dwMDDataType = DWORD_METADATA;
  174. mdr->dwMDDataLen = sizeof(DWORD);
  175. mdr->pbMDData = (unsigned char *)&value;
  176. return FALSE;
  177. }
  178. return TRUE;
  179. }
  180. const DWORD getAllBufSize = 4096;
  181. wchar_t *grabProp(wchar_t *out, wchar_t *in) {
  182. if (!in || *in == L'\0') {
  183. *out = L'\0';
  184. return NULL;
  185. }
  186. while (*in != L',' && *in != L'\0') {
  187. *out++ = *in++;
  188. }
  189. *out = L'\0';
  190. if (*in == L',')
  191. return ++in;
  192. return in;
  193. }
  194. HRESULT StoreSchema() {
  195. DWORD bufSize = getAllBufSize;
  196. BYTE *buf = new BYTE[bufSize];
  197. HRESULT hr;
  198. COSERVERINFO csiName;
  199. COSERVERINFO *pcsiParam = &csiName;
  200. IClassFactory * pcsfFactory = NULL;
  201. IMSAdminBase * pAdminBase = NULL;
  202. METADATA_RECORD mdr;
  203. wchar_t mandProps[MAX_PATH];
  204. wchar_t optProps[MAX_PATH];
  205. wchar_t prop[MAX_PATH], *propList;
  206. MetaHandle root(NULL);
  207. DWORD value = 0;
  208. DWORD i;
  209. //
  210. // nameToProp is used for mapping properties by name to the property structures
  211. // that define the properties. Since we first run through the list of props,
  212. // and write out the names, we add the prop to the map. Then, when we encounter
  213. // the properties by name, which is how the classes maintain them, we can access
  214. // the corresponding property structure.
  215. //
  216. WideStrMap nameToProp;
  217. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  218. pcsiParam->pwszName = NULL;
  219. csiName.pAuthInfo = NULL;
  220. pcsiParam = &csiName;
  221. hr = CoGetClassObject(
  222. CLSID_MSAdminBase,
  223. CLSCTX_SERVER,
  224. pcsiParam,
  225. IID_IClassFactory,
  226. (void**) &pcsfFactory
  227. );
  228. BAIL_ON_FAILURE(hr);
  229. hr = pcsfFactory->CreateInstance(
  230. NULL,
  231. IID_IMSAdminBase,
  232. (void **) &pAdminBase
  233. );
  234. pcsfFactory->Release();
  235. BAIL_ON_FAILURE(hr);
  236. root.setpointer(pAdminBase);
  237. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  238. L"",
  239. METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
  240. DEFAULT_TIMEOUT_VALUE,
  241. root);
  242. BAIL_ON_FAILURE(hr);
  243. hr = pAdminBase->AddKey(root, L"Schema");
  244. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  245. BAIL_ON_FAILURE(hr);
  246. }
  247. hr = pAdminBase->AddKey(root, L"Schema/Properties");
  248. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  249. BAIL_ON_FAILURE(hr);
  250. }
  251. hr = pAdminBase->AddKey(root, L"Schema/Classes");
  252. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  253. BAIL_ON_FAILURE(hr);
  254. }
  255. hr = pAdminBase->AddKey(root, L"Schema/Properties/Names");
  256. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  257. BAIL_ON_FAILURE(hr);
  258. }
  259. hr = pAdminBase->AddKey(root, L"Schema/Properties/Types");
  260. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  261. BAIL_ON_FAILURE(hr);
  262. }
  263. hr = pAdminBase->AddKey(root, L"Schema/Properties/Defaults");
  264. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  265. BAIL_ON_FAILURE(hr);
  266. }
  267. root.close();
  268. //
  269. // Now, let's initialize the property dictionary.
  270. //
  271. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  272. L"/Schema/Properties",
  273. METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
  274. DEFAULT_TIMEOUT_VALUE,
  275. root);
  276. BAIL_ON_FAILURE(hr);
  277. mdr.dwMDDataTag = 0;
  278. DWORD propData[2];
  279. PropValue pv;
  280. for (i=0; i < g_cIISProperties; i++) {
  281. //
  282. // First, we set the name prop to the string value of the properties name.
  283. //
  284. mdr.dwMDIdentifier = g_aIISProperties[i].dwPropID;
  285. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  286. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  287. mdr.dwMDDataType = STRING_METADATA;
  288. mdr.dwMDDataLen = (wcslen(g_aIISProperties[i].szPropertyName)+1)*2;
  289. mdr.pbMDData = (unsigned char *)g_aIISProperties[i].szPropertyName;
  290. hr = pAdminBase->SetData(root, L"Names", &mdr);
  291. BAIL_ON_FAILURE(hr);
  292. //
  293. // Next, we need to update the type field.
  294. //
  295. InitPropValue(&pv, &g_aIISProperties[i]);
  296. mdr.dwMDDataType = BINARY_METADATA;
  297. mdr.dwMDDataLen = sizeof(PropValue);
  298. mdr.pbMDData = (unsigned char *)&pv;
  299. hr = pAdminBase->SetData(root, L"Types", &mdr);
  300. BAIL_ON_FAILURE(hr);
  301. //
  302. // update default values
  303. //
  304. mdr.dwMDIdentifier = g_aIISProperties[i].dwPropID;
  305. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  306. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  307. DataForSyntaxID(&(g_aIISProperties[i]), &mdr);
  308. hr = pAdminBase->SetData(root, L"Defaults", &mdr);
  309. BAIL_ON_FAILURE(hr);
  310. }
  311. root.close();
  312. hr = pAdminBase->SaveData();
  313. BAIL_ON_FAILURE(hr);
  314. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  315. L"/Schema/Classes",
  316. METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
  317. DEFAULT_TIMEOUT_VALUE,
  318. root);
  319. BAIL_ON_FAILURE(hr);
  320. for (i=0; i < g_cIISClasses; i++) {
  321. hr = pAdminBase->AddKey(root, g_aIISClasses[i].bstrName);
  322. if (FAILED(hr) && HRESULT_CODE(hr) != ERROR_ALREADY_EXISTS) {
  323. BAIL_ON_FAILURE(hr);
  324. }
  325. //
  326. // setting Containment and Container property for classes
  327. //
  328. mdr.dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINMENT;
  329. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  330. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  331. mdr.dwMDDataType = STRING_METADATA;
  332. if (g_aIISClasses[i].bstrContainment) {
  333. mdr.dwMDDataLen = (wcslen((LPWSTR)g_aIISClasses[i].bstrContainment)+1)*2;
  334. }
  335. else {
  336. mdr.dwMDDataLen = 0;
  337. }
  338. mdr.pbMDData = (unsigned char *)g_aIISClasses[i].bstrContainment;
  339. hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
  340. BAIL_ON_FAILURE(hr);
  341. mdr.dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINER;
  342. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  343. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  344. mdr.dwMDDataType = DWORD_METADATA;
  345. mdr.dwMDDataLen = sizeof(DWORD);
  346. mdr.pbMDData = (unsigned char *)&(g_aIISClasses[i].fContainer);
  347. hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
  348. BAIL_ON_FAILURE(hr);
  349. //
  350. // setting Optional and Mandatory Properties
  351. //
  352. mdr.dwMDIdentifier = MD_SCHEMA_CLASS_MAND_PROPERTIES;
  353. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  354. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  355. mdr.dwMDDataType = STRING_METADATA;
  356. if (g_aIISClasses[i].bstrMandatoryProperties) {
  357. mdr.dwMDDataLen = (wcslen((LPWSTR)g_aIISClasses[i].bstrMandatoryProperties)+1)*2;
  358. }
  359. else {
  360. mdr.dwMDDataLen = 0;
  361. }
  362. mdr.pbMDData = (unsigned char *)g_aIISClasses[i].bstrMandatoryProperties;
  363. hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
  364. BAIL_ON_FAILURE(hr);
  365. mdr.dwMDIdentifier = MD_SCHEMA_CLASS_OPT_PROPERTIES;
  366. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  367. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  368. mdr.dwMDDataType = STRING_METADATA;
  369. if (g_aIISClasses[i].bstrOptionalProperties) {
  370. mdr.dwMDDataLen = (wcslen((LPWSTR)g_aIISClasses[i].bstrOptionalProperties)+1)*2;
  371. }
  372. else {
  373. mdr.dwMDDataLen = 0;
  374. }
  375. mdr.pbMDData = (unsigned char *)g_aIISClasses[i].bstrOptionalProperties;
  376. hr = pAdminBase->SetData(root, g_aIISClasses[i].bstrName, &mdr);
  377. BAIL_ON_FAILURE(hr);
  378. }
  379. root.close();
  380. hr = pAdminBase->SaveData();
  381. BAIL_ON_FAILURE(hr);
  382. hr = SetAdminACL(pAdminBase);
  383. error:
  384. root.close();
  385. if (pAdminBase)
  386. pAdminBase->Release();
  387. return hr;
  388. }
  389. HRESULT SetAdminACL(
  390. IMSAdminBase * pAdminBase
  391. )
  392. {
  393. BOOL b = FALSE;
  394. DWORD dwLength = 0;
  395. PSECURITY_DESCRIPTOR pSD = NULL;
  396. PSECURITY_DESCRIPTOR outpSD = NULL;
  397. DWORD cboutpSD = 0;
  398. PACL pACLNew = NULL;
  399. DWORD cbACL = 0;
  400. PSID pAdminsSID = NULL, pEveryoneSID = NULL;
  401. BOOL bWellKnownSID = FALSE;
  402. MetaHandle root(NULL);
  403. METADATA_RECORD mdr;
  404. HRESULT hr = NO_ERROR;
  405. DWORD dwStartMetaId = IIS_MD_ADSI_METAID_BEGIN;
  406. // Initialize a new security descriptor
  407. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  408. if (!pSD) {hr = E_OUTOFMEMORY;}
  409. BAIL_ON_FAILURE(hr);
  410. InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
  411. // Get Local Admins Sid
  412. GetPrincipalSID (_T("Administrators"), &pAdminsSID, &bWellKnownSID);
  413. // Get everyone Sid
  414. GetPrincipalSID (_T("Everyone"), &pEveryoneSID, &bWellKnownSID);
  415. // Initialize a new ACL, which only contains 2 aaace
  416. cbACL = sizeof(ACL) +
  417. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pAdminsSID) - sizeof(DWORD)) +
  418. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pEveryoneSID) - sizeof(DWORD)) ;
  419. pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
  420. if (!pACLNew) {hr = E_OUTOFMEMORY;}
  421. BAIL_ON_FAILURE(hr);
  422. InitializeAcl(pACLNew, cbACL, ACL_REVISION);
  423. AddAccessAllowedAce(
  424. pACLNew,
  425. ACL_REVISION,
  426. FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE,
  427. pAdminsSID);
  428. AddAccessAllowedAce(
  429. pACLNew,
  430. ACL_REVISION,
  431. FILE_GENERIC_READ,
  432. pEveryoneSID);
  433. // Add the ACL to the security descriptor
  434. b = SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE);
  435. b = SetSecurityDescriptorOwner(pSD, pAdminsSID, TRUE);
  436. b = SetSecurityDescriptorGroup(pSD, pAdminsSID, TRUE);
  437. // Security descriptor blob must be self relative
  438. b = MakeSelfRelativeSD(pSD, outpSD, &cboutpSD);
  439. outpSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GPTR, cboutpSD);
  440. if (!outpSD) {hr = E_OUTOFMEMORY;}
  441. BAIL_ON_FAILURE(hr);
  442. b = MakeSelfRelativeSD( pSD, outpSD, &cboutpSD );
  443. // below this modify pSD to outpSD
  444. // Apply the new security descriptor to the file
  445. dwLength = GetSecurityDescriptorLength(outpSD);
  446. // Apply the new security descriptor to the file
  447. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  448. L"/Schema",
  449. METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE,
  450. DEFAULT_TIMEOUT_VALUE,
  451. root);
  452. BAIL_ON_FAILURE(hr);
  453. mdr.dwMDIdentifier = MD_ADMIN_ACL;
  454. mdr.dwMDAttributes = METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE;
  455. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  456. mdr.dwMDDataType = BINARY_METADATA;
  457. mdr.dwMDDataLen = dwLength;
  458. mdr.pbMDData = (LPBYTE)outpSD;
  459. hr = pAdminBase->SetData(root, L"", &mdr);
  460. BAIL_ON_FAILURE(hr);
  461. //
  462. // set the start count for meta id
  463. //
  464. mdr.dwMDIdentifier = MD_SCHEMA_METAID;
  465. mdr.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  466. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  467. mdr.dwMDDataType = DWORD_METADATA;
  468. mdr.dwMDDataLen = sizeof(DWORD);
  469. mdr.pbMDData = (LPBYTE)&dwStartMetaId;
  470. hr = pAdminBase->SetData(root, L"", &mdr);
  471. BAIL_ON_FAILURE(hr);
  472. root.close();
  473. error :
  474. //Cleanup:
  475. // both of Administrators and Everyone are well-known SIDs, use FreeSid() to free them.
  476. if (outpSD)
  477. GlobalFree(outpSD);
  478. if (pAdminsSID)
  479. FreeSid(pAdminsSID);
  480. if (pEveryoneSID)
  481. FreeSid(pEveryoneSID);
  482. if (pSD)
  483. LocalFree((HLOCAL) pSD);
  484. if (pACLNew)
  485. LocalFree((HLOCAL) pACLNew);
  486. return (hr);
  487. }
  488. DWORD
  489. GetPrincipalSID (
  490. LPTSTR Principal,
  491. PSID *Sid,
  492. BOOL *pbWellKnownSID
  493. )
  494. {
  495. SID_IDENTIFIER_AUTHORITY SidIdentifierNTAuthority = SECURITY_NT_AUTHORITY;
  496. SID_IDENTIFIER_AUTHORITY SidIdentifierWORLDAuthority = SECURITY_WORLD_SID_AUTHORITY;
  497. PSID_IDENTIFIER_AUTHORITY pSidIdentifierAuthority;
  498. BYTE Count;
  499. DWORD dwRID[8];
  500. *pbWellKnownSID = TRUE;
  501. memset(&(dwRID[0]), 0, 8 * sizeof(DWORD));
  502. if ( wcscmp(Principal,_T("Administrators")) == 0 ) {
  503. // Administrators group
  504. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  505. Count = 2;
  506. dwRID[0] = SECURITY_BUILTIN_DOMAIN_RID;
  507. dwRID[1] = DOMAIN_ALIAS_RID_ADMINS;
  508. } else if ( wcscmp(Principal,_T("System")) == 0) {
  509. // SYSTEM
  510. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  511. Count = 1;
  512. dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
  513. } else if ( wcscmp(Principal,_T("Interactive")) == 0) {
  514. // INTERACTIVE
  515. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  516. Count = 1;
  517. dwRID[0] = SECURITY_INTERACTIVE_RID;
  518. } else if ( wcscmp(Principal,_T("Everyone")) == 0) {
  519. // Everyone
  520. pSidIdentifierAuthority = &SidIdentifierWORLDAuthority;
  521. Count = 1;
  522. dwRID[0] = SECURITY_WORLD_RID;
  523. } else {
  524. *pbWellKnownSID = FALSE;
  525. }
  526. if (*pbWellKnownSID) {
  527. if ( !AllocateAndInitializeSid(pSidIdentifierAuthority,
  528. (BYTE)Count,
  529. dwRID[0],
  530. dwRID[1],
  531. dwRID[2],
  532. dwRID[3],
  533. dwRID[4],
  534. dwRID[5],
  535. dwRID[6],
  536. dwRID[7],
  537. Sid) )
  538. return GetLastError();
  539. } else {
  540. // get regular account sid
  541. DWORD sidSize;
  542. TCHAR refDomain [256];
  543. DWORD refDomainSize;
  544. DWORD returnValue;
  545. SID_NAME_USE snu;
  546. sidSize = 0;
  547. refDomainSize = 255;
  548. LookupAccountName (NULL,
  549. Principal,
  550. *Sid,
  551. &sidSize,
  552. refDomain,
  553. &refDomainSize,
  554. &snu);
  555. returnValue = GetLastError();
  556. if (returnValue != ERROR_INSUFFICIENT_BUFFER)
  557. return returnValue;
  558. *Sid = (PSID) malloc (sidSize);
  559. refDomainSize = 255;
  560. if (!LookupAccountName (NULL,
  561. Principal,
  562. *Sid,
  563. &sidSize,
  564. refDomain,
  565. &refDomainSize,
  566. &snu))
  567. {
  568. return GetLastError();
  569. }
  570. }
  571. return ERROR_SUCCESS;
  572. }