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.

1035 lines
30 KiB

  1. #include "stdafx.h"
  2. #include <loadperf.h>
  3. #include <aclapi.h>
  4. #include "setupapi.h"
  5. #include "log.h"
  6. #include "iiscnfg.h"
  7. #include "iadmw.h"
  8. #include "mdkey.h"
  9. #define DBL_UNDEFINED ((DWORD)-1)
  10. DWORD gDebugLevel = DBL_UNDEFINED;
  11. extern MyLogFile g_MyLogFile;
  12. // Forward references
  13. DWORD SetAdminACL_wrap(LPCTSTR szKeyPath, DWORD dwAccessForEveryoneAccount, BOOL bDisplayMsgOnErrFlag);
  14. DWORD WriteSDtoMetaBase(PSECURITY_DESCRIPTOR outpSD, LPCTSTR szKeyPath);
  15. DWORD GetPrincipalSID (LPTSTR Principal, PSID *Sid, BOOL *pbWellKnownSID);
  16. DWORD SetAdminACL(LPCTSTR szKeyPath, DWORD dwAccessForEveryoneAccount);
  17. void DebugOutputFile(TCHAR* pszTemp)
  18. {
  19. //
  20. // NT5 doesn't want us to put all the debug string
  21. // in debugger. So we skip them based on a regkey.
  22. // See GetDebugLevel().
  23. // Todo: Log strings to a logfile!!!
  24. // See IIS log.h, log.cpp for examples!
  25. //
  26. g_MyLogFile.LogFileWrite(pszTemp);
  27. if (gDebugLevel == DBL_UNDEFINED) {gDebugLevel = GetDebugLevel();}
  28. if (gDebugLevel)
  29. {
  30. OutputDebugString(pszTemp);
  31. }
  32. }
  33. void DebugOutput(LPCTSTR szFormat, ...)
  34. {
  35. va_list marker;
  36. const int chTemp = 1024;
  37. TCHAR szTemp[chTemp];
  38. // Make sure the last two bytes are null in case the printf doesn't null terminate
  39. szTemp[chTemp-2] = szTemp[chTemp-1] = '\0';
  40. // Encompass this whole iisdebugout deal in a try-catch.
  41. // not too good to have this one access violating.
  42. // when trying to produce a debugoutput!
  43. __try
  44. {
  45. va_start( marker, szFormat );
  46. _vsnwprintf(szTemp, chTemp-2, szFormat, marker );
  47. lstrcat(szTemp, _T("\n"));
  48. va_end( marker );
  49. }
  50. __except(EXCEPTION_EXECUTE_HANDLER)
  51. {
  52. TCHAR szErrorString[100];
  53. _stprintf(szErrorString, _T("\r\n\r\nException Caught in DebugOutput(). GetExceptionCode()=0x%x.\r\n\r\n"), GetExceptionCode());
  54. OutputDebugString(szErrorString);
  55. g_MyLogFile.LogFileWrite(szErrorString);
  56. }
  57. // output to log file and the screen.
  58. DebugOutputFile(szTemp);
  59. return;
  60. }
  61. // This function requires inputs like this:
  62. // iisDebugOutSafeParams2("this %1!s! is %2!s! and has %3!d! args", "function", "kool", 3);
  63. // you must specify the %1 deals. this is so that
  64. // if something like this is passed in "this %SYSTEMROOT% %1!s!", it will put the string into %1 not %s!
  65. void DebugOutputSafe(TCHAR *pszfmt, ...)
  66. {
  67. // The count of parameters do not match
  68. va_list va;
  69. TCHAR *pszFullErrMsg = NULL;
  70. va_start(va, pszfmt);
  71. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
  72. (LPCVOID) pszfmt,
  73. 0,
  74. 0,
  75. (LPTSTR) &pszFullErrMsg,
  76. 0,
  77. &va);
  78. if (pszFullErrMsg)
  79. {
  80. // output to log file and the screen.
  81. DebugOutputFile(pszFullErrMsg);
  82. }
  83. va_end(va);
  84. if (pszFullErrMsg) {LocalFree(pszFullErrMsg);pszFullErrMsg=NULL;}
  85. return;
  86. }
  87. BOOL IsFileExist(LPCTSTR szFile)
  88. {
  89. return (GetFileAttributes(szFile) != 0xFFFFFFFF);
  90. }
  91. INT InstallPerformance(
  92. CString nlsRegPerf,
  93. CString nlsDll,
  94. CString nlsOpen,
  95. CString nlsClose,
  96. CString nlsCollect )
  97. {
  98. INT err = NERR_Success;
  99. if (theApp.m_eOS != OS_W95) {
  100. CRegKey regPerf( nlsRegPerf, HKEY_LOCAL_MACHINE );
  101. if (regPerf)
  102. {
  103. regPerf.SetValue(_T("Library"), nlsDll );
  104. regPerf.SetValue(_T("Open"), nlsOpen );
  105. regPerf.SetValue(_T("Close"), nlsClose );
  106. regPerf.SetValue(_T("Collect"), nlsCollect );
  107. }
  108. }
  109. return(err);
  110. }
  111. //
  112. // Add eventlog to the registry
  113. //
  114. INT AddEventLog(CString nlsService, CString nlsMsgFile, DWORD dwType)
  115. {
  116. INT err = NERR_Success;
  117. CString nlsLog = REG_EVENTLOG;
  118. nlsLog += _T("\\");
  119. nlsLog += nlsService;
  120. CRegKey regService( nlsLog, HKEY_LOCAL_MACHINE );
  121. if ( regService ) {
  122. regService.SetValue( _T("EventMessageFile"), nlsMsgFile, TRUE );
  123. regService.SetValue( _T("TypesSupported"), dwType );
  124. }
  125. return(err);
  126. }
  127. //
  128. // Remove eventlog from the registry
  129. //
  130. INT RemoveEventLog( CString nlsService )
  131. {
  132. INT err = NERR_Success;
  133. CString nlsLog = REG_EVENTLOG;
  134. CRegKey regService( HKEY_LOCAL_MACHINE, nlsLog );
  135. if ( regService )
  136. regService.DeleteTree( nlsService );
  137. return(err);
  138. }
  139. //
  140. // Remove an SNMP agent from the registry
  141. //
  142. INT RemoveAgent( CString nlsServiceName )
  143. {
  144. INT err = NERR_Success;
  145. do
  146. {
  147. CString nlsSoftwareAgent = REG_SOFTWAREMSFT;
  148. CRegKey regSoftwareAgent( HKEY_LOCAL_MACHINE, nlsSoftwareAgent );
  149. if ((HKEY)NULL == regSoftwareAgent )
  150. break;
  151. regSoftwareAgent.DeleteTree( nlsServiceName );
  152. CString nlsSnmpParam = REG_SNMPPARAMETERS;
  153. CRegKey regSnmpParam( HKEY_LOCAL_MACHINE, nlsSnmpParam );
  154. if ((HKEY) NULL == regSnmpParam )
  155. break;
  156. regSnmpParam.DeleteTree( nlsServiceName );
  157. CString nlsSnmpExt = REG_SNMPEXTAGENT;
  158. CRegKey regSnmpExt( HKEY_LOCAL_MACHINE, nlsSnmpExt );
  159. if ((HKEY) NULL == regSnmpExt )
  160. break;
  161. CRegValueIter enumSnmpExt( regSnmpExt );
  162. CString strName;
  163. DWORD dwType;
  164. CString csServiceName;
  165. csServiceName = _T("\\") + nlsServiceName;
  166. csServiceName += _T("\\");
  167. while ( enumSnmpExt.Next( &strName, &dwType ) == NERR_Success )
  168. {
  169. CString nlsValue;
  170. regSnmpExt.QueryValue( strName, nlsValue );
  171. if ( nlsValue.Find( csServiceName ) != (-1))
  172. {
  173. // found it
  174. regSnmpExt.DeleteValue( (LPCTSTR)strName );
  175. break;
  176. }
  177. }
  178. } while (FALSE);
  179. return(err);
  180. }
  181. LONG lodctr(LPCTSTR lpszIniFile)
  182. {
  183. CString csCmdLine = _T("lodctr ");
  184. csCmdLine += theApp.m_csSysDir;
  185. csCmdLine += _T("\\");
  186. csCmdLine += lpszIniFile;
  187. return (LONG)(LoadPerfCounterTextStrings((LPTSTR)(LPCTSTR)csCmdLine, TRUE));
  188. }
  189. LONG unlodctr(LPCTSTR lpszDriver)
  190. {
  191. CString csCmdLine = _T("unlodctr ");
  192. csCmdLine += lpszDriver;
  193. return (LONG)(UnloadPerfCounterTextStrings((LPTSTR)(LPCTSTR)csCmdLine, TRUE));
  194. }
  195. //
  196. // Given a directory path, set everyone full control security
  197. //
  198. BOOL SetNntpACL (CString &str, BOOL fAddAnonymousLogon, BOOL fAdminOnly)
  199. {
  200. DWORD dwRes, dwDisposition;
  201. PSID pEveryoneSID = NULL;
  202. PSID pAnonymousLogonSID = NULL;
  203. PSID pLocalSystemSID = NULL;
  204. PSID pAdminSID = NULL;
  205. PACL pACL = NULL;
  206. PSECURITY_DESCRIPTOR pSD = NULL;
  207. const int cMaxExplicitAccess = 4;
  208. EXPLICIT_ACCESS ea[cMaxExplicitAccess];
  209. int cExplicitAccess = 0;
  210. SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
  211. SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  212. LONG lRes;
  213. BOOL fRet = FALSE;
  214. // Create a security descriptor for the files
  215. ZeroMemory(ea, sizeof(ea));
  216. // Create a well-known SID for the Everyone group.
  217. if (fAdminOnly)
  218. {
  219. if(! AllocateAndInitializeSid( &SIDAuthNT, 1,
  220. SECURITY_LOCAL_SYSTEM_RID,
  221. 0, 0, 0, 0, 0, 0, 0,
  222. &pLocalSystemSID) )
  223. {
  224. goto Exit;
  225. }
  226. if(! AllocateAndInitializeSid( &SIDAuthNT, 2,
  227. SECURITY_BUILTIN_DOMAIN_RID,
  228. DOMAIN_ALIAS_RID_ADMINS,
  229. 0, 0, 0, 0, 0, 0,
  230. &pAdminSID) )
  231. {
  232. goto Exit;
  233. }
  234. ea[0].grfAccessPermissions = GENERIC_ALL;
  235. ea[0].grfAccessMode = SET_ACCESS;
  236. ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  237. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  238. ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
  239. ea[0].Trustee.ptstrName = (LPTSTR) pLocalSystemSID;
  240. ea[1].grfAccessPermissions = GENERIC_ALL;
  241. ea[1].grfAccessMode = SET_ACCESS;
  242. ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  243. ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  244. ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  245. ea[1].Trustee.ptstrName = (LPTSTR) pAdminSID;
  246. cExplicitAccess = 2;
  247. }
  248. else
  249. {
  250. if(! AllocateAndInitializeSid( &SIDAuthWorld, 1,
  251. SECURITY_WORLD_RID,
  252. 0, 0, 0, 0, 0, 0, 0,
  253. &pEveryoneSID) )
  254. {
  255. goto Exit;
  256. }
  257. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  258. // The ACE will allow Everyone read access to the key.
  259. ea[0].grfAccessPermissions = WRITE_DAC | WRITE_OWNER;
  260. ea[0].grfAccessMode = DENY_ACCESS;
  261. ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  262. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  263. ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  264. ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
  265. ea[1].grfAccessPermissions = GENERIC_ALL;
  266. ea[1].grfAccessMode = SET_ACCESS;
  267. ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  268. ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  269. ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  270. ea[1].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
  271. cExplicitAccess = 2;
  272. if (fAddAnonymousLogon) {
  273. if(! AllocateAndInitializeSid( &SIDAuthNT, 1,
  274. SECURITY_ANONYMOUS_LOGON_RID,
  275. 0, 0, 0, 0, 0, 0, 0,
  276. &pAnonymousLogonSID) )
  277. {
  278. goto Exit;
  279. }
  280. ea[2].grfAccessPermissions = WRITE_DAC | WRITE_OWNER;
  281. ea[2].grfAccessMode = DENY_ACCESS;
  282. ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  283. ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  284. ea[2].Trustee.TrusteeType = TRUSTEE_IS_USER;
  285. ea[2].Trustee.ptstrName = (LPTSTR) pAnonymousLogonSID;
  286. ea[3].grfAccessPermissions = GENERIC_ALL;
  287. ea[3].grfAccessMode = SET_ACCESS;
  288. ea[3].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  289. ea[3].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  290. ea[3].Trustee.TrusteeType = TRUSTEE_IS_USER;
  291. ea[3].Trustee.ptstrName = (LPTSTR) pAnonymousLogonSID;
  292. cExplicitAccess = 4;
  293. }
  294. }
  295. // Create a new ACL that contains the new ACEs.
  296. dwRes = SetEntriesInAcl(cExplicitAccess, ea, NULL, &pACL);
  297. if (ERROR_SUCCESS != dwRes)
  298. {
  299. goto Exit;
  300. }
  301. // Initialize a security descriptor.
  302. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
  303. SECURITY_DESCRIPTOR_MIN_LENGTH);
  304. if (pSD == NULL)
  305. {
  306. goto Exit;
  307. }
  308. if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  309. {
  310. goto Exit;
  311. }
  312. // Add the ACL to the security descriptor.
  313. if (!SetSecurityDescriptorDacl(pSD,
  314. TRUE, // fDaclPresent flag
  315. pACL,
  316. FALSE)) // not a default DACL
  317. {
  318. goto Exit;
  319. }
  320. // Initialize a security attributes structure.
  321. fRet = SetFileSecurity (str, DACL_SECURITY_INFORMATION, pSD);
  322. Exit:
  323. if (pEveryoneSID)
  324. FreeSid(pEveryoneSID);
  325. if (pAnonymousLogonSID)
  326. FreeSid(pAnonymousLogonSID);
  327. if (pLocalSystemSID)
  328. FreeSid(pLocalSystemSID);
  329. if (pAdminSID)
  330. FreeSid(pAdminSID);
  331. if (pACL)
  332. LocalFree(pACL);
  333. if (pSD)
  334. LocalFree(pSD);
  335. return fRet;
  336. }
  337. //
  338. // Given a directory path, this subroutine will create the direct layer by layer
  339. //
  340. BOOL CreateLayerDirectory( CString &str )
  341. {
  342. BOOL fReturn = TRUE;
  343. do
  344. {
  345. INT index=0;
  346. INT iLength = str.GetLength();
  347. // first find the index for the first directory
  348. if ( iLength > 2 )
  349. {
  350. if ( str[1] == _T(':'))
  351. {
  352. // assume the first character is driver letter
  353. if ( str[2] == _T('\\'))
  354. {
  355. index = 2;
  356. } else
  357. {
  358. index = 1;
  359. }
  360. } else if ( str[0] == _T('\\'))
  361. {
  362. if ( str[1] == _T('\\'))
  363. {
  364. BOOL fFound = FALSE;
  365. INT i;
  366. INT nNum = 0;
  367. // unc name
  368. for (i = 2; i < iLength; i++ )
  369. {
  370. if ( str[i]==_T('\\'))
  371. {
  372. // find it
  373. nNum ++;
  374. if ( nNum == 2 )
  375. {
  376. fFound = TRUE;
  377. break;
  378. }
  379. }
  380. }
  381. if ( fFound )
  382. {
  383. index = i;
  384. } else
  385. {
  386. // bad name
  387. break;
  388. }
  389. } else
  390. {
  391. index = 1;
  392. }
  393. }
  394. } else if ( str[0] == _T('\\'))
  395. {
  396. index = 0;
  397. }
  398. // okay ... build directory
  399. do
  400. {
  401. // find next one
  402. do
  403. {
  404. if ( index < ( iLength - 1))
  405. {
  406. index ++;
  407. } else
  408. {
  409. break;
  410. }
  411. } while ( str[index] != _T('\\'));
  412. TCHAR szCurrentDir[MAX_PATH+1];
  413. GetCurrentDirectory( MAX_PATH+1, szCurrentDir );
  414. if ( !SetCurrentDirectory( str.Left( index + 1 )))
  415. {
  416. if (( fReturn = CreateDirectory( str.Left( index + 1 ), NULL )) != TRUE )
  417. {
  418. break;
  419. }
  420. }
  421. SetCurrentDirectory( szCurrentDir );
  422. if ( index >= ( iLength - 1 ))
  423. {
  424. fReturn = TRUE;
  425. break;
  426. }
  427. } while ( TRUE );
  428. } while (FALSE);
  429. return(fReturn);
  430. }
  431. //
  432. // Used when the strings are passed in.
  433. //
  434. int MyMessageBox(HWND hWnd, LPCTSTR lpszTheMessage, LPCTSTR lpszTheTitle, UINT style)
  435. {
  436. int iReturn = IDOK;
  437. // make sure it goes to DebugOutput
  438. DebugOutput(_T("MyMessageBox: Title:%s, Msg:%s"), lpszTheTitle, lpszTheMessage);
  439. if (style & MB_ABORTRETRYIGNORE)
  440. {
  441. iReturn = IDIGNORE;
  442. }
  443. return iReturn;
  444. }
  445. void GetErrorMsg(int errCode, LPCTSTR szExtraMsg)
  446. {
  447. TCHAR pMsg[_MAX_PATH];
  448. FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
  449. NULL, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  450. pMsg, _MAX_PATH, NULL);
  451. lstrcat(pMsg, szExtraMsg);
  452. MyMessageBox(NULL, pMsg, _T(""), MB_OK | MB_SETFOREGROUND);
  453. return;
  454. }
  455. DWORD GetDebugLevel(void)
  456. {
  457. DWORD rc;
  458. DWORD err;
  459. DWORD size;
  460. DWORD type;
  461. HKEY hkey;
  462. err = RegOpenKey(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\microsoft\\windows\\currentversion\\setup"), &hkey);
  463. if (err != ERROR_SUCCESS) {return 0;}
  464. size = sizeof(DWORD);
  465. err = RegQueryValueEx(hkey,_T("OC Manager Debug Level"),0,&type,(LPBYTE)&rc,&size);
  466. if (err != ERROR_SUCCESS || type != REG_DWORD) {rc = 0;}
  467. RegCloseKey(hkey);
  468. return rc;
  469. }
  470. void MyLoadString(int nID, CString &csResult)
  471. {
  472. TCHAR buf[MAX_STR_LEN];
  473. if (LoadString(theApp.m_hDllHandle, nID, buf, MAX_STR_LEN))
  474. csResult = buf;
  475. return;
  476. }
  477. void MakePath(LPTSTR lpPath)
  478. {
  479. LPTSTR lpTmp;
  480. lpTmp = CharPrev( lpPath, lpPath + _tcslen(lpPath));
  481. // chop filename off
  482. while ( (lpTmp > lpPath) && *lpTmp && (*lpTmp != '\\') )
  483. lpTmp = CharPrev( lpPath, lpTmp );
  484. if ( *CharPrev( lpPath, lpTmp ) != ':' )
  485. *lpTmp = '\0';
  486. else
  487. *CharNext(lpTmp) = '\0';
  488. return;
  489. }
  490. void AddPath(LPTSTR szPath, LPCTSTR szName )
  491. {
  492. LPTSTR p = szPath;
  493. ASSERT(szPath);
  494. ASSERT(szName);
  495. // Find end of the string
  496. while (*p){p = _tcsinc(p);}
  497. // If no trailing backslash then add one
  498. if (*(_tcsdec(szPath, p)) != _T('\\'))
  499. {_tcscat(szPath, _T("\\"));}
  500. // if there are spaces precluding szName, then skip
  501. while ( *szName == ' ' ) szName = _tcsinc(szName);;
  502. // Add new name to existing path string
  503. _tcscat(szPath, szName);
  504. }
  505. // GetPrincipalSID is from \nt\private\inet\iis\ui\setup\osrc\dcomperm.cpp
  506. DWORD
  507. GetPrincipalSID (
  508. LPTSTR Principal,
  509. PSID *Sid,
  510. BOOL *pbWellKnownSID
  511. )
  512. {
  513. DebugOutput(_T("GetPrincipalSID:Principal=%s"), Principal);
  514. DWORD returnValue=ERROR_SUCCESS;
  515. CString csPrincipal = Principal;
  516. SID_IDENTIFIER_AUTHORITY SidIdentifierNTAuthority = SECURITY_NT_AUTHORITY;
  517. SID_IDENTIFIER_AUTHORITY SidIdentifierWORLDAuthority = SECURITY_WORLD_SID_AUTHORITY;
  518. PSID_IDENTIFIER_AUTHORITY pSidIdentifierAuthority;
  519. BYTE Count;
  520. DWORD dwRID[8];
  521. *pbWellKnownSID = TRUE;
  522. memset(&(dwRID[0]), 0, 8 * sizeof(DWORD));
  523. csPrincipal.MakeLower();
  524. if ( csPrincipal.Find(_T("administrators")) != -1 ) {
  525. // Administrators group
  526. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  527. Count = 2;
  528. dwRID[0] = SECURITY_BUILTIN_DOMAIN_RID;
  529. dwRID[1] = DOMAIN_ALIAS_RID_ADMINS;
  530. } else if (csPrincipal.Find(_T("system")) != -1) {
  531. // SYSTEM
  532. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  533. Count = 1;
  534. dwRID[0] = SECURITY_LOCAL_SYSTEM_RID;
  535. } else if (csPrincipal.Find(_T("networkservice")) != -1) {
  536. // SYSTEM
  537. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  538. Count = 1;
  539. dwRID[0] = SECURITY_NETWORK_SERVICE_RID;
  540. } else if (csPrincipal.Find(_T("service")) != -1) {
  541. // SYSTEM
  542. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  543. Count = 1;
  544. dwRID[0] = SECURITY_LOCAL_SERVICE_RID;
  545. } else if (csPrincipal.Find(_T("interactive")) != -1) {
  546. // INTERACTIVE
  547. pSidIdentifierAuthority = &SidIdentifierNTAuthority;
  548. Count = 1;
  549. dwRID[0] = SECURITY_INTERACTIVE_RID;
  550. } else if (csPrincipal.Find(_T("everyone")) != -1) {
  551. // Everyone
  552. pSidIdentifierAuthority = &SidIdentifierWORLDAuthority;
  553. Count = 1;
  554. dwRID[0] = SECURITY_WORLD_RID;
  555. } else {
  556. *pbWellKnownSID = FALSE;
  557. }
  558. if (*pbWellKnownSID) {
  559. if ( !AllocateAndInitializeSid(pSidIdentifierAuthority,
  560. (BYTE)Count,
  561. dwRID[0],
  562. dwRID[1],
  563. dwRID[2],
  564. dwRID[3],
  565. dwRID[4],
  566. dwRID[5],
  567. dwRID[6],
  568. dwRID[7],
  569. Sid) ) {
  570. returnValue = GetLastError();
  571. }
  572. } else {
  573. // get regular account sid
  574. DWORD sidSize;
  575. TCHAR refDomain [256];
  576. DWORD refDomainSize;
  577. SID_NAME_USE snu;
  578. sidSize = 0;
  579. refDomainSize = 255;
  580. LookupAccountName (NULL,
  581. Principal,
  582. *Sid,
  583. &sidSize,
  584. refDomain,
  585. &refDomainSize,
  586. &snu);
  587. returnValue = GetLastError();
  588. if (returnValue == ERROR_INSUFFICIENT_BUFFER) {
  589. *Sid = (PSID) malloc (sidSize);
  590. refDomainSize = 255;
  591. if (!LookupAccountName (NULL,
  592. Principal,
  593. *Sid,
  594. &sidSize,
  595. refDomain,
  596. &refDomainSize,
  597. &snu))
  598. {
  599. returnValue = GetLastError();
  600. } else {
  601. returnValue = ERROR_SUCCESS;
  602. }
  603. }
  604. }
  605. return returnValue;
  606. }
  607. // SetAdminACL taken from \nt\private\inet\iis\ui\setup\osrc\helper.cpp
  608. DWORD SetAdminACL(LPCTSTR szKeyPath, DWORD dwAccessForEveryoneAccount)
  609. {
  610. DebugOutputSafe(_T("SetAdminACL(%1!s!) Start."), szKeyPath);
  611. int iErr=0;
  612. DWORD dwErr=ERROR_SUCCESS;
  613. BOOL b = FALSE;
  614. DWORD dwLength = 0;
  615. PSECURITY_DESCRIPTOR pSD = NULL;
  616. PSECURITY_DESCRIPTOR outpSD = NULL;
  617. DWORD cboutpSD = 0;
  618. PACL pACLNew = NULL;
  619. DWORD cbACL = 0;
  620. PSID pAdminsSID = NULL, pEveryoneSID = NULL;
  621. PSID pServiceSID = NULL;
  622. PSID pNetworkServiceSID = NULL;
  623. BOOL bWellKnownSID = FALSE;
  624. // Initialize a new security descriptor
  625. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  626. if (NULL == pSD) {
  627. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  628. DebugOutput(_T("LocalAlloc failed"));
  629. goto Cleanup;
  630. }
  631. iErr = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
  632. if (iErr == 0)
  633. {
  634. dwErr=GetLastError();
  635. DebugOutput(_T("SetAdminACL:InitializeSecurityDescriptor FAILED. GetLastError()= 0x%x"), dwErr);
  636. goto Cleanup;
  637. }
  638. // Get Local Admins Sid
  639. dwErr = GetPrincipalSID (_T("Administrators"), &pAdminsSID, &bWellKnownSID);
  640. if (dwErr != ERROR_SUCCESS)
  641. {
  642. DebugOutput(_T("SetAdminACL:GetPrincipalSID(Administrators) FAILED. GetLastError()= 0x%x"), dwErr);
  643. goto Cleanup;
  644. }
  645. // Get Local Service Sid
  646. dwErr = GetPrincipalSID (_T("Service"), &pServiceSID, &bWellKnownSID);
  647. if (dwErr != ERROR_SUCCESS)
  648. {
  649. DebugOutput(_T("SetAdminACL:GetPrincipalSID(Local Service) FAILED. GetLastError()= 0x%x"), dwErr);
  650. goto Cleanup;
  651. }
  652. // Get Network Service Sid
  653. dwErr = GetPrincipalSID (_T("NetworkService"), &pNetworkServiceSID, &bWellKnownSID);
  654. if (dwErr != ERROR_SUCCESS)
  655. {
  656. DebugOutput(_T("SetAdminACL:GetPrincipalSID(Network Service) FAILED. GetLastError()= 0x%x"), dwErr);
  657. goto Cleanup;
  658. }
  659. // Get everyone Sid
  660. dwErr = GetPrincipalSID (_T("Everyone"), &pEveryoneSID, &bWellKnownSID);
  661. if (dwErr != ERROR_SUCCESS)
  662. {
  663. DebugOutput(_T("SetAdminACL:GetPrincipalSID(Everyone) FAILED. GetLastError()= 0x%x"), dwErr);
  664. goto Cleanup;
  665. }
  666. // Initialize a new ACL, which only contains 2 aaace
  667. cbACL = sizeof(ACL) +
  668. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pAdminsSID) - sizeof(DWORD)) +
  669. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pServiceSID) - sizeof(DWORD)) +
  670. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pNetworkServiceSID) - sizeof(DWORD)) +
  671. (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pEveryoneSID) - sizeof(DWORD)) ;
  672. pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
  673. if ( !pACLNew )
  674. {
  675. dwErr=ERROR_NOT_ENOUGH_MEMORY;
  676. DebugOutput(_T("SetAdminACL:pACLNew LocalAlloc(LPTR, FAILED. size = %u GetLastError()= 0x%x"), cbACL, dwErr);
  677. goto Cleanup;
  678. }
  679. if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION))
  680. {
  681. dwErr=GetLastError();
  682. DebugOutput(_T("SetAdminACL:InitializeAcl FAILED. GetLastError()= 0x%x"), dwErr);
  683. goto Cleanup;
  684. }
  685. if (!AddAccessAllowedAce(pACLNew,ACL_REVISION,(MD_ACR_READ |MD_ACR_WRITE |MD_ACR_RESTRICTED_WRITE |MD_ACR_UNSECURE_PROPS_READ |MD_ACR_ENUM_KEYS |MD_ACR_WRITE_DAC),pAdminsSID))
  686. {
  687. dwErr=GetLastError();
  688. DebugOutput(_T("SetAdminACL:AddAccessAllowedAce(pAdminsSID) FAILED. GetLastError()= 0x%x"), dwErr);
  689. goto Cleanup;
  690. }
  691. if (!AddAccessAllowedAce(pACLNew,ACL_REVISION,(MD_ACR_UNSECURE_PROPS_READ | MD_ACR_ENUM_KEYS),pServiceSID))
  692. {
  693. dwErr=GetLastError();
  694. DebugOutput(_T("SetAdminACL:AddAccessAllowedAce(pServiceSID) FAILED. GetLastError()= 0x%x"), dwErr);
  695. goto Cleanup;
  696. }
  697. if (!AddAccessAllowedAce(pACLNew,ACL_REVISION,(MD_ACR_UNSECURE_PROPS_READ |MD_ACR_ENUM_KEYS),pNetworkServiceSID))
  698. {
  699. dwErr=GetLastError();
  700. DebugOutput(_T("SetAdminACL:AddAccessAllowedAce(pNetworkServiceSID) FAILED. GetLastError()= 0x%x"), dwErr);
  701. goto Cleanup;
  702. }
  703. #if 0 // Don't allow Everyone to have perms
  704. if (!AddAccessAllowedAce(pACLNew,ACL_REVISION,dwAccessForEveryoneAccount,pEveryoneSID))
  705. {
  706. dwErr=GetLastError();
  707. DebugOutput(_T("SetAdminACL:AddAccessAllowedAce(pEveryoneSID) FAILED. GetLastError()= 0x%x"), dwErr);
  708. goto Cleanup;
  709. }
  710. #endif
  711. // Add the ACL to the security descriptor
  712. b = SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE);
  713. if (!b)
  714. {
  715. dwErr=GetLastError();
  716. DebugOutput(_T("SetAdminACL:SetSecurityDescriptorDacl(pACLNew) FAILED. GetLastError()= 0x%x"), dwErr);
  717. goto Cleanup;
  718. }
  719. b = SetSecurityDescriptorOwner(pSD, pAdminsSID, TRUE);
  720. if (!b)
  721. {
  722. dwErr=GetLastError();
  723. DebugOutput(_T("SetAdminACL:SetSecurityDescriptorOwner(pAdminsSID) FAILED. GetLastError()= 0x%x"), dwErr);
  724. goto Cleanup;
  725. }
  726. b = SetSecurityDescriptorGroup(pSD, pAdminsSID, TRUE);
  727. if (!b)
  728. {
  729. dwErr=GetLastError();
  730. DebugOutput(_T("SetAdminACL:SetSecurityDescriptorGroup(pAdminsSID) FAILED. GetLastError()= 0x%x"), dwErr);
  731. goto Cleanup;
  732. }
  733. // Security descriptor blob must be self relative
  734. b = MakeSelfRelativeSD(pSD, outpSD, &cboutpSD);
  735. if (!b && (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
  736. {
  737. dwErr=GetLastError();
  738. DebugOutput(_T("SetAdminACL:MakeSelfRelativeSD FAILED. GetLastError()= 0x%x"), dwErr);
  739. goto Cleanup;
  740. }
  741. outpSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GPTR, cboutpSD);
  742. if ( !outpSD )
  743. {
  744. dwErr=GetLastError();
  745. DebugOutput(_T("SetAdminACL:GlobalAlloc FAILED. cboutpSD = %u GetLastError()= 0x%x"), cboutpSD, dwErr);
  746. goto Cleanup;
  747. }
  748. b = MakeSelfRelativeSD( pSD, outpSD, &cboutpSD );
  749. if (!b)
  750. {
  751. dwErr=GetLastError();
  752. DebugOutput(_T("SetAdminACL:MakeSelfRelativeSD() FAILED. cboutpSD = %u GetLastError()= 0x%x"),cboutpSD, dwErr);
  753. goto Cleanup;
  754. }
  755. // Apply the new security descriptor to the metabase
  756. DebugOutput(_T("SetAdminACL:Write the new security descriptor to the Metabase. Start."));
  757. dwErr = WriteSDtoMetaBase(outpSD, szKeyPath);
  758. DebugOutput(_T("SetAdminACL:Write the new security descriptor to the Metabase. End."));
  759. Cleanup:
  760. // both of Administrators and Everyone are well-known SIDs, use FreeSid() to free them.
  761. if (outpSD){GlobalFree(outpSD);}
  762. if (pAdminsSID){FreeSid(pAdminsSID);}
  763. if (pServiceSID){FreeSid(pServiceSID);}
  764. if (pNetworkServiceSID){FreeSid(pNetworkServiceSID);}
  765. if (pEveryoneSID){FreeSid(pEveryoneSID);}
  766. if (pSD){LocalFree((HLOCAL) pSD);}
  767. if (pACLNew){LocalFree((HLOCAL) pACLNew);}
  768. DebugOutputSafe(_T("SetAdminACL(%1!s!) End."), szKeyPath);
  769. return (dwErr);
  770. }
  771. DWORD SetAdminACL_wrap(LPCTSTR szKeyPath, DWORD dwAccessForEveryoneAccount, BOOL bDisplayMsgOnErrFlag)
  772. {
  773. int bFinishedFlag = FALSE;
  774. UINT iMsg = NULL;
  775. DWORD dwReturn = ERROR_SUCCESS;
  776. // LogHeapState(FALSE, __FILE__, __LINE__);
  777. do
  778. {
  779. dwReturn = SetAdminACL(szKeyPath, dwAccessForEveryoneAccount);
  780. // LogHeapState(FALSE, __FILE__, __LINE__);
  781. if (FAILED(dwReturn))
  782. {
  783. // SetErrorFlag(__FILE__, __LINE__);
  784. if (bDisplayMsgOnErrFlag == TRUE)
  785. {
  786. CString msg;
  787. MyLoadString(IDS_RETRY, msg);
  788. iMsg = MyMessageBox( NULL, msg, _T(""), MB_ABORTRETRYIGNORE | MB_SETFOREGROUND );
  789. switch ( iMsg )
  790. {
  791. case IDIGNORE:
  792. dwReturn = ERROR_SUCCESS;
  793. goto SetAdminACL_wrap_Exit;
  794. case IDABORT:
  795. dwReturn = ERROR_OPERATION_ABORTED;
  796. goto SetAdminACL_wrap_Exit;
  797. case IDRETRY:
  798. break;
  799. default:
  800. break;
  801. }
  802. }
  803. else
  804. {
  805. // return whatever err happened
  806. goto SetAdminACL_wrap_Exit;
  807. }
  808. }
  809. else
  810. {
  811. break;
  812. }
  813. } while ( FAILED(dwReturn) );
  814. SetAdminACL_wrap_Exit:
  815. return dwReturn;
  816. }
  817. DWORD WriteSDtoMetaBase(PSECURITY_DESCRIPTOR outpSD, LPCTSTR szKeyPath)
  818. {
  819. DebugOutput(_T("WriteSDtoMetaBase: Start"));
  820. DWORD dwReturn = E_FAIL;
  821. DWORD dwLength = 0;
  822. CMDKey cmdKey;
  823. if (!outpSD)
  824. {
  825. dwReturn = ERROR_INVALID_SECURITY_DESCR;
  826. goto WriteSDtoMetaBase_Exit;
  827. }
  828. // Apply the new security descriptor to the metabase
  829. dwLength = GetSecurityDescriptorLength(outpSD);
  830. // open the metabase
  831. // stick it into the metabase. warning those hoses a lot because
  832. // it uses encryption. rsabase.dll
  833. cmdKey.CreateNode(METADATA_MASTER_ROOT_HANDLE, szKeyPath);
  834. if ( (METADATA_HANDLE)cmdKey )
  835. {
  836. DebugOutput(_T("WriteSDtoMetaBase:cmdKey():SetData(MD_ADMIN_ACL), dwdata = %u; outpSD = %p, Start"), dwLength, outpSD );
  837. dwReturn = cmdKey.SetData(MD_ADMIN_ACL,METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE,IIS_MD_UT_SERVER,BINARY_METADATA,dwLength,(LPBYTE)outpSD);
  838. if (FAILED(dwReturn))
  839. {
  840. // SetErrorFlag(__FILE__, __LINE__);
  841. DebugOutput(_T("WriteSDtoMetaBase:cmdKey():SetData(MD_ADMIN_ACL), FAILED. Code=0x%x. End."), dwReturn);
  842. }
  843. else
  844. {
  845. dwReturn = ERROR_SUCCESS;
  846. DebugOutput(_T("WriteSDtoMetaBase:cmdKey():SetData(MD_ADMIN_ACL), Success. End."));
  847. }
  848. cmdKey.Close();
  849. }
  850. else
  851. {
  852. dwReturn = E_FAIL;
  853. }
  854. WriteSDtoMetaBase_Exit:
  855. DebugOutput(_T("WriteSDtoMetaBase: End. Return=0x%x"), dwReturn);
  856. return dwReturn;
  857. }
  858. void SetupSetStringId_Wrapper(HINF hInf)
  859. {
  860. // Note, we only care about the intel variants since they're the only ones
  861. // special cased in the .INFs
  862. // Not anymore, we handles the [SourceDisksName] section as well
  863. SYSTEM_INFO SystemInfo;
  864. GetSystemInfo( &SystemInfo );
  865. TCHAR szSourceCatOSName[20];
  866. _tcscpy(szSourceCatOSName, _T("\\i386"));
  867. switch(SystemInfo.wProcessorArchitecture) {
  868. case PROCESSOR_ARCHITECTURE_AMD64:
  869. _tcscpy(szSourceCatOSName, _T("\\AMD64"));
  870. break;
  871. case PROCESSOR_ARCHITECTURE_IA64:
  872. _tcscpy(szSourceCatOSName, _T("\\IA64"));
  873. break;
  874. case PROCESSOR_ARCHITECTURE_INTEL:
  875. if (IsNEC_98) {
  876. _tcscpy(szSourceCatOSName, _T("\\Nec98"));
  877. }
  878. break;
  879. default:
  880. break;
  881. }
  882. // 34000 is no longer used
  883. //SetupSetDirectoryIdEx(hInf, 34000, szSourceCatOSName, SETDIRID_NOT_FULL_PATH, 0, 0);
  884. SetupSetDirectoryIdEx(hInf, 34001, szSourceCatOSName, SETDIRID_NOT_FULL_PATH, 0, 0);
  885. }