TWProcHelper.cpp 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870
  1. #include "StdAfx.h"
  2. #include "TWProcHelper.h"
  3. CTWProcHelper::CTWProcHelper(void)
  4. :m_hJob(NULL)
  5. {
  6. }
  7. CTWProcHelper::CTWProcHelper(HANDLE hJob)
  8. :m_hJob(hJob)
  9. {
  10. }
  11. CTWProcHelper::~CTWProcHelper(void)
  12. {
  13. if (m_hJob != NULL)
  14. {
  15. CloseHandle(m_hJob);
  16. m_hJob = NULL;
  17. }
  18. }
  19. // PrintError support function.
  20. // Simple wrapper function for error output.
  21. void CTWProcHelper::PrintError(LPCTSTR errDesc)
  22. {
  23. DWORD dwErrCode = GetLastError();
  24. LPCTSTR errMsg = ErrorMessage(dwErrCode);
  25. Dbg(TEXT("** ERROR ** %s: %s(%d)."), errDesc, errMsg, dwErrCode);
  26. LocalFree((LPVOID)errMsg);
  27. }
  28. void CTWProcHelper::PrintInfo(LPCTSTR lpszDesc)
  29. {
  30. Dbg("ProcHelper: %s.", lpszDesc);
  31. return;
  32. }
  33. // ErrorMessage support function.
  34. // Retrieves the system error message for the GetLastError() code.
  35. // Note: caller must use LocalFree() on the returned LPCTSTR buffer.
  36. LPCTSTR CTWProcHelper::ErrorMessage(DWORD error)
  37. {
  38. LPVOID lpMsgBuf;
  39. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
  40. | FORMAT_MESSAGE_FROM_SYSTEM
  41. | FORMAT_MESSAGE_IGNORE_INSERTS,
  42. NULL,
  43. error,
  44. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  45. (LPTSTR) &lpMsgBuf,
  46. 0,
  47. NULL);
  48. return((LPCTSTR)lpMsgBuf);
  49. }
  50. //===== Below is Functions about Job ========================
  51. BOOL CTWProcHelper::Create(PSECURITY_ATTRIBUTES psa, PCTSTR pszName)
  52. {
  53. m_hJob = CreateJobObject(psa, pszName);
  54. return(m_hJob != NULL);
  55. }
  56. BOOL CTWProcHelper::Open(PCTSTR pszName, DWORD dwDesiredAccess, BOOL fInheritHandle)
  57. {
  58. m_hJob = OpenJobObject(dwDesiredAccess, fInheritHandle, pszName);
  59. return(m_hJob != NULL);
  60. }
  61. BOOL CTWProcHelper::AssignProcess(HANDLE hProcess)
  62. {
  63. return(AssignProcessToJobObject(m_hJob, hProcess));
  64. }
  65. BOOL CTWProcHelper::AssignProcess(DWORD dwProcessId)
  66. {
  67. HANDLE hProcess = OpenProcess(
  68. PROCESS_SET_QUOTA | PROCESS_TERMINATE, FALSE, dwProcessId);
  69. if(hProcess == NULL)
  70. {
  71. PrintError("The hProcess is null which get from ProcessId");
  72. return FALSE;
  73. }
  74. return (AssignProcess(hProcess));
  75. }
  76. BOOL CTWProcHelper::SetBasicLimitInfo(PJOBOBJECT_BASIC_LIMIT_INFORMATION pjobli)
  77. {
  78. return(SetInformationJobObject(m_hJob,
  79. JobObjectBasicLimitInformation, pjobli, sizeof(*pjobli)));
  80. }
  81. BOOL CTWProcHelper::SetExtendedLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pjobeli)
  82. {
  83. return(SetInformationJobObject(m_hJob,
  84. JobObjectExtendedLimitInformation, pjobeli, sizeof(*pjobeli)));
  85. }
  86. BOOL CTWProcHelper::SetBasicUIRestrictions(DWORD fdwLimits)
  87. {
  88. JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir = { fdwLimits };
  89. return(SetInformationJobObject(m_hJob,
  90. JobObjectBasicUIRestrictions, &jobuir, sizeof(jobuir)));
  91. }
  92. BOOL CTWProcHelper::QueryEndOfJobTimeInfo(PDWORD pfdwEndOfJobTimeInfo)
  93. {
  94. JOBOBJECT_END_OF_JOB_TIME_INFORMATION joeojti;
  95. BOOL bRet = QueryInformationJobObject(m_hJob, JobObjectBasicUIRestrictions,
  96. &joeojti, sizeof(joeojti), NULL);
  97. if (bRet)
  98. *pfdwEndOfJobTimeInfo = joeojti.EndOfJobTimeAction;
  99. return(bRet);
  100. }
  101. BOOL CTWProcHelper::SetSecurityLimitInfo(PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjobsli)
  102. {
  103. return(SetInformationJobObject(m_hJob,
  104. JobObjectSecurityLimitInformation, pjobsli, sizeof(*pjobsli)));
  105. }
  106. BOOL CTWProcHelper::SetEndOfJobInfo(DWORD fdwEndOfJobInfo)
  107. {
  108. JOBOBJECT_END_OF_JOB_TIME_INFORMATION joeojti;
  109. joeojti.EndOfJobTimeAction = fdwEndOfJobInfo;
  110. return(SetInformationJobObject(m_hJob,
  111. JobObjectEndOfJobTimeInformation, &joeojti, sizeof(joeojti)));
  112. }
  113. BOOL CTWProcHelper::QueryBaseAndIOInfo(PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION pjobai)
  114. {
  115. return(QueryInformationJobObject(m_hJob,
  116. JobObjectBasicAndIoAccountingInformation, pjobai, sizeof(*pjobai),
  117. NULL));
  118. }
  119. BOOL CTWProcHelper::QueryExtendLimitInfo(PJOBOBJECT_EXTENDED_LIMIT_INFORMATION pjobeli)
  120. {
  121. return(QueryInformationJobObject(m_hJob,
  122. JobObjectExtendedLimitInformation, pjobeli, sizeof(*pjobeli),
  123. NULL));
  124. }
  125. BOOL CTWProcHelper::QueryBasicProcessIdList(DWORD dwMaxProcesses, PDWORD pdwProcessIdList, PDWORD pdwProcessesReturned)
  126. {
  127. // Calculate the # of bytes necessary
  128. DWORD cb = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) +
  129. (sizeof(DWORD) * (dwMaxProcesses - 1));
  130. // Allocate those bytes from the stack
  131. PJOBOBJECT_BASIC_PROCESS_ID_LIST pjobProIdList =
  132. (PJOBOBJECT_BASIC_PROCESS_ID_LIST) _alloca(cb);
  133. if(pjobProIdList == NULL)
  134. return FALSE;
  135. pjobProIdList->NumberOfProcessIdsInList = dwMaxProcesses;
  136. BOOL bRet = QueryInformationJobObject(m_hJob,
  137. JobObjectBasicProcessIdList, pjobProIdList, cb, NULL);
  138. if(bRet)
  139. {
  140. if(pdwProcessesReturned != NULL)
  141. {
  142. *pdwProcessesReturned = pjobProIdList->NumberOfProcessIdsInList;
  143. }
  144. CopyMemory(pdwProcessIdList, pjobProIdList->ProcessIdList,
  145. sizeof(DWORD) * pjobProIdList->NumberOfProcessIdsInList);
  146. }
  147. return bRet;
  148. }
  149. BOOL CTWProcHelper::QueryBasicUIRestrictions(PDWORD pfdwRestrictions)
  150. {
  151. JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
  152. BOOL bRet = QueryInformationJobObject(m_hJob, JobObjectBasicUIRestrictions,
  153. &jobuir, sizeof(jobuir), NULL);
  154. if (bRet)
  155. *pfdwRestrictions = jobuir.UIRestrictionsClass;
  156. return(bRet);
  157. }
  158. BOOL CTWProcHelper::QuerySecurityLimitInfo(
  159. PJOBOBJECT_SECURITY_LIMIT_INFORMATION pjosli)
  160. {
  161. return(QueryInformationJobObject(m_hJob, JobObjectSecurityLimitInformation,
  162. pjosli, sizeof(*pjosli), NULL));
  163. }
  164. BOOL CTWProcHelper::Terminate(UINT uExitCode)
  165. {
  166. return(TerminateJobObject(m_hJob, uExitCode));
  167. }
  168. BOOL CTWProcHelper::AssociateCompletionPort(HANDLE hIOCP, ULONG_PTR CompKey)
  169. {
  170. JOBOBJECT_ASSOCIATE_COMPLETION_PORT joacp = { (PVOID) CompKey, hIOCP };
  171. return(SetInformationJobObject(m_hJob,
  172. JobObjectAssociateCompletionPortInformation, &joacp, sizeof(joacp)));
  173. }
  174. BOOL CTWProcHelper::QueryAssociatedCompletionPort
  175. (PJOBOBJECT_ASSOCIATE_COMPLETION_PORT pjoacp)
  176. {
  177. return(QueryInformationJobObject(m_hJob,
  178. JobObjectAssociateCompletionPortInformation, pjoacp, sizeof(*pjoacp),
  179. NULL));
  180. }
  181. void CTWProcHelper::GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize)
  182. {
  183. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
  184. FALSE, PID);
  185. if (hProcess == NULL) {
  186. _tcscpy_s(szProcessName, cchSize, TEXT("???"));
  187. return;
  188. }
  189. if (GetModuleFileNameEx(hProcess, (HMODULE)0, szProcessName, cchSize)
  190. == 0) {
  191. // GetModuleFileNameEx could fail when the address space
  192. // is not completely initialized. This occurs when the job
  193. // notification happens.
  194. // Hopefully, GetProcessImageFileNameW still works even though
  195. // the obtained path is more complication to decipher
  196. // \Device\HarddiskVolume1\Windows\System32\notepad.exe
  197. //if (!GetProcessImageFileName(hProcess, szProcessName, cchSize)) {
  198. // _tcscpy_s(szProcessName, cchSize, TEXT("???"));
  199. //}
  200. DWORD dwSize = (DWORD) cchSize;
  201. if(QueryFullProcessImageName(hProcess, 0, szProcessName, &dwSize) == 0)
  202. {
  203. if (!GetProcessImageFileName(hProcess, szProcessName, cchSize)) {
  204. _tcscpy_s(szProcessName, cchSize, TEXT("???"));
  205. }
  206. }
  207. }
  208. // but it is easier to call this function instead that works fine
  209. // in all situations.
  210. // Don't forget to close the process handle
  211. CloseHandle(hProcess);
  212. }
  213. BOOL CTWProcHelper::DestoryProcess(DWORD dwProcessId)
  214. {
  215. HANDLE hProcess = OpenProcess(
  216. PROCESS_SET_QUOTA | PROCESS_TERMINATE, FALSE, dwProcessId);
  217. if(hProcess == NULL)
  218. {
  219. PrintError("The hProcess is null which get from ProcessId");
  220. return FALSE;
  221. }
  222. BOOL bRet = TerminateProcess(hProcess, 0);
  223. if(!bRet)
  224. {
  225. PrintError("TerminateProcess failed");
  226. }
  227. return bRet;
  228. }
  229. //===== Above is Functions about Job ========================
  230. DWORD CTWProcHelper::ModifyDefaultDacl(HANDLE hProcess)
  231. {
  232. int i;
  233. ACL_SIZE_INFORMATION asi;
  234. ACCESS_ALLOWED_ACE *pTempAce;
  235. DWORD dwNewAclSize;
  236. DWORD dwSize = 0;
  237. DWORD dwTokenInfoLength = 0;
  238. DWORD dwResult = -1;
  239. HANDLE hToken = NULL;
  240. PACL pNewAcl = NULL;
  241. PSID pEveryoneSID = NULL;
  242. SID_IDENTIFIER_AUTHORITY sidAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
  243. TOKEN_DEFAULT_DACL tddNew;
  244. TOKEN_DEFAULT_DACL *ptdd = NULL;
  245. TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl;
  246. __try
  247. {
  248. //获取与进程关联的令牌
  249. if (!OpenProcessToken(hProcess, TOKEN_QUERY |
  250. TOKEN_ADJUST_DEFAULT, &hToken))
  251. {
  252. dwResult = GetLastError();
  253. __leave;
  254. }
  255. if (!GetTokenInformation(hToken, tic, (LPVOID)NULL,
  256. dwTokenInfoLength, &dwSize))
  257. {
  258. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  259. {
  260. ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize);
  261. if (ptdd == NULL)
  262. {
  263. dwResult = GetLastError();
  264. __leave;
  265. }
  266. //直接获取令牌的缺省 DACL
  267. if (!GetTokenInformation(hToken, tic, (LPVOID)ptdd, dwSize, &dwSize))
  268. {
  269. dwResult = GetLastError();
  270. __leave;
  271. }
  272. }
  273. else
  274. {
  275. dwResult = GetLastError();
  276. __leave;
  277. }
  278. }
  279. //获取访问控制列表信息
  280. if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID)&asi,
  281. (DWORD)sizeof(ACL_SIZE_INFORMATION),
  282. AclSizeInformation))
  283. {
  284. dwResult = GetLastError();
  285. __leave;
  286. }
  287. //
  288. // Create a well-known SID for the Everyone group.
  289. //
  290. if (!AllocateAndInitializeSid(&sidAuthWorld, 1, SECURITY_WORLD_RID,
  291. 0, 0, 0, 0, 0, 0, 0,
  292. &pEveryoneSID))
  293. {
  294. dwResult = GetLastError();
  295. __leave;
  296. }
  297. //
  298. // Compute the size of the new ACL.
  299. //
  300. dwNewAclSize = asi.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) +
  301. GetLengthSid(pEveryoneSID) - sizeof(DWORD);
  302. //
  303. // Allocate buffer for the new ACL.
  304. //
  305. pNewAcl = (PACL) LocalAlloc(LPTR, dwNewAclSize);
  306. if (pNewAcl == NULL)
  307. {
  308. dwResult = GetLastError();
  309. __leave;
  310. }
  311. //
  312. // Intialize the ACL.
  313. //
  314. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
  315. {
  316. dwResult = GetLastError();
  317. __leave;
  318. }
  319. //
  320. // Loop through all the ACEs.
  321. // 轮询所有的访问控制项
  322. //
  323. for (i = 0; i < (int) asi.AceCount; i++)
  324. {
  325. //
  326. // Get current ACE.
  327. //
  328. if (!GetAce(ptdd->DefaultDacl, i, (LPVOID *)&pTempAce))
  329. {
  330. dwResult = GetLastError();
  331. __leave;
  332. }
  333. //
  334. // 添加访问控制项到指定的访问控制列表
  335. //
  336. if (!AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pTempAce,
  337. ((PACE_HEADER)pTempAce)->AceSize))
  338. {
  339. dwResult = GetLastError();
  340. __leave;
  341. }
  342. }
  343. //
  344. // 添加任意访问控制项到访问控制项列表的末尾
  345. //
  346. if (!AddAccessAllowedAce(pNewAcl, ACL_REVISION, GENERIC_ALL,/*访问权限掩码指定ACE控制的访问权限*/
  347. pEveryoneSID))
  348. {
  349. dwResult = GetLastError();
  350. __leave;
  351. }
  352. //
  353. // Set the new Default DACL.
  354. //
  355. tddNew.DefaultDacl = pNewAcl;
  356. if (!SetTokenInformation(hToken, tic, (LPVOID)&tddNew,
  357. dwNewAclSize))
  358. {
  359. dwResult = GetLastError();
  360. __leave;
  361. }
  362. dwResult = 0;
  363. }
  364. __finally
  365. {
  366. //
  367. // Free the buffer for the sid.
  368. //
  369. if (pEveryoneSID)
  370. {
  371. FreeSid(pEveryoneSID);
  372. }
  373. //
  374. // Free the buffers.
  375. //
  376. if (pNewAcl)
  377. {
  378. LocalFree((HLOCAL)pNewAcl);
  379. }
  380. if (ptdd)
  381. {
  382. LocalFree((HLOCAL)ptdd);
  383. }
  384. //
  385. // Close the access token.
  386. //
  387. if (hToken)
  388. {
  389. CloseHandle(hToken);
  390. }
  391. }
  392. return dwResult;
  393. }
  394. BOOL CTWProcHelper::SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
  395. {
  396. HANDLE hToken = NULL;
  397. if (!OpenProcessToken(GetCurrentProcess(),
  398. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  399. {
  400. PrintError("OpenProcessToken failed");
  401. return FALSE;
  402. }
  403. return SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);
  404. }
  405. BOOL CTWProcHelper::SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
  406. {
  407. TOKEN_PRIVILEGES tp;
  408. LUID luid;
  409. if ( !LookupPrivilegeValue(
  410. NULL, // lookup privilege on local system
  411. lpszPrivilege, // privilege to lookup
  412. &luid ) ) // receives LUID of privilege
  413. {
  414. Dbg("LookupPrivilegeValue error: %u\n", GetLastError() );
  415. return FALSE;
  416. }
  417. tp.PrivilegeCount = 1;
  418. tp.Privileges[0].Luid = luid;
  419. if (bEnablePrivilege)
  420. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  421. else
  422. tp.Privileges[0].Attributes = 0;
  423. // Enable the privilege or disable all privileges.
  424. if ( !AdjustTokenPrivileges(
  425. hToken,
  426. FALSE,
  427. &tp,
  428. sizeof(TOKEN_PRIVILEGES),
  429. (PTOKEN_PRIVILEGES) NULL,
  430. (PDWORD) NULL) )
  431. {
  432. Dbg("AdjustTokenPrivileges error: %u\n", GetLastError() );
  433. return FALSE;
  434. }
  435. if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
  436. {
  437. Dbg("The token does not have the specified privilege. \n");
  438. return FALSE;
  439. }
  440. return TRUE;
  441. }
  442. BOOL CTWProcHelper::CreateLowerProcess(LPTSTR lpCommandLine)
  443. {
  444. BOOL bResult = 0;
  445. HANDLE hToken = NULL;
  446. HANDLE hNewToken = NULL;
  447. // Low integrity SID
  448. CHAR szIntegritySid[20] = "S-1-16-4096";
  449. PSID pIntegritySid = NULL;
  450. TOKEN_MANDATORY_LABEL tml = {0};
  451. PROCESS_INFORMATION pi = {0};
  452. STARTUPINFO si = {0};
  453. ULONG exitCode = 0;
  454. __try
  455. {
  456. if (!OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hToken))
  457. __leave;
  458. if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
  459. SecurityImpersonation, TokenPrimary, &hNewToken))
  460. {
  461. if (ConvertStringSidToSid(szIntegritySid, &pIntegritySid))
  462. {
  463. tml.Label.Attributes = SE_GROUP_INTEGRITY;
  464. tml.Label.Sid = pIntegritySid;
  465. // Set the process integrity level
  466. if (SetTokenInformation(hNewToken, TokenIntegrityLevel, &tml,
  467. sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)))
  468. {
  469. bResult = CreateProcessAsUser(
  470. hNewToken, // access token
  471. NULL, // file to execute
  472. lpCommandLine, // command line
  473. NULL, // pointer to process SECURITY_ATTRIBUTES
  474. NULL, // pointer to thread SECURITY_ATTRIBUTES
  475. FALSE, // handles are not inheritable
  476. 0, // creation flags
  477. NULL, // pointer to new environment block
  478. NULL, // name of current directory
  479. &si, // pointer to STARTUPINFO structure
  480. &pi // receives information about new process
  481. );
  482. //DWORD dw=GetLastError();
  483. //CHAR ch[100];
  484. //sDbg(ch, "CreateProcessAsUser getlasterror =%d",dw);
  485. //MessageBox(NULL,ch,"13",MB_OK);
  486. RevertToSelf();
  487. if(bResult)
  488. {
  489. if (pi.hProcess != INVALID_HANDLE_VALUE)
  490. {
  491. //WaitForSingleObject(pi.hProcess, INFINITE);
  492. CloseHandle(pi.hProcess);
  493. }
  494. if (pi.hThread != INVALID_HANDLE_VALUE)
  495. CloseHandle(pi.hThread);
  496. }
  497. }
  498. }
  499. }
  500. }
  501. __finally
  502. {
  503. if(pIntegritySid)
  504. {
  505. LocalFree(pIntegritySid);
  506. }
  507. //
  508. // Close the access token.
  509. //
  510. if (hToken)
  511. {
  512. CloseHandle(hToken);
  513. }
  514. if(hNewToken)
  515. {
  516. CloseHandle(hNewToken);
  517. }
  518. }
  519. return bResult;
  520. }
  521. BOOL CTWProcHelper::LowerThreadIntegirtyLevel()
  522. {
  523. if(!ImpersonateSelf(SecurityIdentification))
  524. {
  525. PrintError("ImpersonateSelf(SecurityIdentification)");
  526. return FALSE;
  527. }
  528. return TRUE;
  529. HANDLE hToken = NULL;
  530. HANDLE hNewToken = NULL;
  531. BOOL bResult = FALSE;
  532. PSID pEveryoneSID = NULL;
  533. SID_IDENTIFIER_AUTHORITY sidManLabel = SECURITY_MANDATORY_LABEL_AUTHORITY;
  534. PSID pIntegritySid = NULL;
  535. TOKEN_MANDATORY_LABEL tml = { 0 };
  536. __try
  537. {
  538. //获取与进程关联的令牌
  539. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY
  540. | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT | TOKEN_ASSIGN_PRIMARY,
  541. &hToken))
  542. {
  543. PrintError("OpenProcessToken failed");
  544. __leave;
  545. }
  546. // Duplicate the primary token of the current process.
  547. if (!DuplicateTokenEx(hToken, 0, NULL, SecurityImpersonation,
  548. TokenPrimary, &hNewToken))
  549. {
  550. PrintError("DuplicateTokenEx failed");
  551. __leave;
  552. }
  553. // Create the low integrity SID.
  554. if (!AllocateAndInitializeSid(&sidManLabel, 1, SECURITY_MANDATORY_LOW_RID,
  555. 0, 0, 0, 0, 0, 0, 0, &pIntegritySid))
  556. {
  557. PrintError("AllocateAndInitializeSid failed");
  558. __leave;
  559. }
  560. tml.Label.Attributes = SE_GROUP_INTEGRITY;
  561. tml.Label.Sid = pIntegritySid;
  562. // Set the integrity level in the access token to low.
  563. if (!SetTokenInformation(hNewToken, TokenIntegrityLevel, &tml,
  564. (sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))))
  565. {
  566. PrintError("SetTokenInformation failed");
  567. __leave;
  568. }
  569. HANDLE hThread = GetCurrentThread();
  570. if (!SetThreadToken(&hThread, hNewToken))
  571. {
  572. PrintError("SetThreadToken failed");
  573. __leave;
  574. }
  575. RevertToSelf();
  576. bResult = TRUE;
  577. }
  578. __finally
  579. {
  580. if(pIntegritySid)
  581. {
  582. LocalFree(pIntegritySid);
  583. }
  584. //
  585. // Close the access token.
  586. //
  587. if (hToken)
  588. {
  589. CloseHandle(hToken);
  590. }
  591. if(hNewToken)
  592. {
  593. CloseHandle(hNewToken);
  594. }
  595. }
  596. return bResult;
  597. }
  598. void CTWProcHelper::SetLowLabelToFile(LPCTSTR lpszFileName)
  599. {
  600. if(lpszFileName == NULL || strlen(lpszFileName) <= 0)
  601. return;
  602. // The LABEL_SECURITY_INFORMATION SDDL SACL to be set for low integrity
  603. #define LOW_INTEGRITY_SDDL_SACL_W "S:(ML;;NW;;;LW)"
  604. DWORD dwErr = ERROR_SUCCESS;
  605. PSECURITY_DESCRIPTOR pSD = NULL;
  606. //SECURITY_MANDATORY_LOW_RID
  607. PACL pSacl = NULL; // not allocated
  608. BOOL fSaclPresent = FALSE;
  609. BOOL fSaclDefaulted = FALSE;
  610. CHAR szPath[MAX_PATH] = {0};
  611. _tcscpy_s(szPath, lpszFileName);
  612. Dbg("szPath:%s", szPath);
  613. if (ConvertStringSecurityDescriptorToSecurityDescriptorA(
  614. LOW_INTEGRITY_SDDL_SACL_W, SDDL_REVISION_1, &pSD, NULL))
  615. {
  616. //Dbg("enter 1");
  617. if (GetSecurityDescriptorSacl(pSD, &fSaclPresent, &pSacl,
  618. &fSaclDefaulted))
  619. {
  620. //Dbg("enter 2");
  621. // Note that psidOwner, psidGroup, and pDacl are
  622. // all NULL and set the new LABEL_SECURITY_INFORMATION
  623. dwErr = SetNamedSecurityInfoA((LPSTR)szPath,
  624. SE_FILE_OBJECT, LABEL_SECURITY_INFORMATION,
  625. NULL, NULL, NULL, pSacl);
  626. //Dbg("enter 3: %d.", dwErr);
  627. }
  628. LocalFree(pSD);
  629. }
  630. }
  631. BOOL CTWProcHelper::GetProcessIntegrityLevel(HANDLE hProcess, PDWORD pIntegrityLevel,
  632. PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy)
  633. {
  634. HANDLE hToken = NULL;
  635. if (!OpenProcessToken(hProcess, TOKEN_READ, &hToken))
  636. {
  637. return(FALSE);
  638. }
  639. BOOL bReturn = FALSE;
  640. // First, compute the size of the buffer to get the Integrity level
  641. DWORD dwNeededSize = 0;
  642. if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwNeededSize))
  643. {
  644. PTOKEN_MANDATORY_LABEL pTokenInfo = NULL;
  645. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  646. {
  647. pTokenInfo = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwNeededSize);
  648. if (pTokenInfo != NULL)
  649. {
  650. if (GetTokenInformation(hToken, TokenIntegrityLevel, pTokenInfo,
  651. dwNeededSize, &dwNeededSize))
  652. {
  653. *pIntegrityLevel =
  654. *GetSidSubAuthority(
  655. pTokenInfo->Label.Sid,
  656. (*GetSidSubAuthorityCount(pTokenInfo->Label.Sid)-1)
  657. );
  658. bReturn = TRUE;
  659. }
  660. LocalFree(pTokenInfo);
  661. }
  662. }
  663. }
  664. // Try to get the policy if the integrity level was available
  665. if (bReturn)
  666. {
  667. *pPolicy = TOKEN_MANDATORY_POLICY_OFF;
  668. dwNeededSize = sizeof(DWORD);
  669. GetTokenInformation(hToken, TokenMandatoryPolicy, pPolicy,
  670. dwNeededSize, &dwNeededSize);
  671. }
  672. // Look for the resource policy
  673. *pResourceIntegrityLevel = 0; // 0 means none explicitely set
  674. *pResourcePolicy = 0;
  675. PACL pSACL = NULL;
  676. PSECURITY_DESCRIPTOR pSD = NULL;
  677. DWORD dwResult = ERROR_SUCCESS;
  678. // Look for the no-read-up/no-write-up policy in the SACL
  679. if (hToken != NULL)
  680. {
  681. dwResult = GetSecurityInfo(
  682. hProcess, SE_KERNEL_OBJECT,
  683. LABEL_SECURITY_INFORMATION,
  684. NULL, NULL, NULL,
  685. &pSACL, &pSD
  686. );
  687. if (dwResult == ERROR_SUCCESS)
  688. {
  689. if (pSACL != NULL)
  690. {
  691. SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
  692. if ((pSACL->AceCount > 0) && (GetAce(pSACL, 0, (PVOID*)&pACE)))
  693. {
  694. if (pACE != NULL)
  695. {
  696. SID* pSID = (SID*)(&pACE->SidStart);
  697. *pResourceIntegrityLevel = pSID->SubAuthority[0];
  698. *pResourcePolicy = pACE->Mask;
  699. }
  700. }
  701. }
  702. }
  703. // Cleanup memory allocated on our behalf
  704. if (pSD != NULL)
  705. LocalFree(pSD);
  706. }
  707. // Don't forget to close the token handle.
  708. CloseHandle(hToken);
  709. return(bReturn);
  710. }
  711. BOOL CTWProcHelper::GetProcessIntegrityLevel(DWORD PID, PDWORD pIntegrityLevel,
  712. PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy)
  713. {
  714. // Sanity checks
  715. if ((PID <= 0) || (pIntegrityLevel == NULL))
  716. return(FALSE);
  717. // Check if we can get information for this process
  718. HANDLE hProcess = OpenProcess(
  719. READ_CONTROL | PROCESS_QUERY_INFORMATION,
  720. FALSE, PID);
  721. if (hProcess == NULL)
  722. return(FALSE);
  723. BOOL bReturn = GetProcessIntegrityLevel(hProcess, pIntegrityLevel,
  724. pPolicy, pResourceIntegrityLevel, pResourcePolicy);
  725. // Don't forget to release the process handle
  726. CloseHandle(hProcess);
  727. return(bReturn);
  728. }
  729. BOOL CTWProcHelper::CreateSecurityDescriptor()
  730. {
  731. BOOL bRet = FALSE;
  732. DWORD dwRes, dwDisposition;
  733. PSID pEveryoneSID = NULL, pAdminSID = NULL;
  734. PACL pACL = NULL;
  735. PSECURITY_DESCRIPTOR pSD = NULL;
  736. EXPLICIT_ACCESS ea[2];
  737. SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
  738. SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  739. SECURITY_ATTRIBUTES sa;
  740. LONG lRes;
  741. HKEY hkSub = NULL;
  742. // Create a well-known SID for the Everyone group.
  743. if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
  744. SECURITY_WORLD_RID,
  745. 0, 0, 0, 0, 0, 0, 0,
  746. &pEveryoneSID))
  747. {
  748. Dbg(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
  749. goto Cleanup;
  750. }
  751. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  752. // The ACE will allow Everyone read access to the key.
  753. ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
  754. ea[0].grfAccessPermissions = KEY_READ;
  755. ea[0].grfAccessMode = SET_ACCESS;
  756. ea[0].grfInheritance= NO_INHERITANCE;
  757. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  758. ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  759. ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
  760. // Create a SID for the BUILTIN\Administrators group.
  761. if(! AllocateAndInitializeSid(&SIDAuthNT, 2,
  762. SECURITY_BUILTIN_DOMAIN_RID,
  763. DOMAIN_ALIAS_RID_ADMINS,
  764. 0, 0, 0, 0, 0, 0,
  765. &pAdminSID))
  766. {
  767. Dbg(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
  768. goto Cleanup;
  769. }
  770. // Initialize an EXPLICIT_ACCESS structure for an ACE.
  771. // The ACE will allow the Administrators group full access to
  772. // the key.
  773. ea[1].grfAccessPermissions = KEY_ALL_ACCESS;
  774. ea[1].grfAccessMode = SET_ACCESS;
  775. ea[1].grfInheritance= NO_INHERITANCE;
  776. ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  777. ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  778. ea[1].Trustee.ptstrName = (LPTSTR) pAdminSID;
  779. // Create a new ACL that contains the new ACEs.
  780. dwRes = SetEntriesInAcl(2, ea, NULL, &pACL);
  781. if (ERROR_SUCCESS != dwRes)
  782. {
  783. Dbg(_T("SetEntriesInAcl Error %u\n"), GetLastError());
  784. goto Cleanup;
  785. }
  786. // Initialize a security descriptor.
  787. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
  788. SECURITY_DESCRIPTOR_MIN_LENGTH);
  789. if (NULL == pSD)
  790. {
  791. Dbg(_T("LocalAlloc Error %u\n"), GetLastError());
  792. goto Cleanup;
  793. }
  794. if (!InitializeSecurityDescriptor(pSD,
  795. SECURITY_DESCRIPTOR_REVISION))
  796. {
  797. Dbg(_T("InitializeSecurityDescriptor Error %u\n"),
  798. GetLastError());
  799. goto Cleanup;
  800. }
  801. // Add the ACL to the security descriptor.
  802. if (!SetSecurityDescriptorDacl(pSD,
  803. TRUE, // bDaclPresent flag
  804. pACL,
  805. FALSE)) // not a default DACL
  806. {
  807. Dbg(_T("SetSecurityDescriptorDacl Error %u\n"),
  808. GetLastError());
  809. goto Cleanup;
  810. }
  811. // Initialize a security attributes structure.
  812. sa.nLength = sizeof (SECURITY_ATTRIBUTES);
  813. sa.lpSecurityDescriptor = pSD;
  814. sa.bInheritHandle = FALSE;
  815. // Use the security attributes to set the security descriptor
  816. // when you create a key.
  817. lRes = RegCreateKeyEx(HKEY_CURRENT_USER, _T("TWKey"), 0, _T(""), 0,
  818. KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
  819. Dbg(_T("RegCreateKeyEx result %u\n"), lRes );
  820. /*
  821. // 运行进程并等待其正常结束
  822. PROCESS_INFORMATION ProcessInfo;
  823. STARTUPINFO StartupInfo;
  824. ZeroMemory(&StartupInfo, sizeof(StartupInfo));
  825. StartupInfo.cb = sizeof(StartupInfo);
  826. if (CreateProcess("c:\\winnt\\notepad.exe", NULL,
  827. &sa, NULL, FALSE, 0, NULL,
  828. NULL, &StartupInfo, &ProcessInfo))
  829. {
  830. WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
  831. CloseHandle(ProcessInfo.hThread);
  832. CloseHandle(ProcessInfo.hProcess);
  833. }
  834. else
  835. {
  836. Dbg("CreateProcess failed!\n");
  837. goto Cleanup;
  838. }
  839. */
  840. if(lRes == ERROR_SUCCESS)
  841. bRet = TRUE;
  842. Cleanup:
  843. if (pEveryoneSID)
  844. FreeSid(pEveryoneSID);
  845. if (pAdminSID)
  846. FreeSid(pAdminSID);
  847. if (pACL)
  848. LocalFree(pACL);
  849. if (pSD)
  850. LocalFree(pSD);
  851. if (hkSub)
  852. RegCloseKey(hkSub);
  853. return bRet;
  854. }
  855. DWORD CTWProcHelper::AddAceToObjectsSecurityDescriptor(
  856. LPTSTR pszObjName,
  857. SE_OBJECT_TYPE ObjectType,
  858. LPTSTR pszTrustee,
  859. TRUSTEE_FORM TrusteeForm,
  860. DWORD dwAccessRights,
  861. ACCESS_MODE AccessMode,
  862. DWORD dwInheritance)
  863. {
  864. DWORD dwRes = 0;
  865. PACL pOldDACL = NULL, pNewDACL = NULL;
  866. PSECURITY_DESCRIPTOR pSD = NULL;
  867. EXPLICIT_ACCESS ea;
  868. if (NULL == pszObjName)
  869. return ERROR_INVALID_PARAMETER;
  870. // Get a pointer to the existing DACL.
  871. dwRes = GetNamedSecurityInfo(pszObjName, ObjectType,
  872. DACL_SECURITY_INFORMATION,
  873. NULL, NULL, &pOldDACL, NULL, &pSD);
  874. if (ERROR_SUCCESS != dwRes)
  875. {
  876. Dbg( "GetNamedSecurityInfo Error %u\n", dwRes );
  877. goto Cleanup;
  878. }
  879. // Initialize an EXPLICIT_ACCESS structure for the new ACE.
  880. ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  881. ea.grfAccessPermissions = dwAccessRights;
  882. ea.grfAccessMode = AccessMode;
  883. ea.grfInheritance= dwInheritance;
  884. ea.Trustee.TrusteeForm = TrusteeForm;
  885. ea.Trustee.ptstrName = pszTrustee;
  886. // Create a new ACL that merges the new ACE
  887. // into the existing DACL.
  888. dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
  889. if (ERROR_SUCCESS != dwRes)
  890. {
  891. Dbg( "SetEntriesInAcl Error %u\n", dwRes );
  892. goto Cleanup;
  893. }
  894. // Attach the new ACL as the object's DACL.
  895. dwRes = SetNamedSecurityInfo(pszObjName, ObjectType,
  896. DACL_SECURITY_INFORMATION,
  897. NULL, NULL, pNewDACL, NULL);
  898. if (ERROR_SUCCESS != dwRes)
  899. {
  900. Dbg( "SetNamedSecurityInfo Error %u\n", dwRes );
  901. goto Cleanup;
  902. }
  903. Cleanup:
  904. if(pSD != NULL)
  905. LocalFree((HLOCAL) pSD);
  906. if(pNewDACL != NULL)
  907. LocalFree((HLOCAL) pNewDACL);
  908. return dwRes;
  909. }
  910. BOOL CTWProcHelper::TakeOwnership(LPTSTR lpszOwnFile)
  911. {
  912. BOOL bRetval = FALSE;
  913. HANDLE hToken = NULL;
  914. PSID pSIDAdmin = NULL;
  915. PSID pSIDEveryone = NULL;
  916. PACL pACL = NULL;
  917. SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
  918. SECURITY_WORLD_SID_AUTHORITY;
  919. SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  920. const int NUM_ACES = 2;
  921. EXPLICIT_ACCESS ea[NUM_ACES];
  922. DWORD dwRes;
  923. // Specify the DACL to use.
  924. // Create a SID for the Everyone group.
  925. if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
  926. SECURITY_WORLD_RID,
  927. 0,
  928. 0, 0, 0, 0, 0, 0,
  929. &pSIDEveryone))
  930. {
  931. Dbg("AllocateAndInitializeSid (Everyone) error %u\n",
  932. GetLastError());
  933. goto Cleanup;
  934. }
  935. // Create a SID for the BUILTIN\Administrators group.
  936. if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
  937. SECURITY_BUILTIN_DOMAIN_RID,
  938. DOMAIN_ALIAS_RID_ADMINS,
  939. 0, 0, 0, 0, 0, 0,
  940. &pSIDAdmin))
  941. {
  942. Dbg("AllocateAndInitializeSid (Admin) error %u\n",
  943. GetLastError());
  944. goto Cleanup;
  945. }
  946. ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));
  947. // Set read access for Everyone.
  948. ea[0].grfAccessPermissions = GENERIC_READ; //指定ACE允许,否认或审查受托人权限的位标志
  949. ea[0].grfAccessMode = SET_ACCESS; //对于DACL, 指定ACL是否允许或者拒绝指定访问权限
  950. ea[0].grfInheritance = NO_INHERITANCE;
  951. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  952. ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  953. ea[0].Trustee.ptstrName = (LPTSTR) pSIDEveryone;
  954. // Set full control for Administrators.
  955. ea[1].grfAccessPermissions = GENERIC_ALL;
  956. ea[1].grfAccessMode = SET_ACCESS;
  957. ea[1].grfInheritance = NO_INHERITANCE;
  958. ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  959. ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  960. ea[1].Trustee.ptstrName = (LPTSTR) pSIDAdmin;
  961. if (ERROR_SUCCESS != SetEntriesInAcl(NUM_ACES, ea, NULL, &pACL))
  962. {
  963. Dbg("Failed SetEntriesInAcl\n");
  964. goto Cleanup;
  965. }
  966. // Try to modify the object's DACL.
  967. dwRes = SetNamedSecurityInfo(
  968. lpszOwnFile, // name of the object
  969. SE_FILE_OBJECT, // type of object
  970. DACL_SECURITY_INFORMATION, // change only the object's DACL
  971. NULL, NULL, // do not change owner or group
  972. pACL, // DACL specified
  973. NULL); // do not change SACL
  974. if (ERROR_SUCCESS == dwRes)
  975. {
  976. Dbg("Successfully changed DACL\n");
  977. bRetval = TRUE;
  978. // No more processing needed.
  979. goto Cleanup;
  980. }
  981. if (dwRes != ERROR_ACCESS_DENIED)
  982. {
  983. Dbg("First SetNamedSecurityInfo call failed: %u\n", dwRes);
  984. goto Cleanup;
  985. }
  986. // If the preceding call failed because access was denied,
  987. // enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for
  988. // the Administrators group, take ownership of the object, and
  989. // disable the privilege. Then try again to set the object's DACL.
  990. // Open a handle to the access token for the calling process.
  991. if (!OpenProcessToken(GetCurrentProcess(),
  992. TOKEN_ADJUST_PRIVILEGES,
  993. &hToken))
  994. {
  995. Dbg("OpenProcessToken failed: %u\n", GetLastError());
  996. goto Cleanup;
  997. }
  998. // Enable the SE_TAKE_OWNERSHIP_NAME privilege.
  999. if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
  1000. {
  1001. Dbg("You must be logged on as Administrator.\n");
  1002. goto Cleanup;
  1003. }
  1004. // Set the owner in the object's security descriptor.
  1005. dwRes = SetNamedSecurityInfo(
  1006. lpszOwnFile, // name of the object
  1007. SE_FILE_OBJECT, // type of object
  1008. OWNER_SECURITY_INFORMATION, // change only the object's owner
  1009. pSIDAdmin, // SID of Administrator group
  1010. NULL,
  1011. NULL,
  1012. NULL);
  1013. if (dwRes != ERROR_SUCCESS)
  1014. {
  1015. Dbg("Could not set owner. Error: %u\n", dwRes);
  1016. goto Cleanup;
  1017. }
  1018. // Disable the SE_TAKE_OWNERSHIP_NAME privilege.
  1019. if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
  1020. {
  1021. Dbg("Failed SetPrivilege call unexpectedly.\n");
  1022. goto Cleanup;
  1023. }
  1024. // Try again to modify the object's DACL,
  1025. // now that we are the owner.
  1026. dwRes = SetNamedSecurityInfo(
  1027. lpszOwnFile, // name of the object
  1028. SE_FILE_OBJECT, // type of object
  1029. DACL_SECURITY_INFORMATION, // change only the object's DACL
  1030. NULL, NULL, // do not change owner or group
  1031. pACL, // DACL specified
  1032. NULL); // do not change SACL
  1033. if (dwRes == ERROR_SUCCESS)
  1034. {
  1035. Dbg("Successfully changed DACL\n");
  1036. bRetval = TRUE;
  1037. }
  1038. else
  1039. {
  1040. Dbg("Second SetNamedSecurityInfo call failed: %u\n", dwRes);
  1041. }
  1042. Cleanup:
  1043. if (pSIDAdmin)
  1044. FreeSid(pSIDAdmin);
  1045. if (pSIDEveryone)
  1046. FreeSid(pSIDEveryone);
  1047. if (pACL)
  1048. LocalFree(pACL);
  1049. if (hToken)
  1050. CloseHandle(hToken);
  1051. return bRetval;
  1052. }
  1053. BOOL CTWProcHelper::FindOwnerOfFile(LPCTSTR lpszOwnFile, LPTSTR lpszOwnerAccount)
  1054. {
  1055. DWORD dwRtnCode = 0;
  1056. PSID pSidOwner = NULL;
  1057. BOOL bRtnBool = TRUE;
  1058. LPTSTR AcctName = NULL;
  1059. LPTSTR DomainName = NULL;
  1060. DWORD dwAcctName = 1, dwDomainName = 1;
  1061. SID_NAME_USE eUse = SidTypeUnknown;
  1062. HANDLE hFile;
  1063. PSECURITY_DESCRIPTOR pSD = NULL;
  1064. // Get the handle of the file object.
  1065. hFile = CreateFile(
  1066. lpszOwnFile,
  1067. GENERIC_READ,
  1068. FILE_SHARE_READ,
  1069. NULL,
  1070. OPEN_EXISTING,
  1071. FILE_ATTRIBUTE_NORMAL,
  1072. NULL);
  1073. // Check GetLastError for CreateFile error code.
  1074. if (hFile == INVALID_HANDLE_VALUE)
  1075. {
  1076. DWORD dwErrorCode = 0;
  1077. dwErrorCode = GetLastError();
  1078. Dbg(TEXT("CreateFile error = %d\n"), dwErrorCode);
  1079. return FALSE;
  1080. }
  1081. // Get the owner SID of the file.
  1082. dwRtnCode = GetSecurityInfo(
  1083. hFile,
  1084. SE_FILE_OBJECT,
  1085. OWNER_SECURITY_INFORMATION,
  1086. &pSidOwner,
  1087. NULL,
  1088. NULL,
  1089. NULL,
  1090. &pSD);
  1091. // Check GetLastError for GetSecurityInfo error condition.
  1092. if (dwRtnCode != ERROR_SUCCESS)
  1093. {
  1094. DWORD dwErrorCode = 0;
  1095. dwErrorCode = GetLastError();
  1096. Dbg(TEXT("GetSecurityInfo error = %d\n"), dwErrorCode);
  1097. return FALSE;
  1098. }
  1099. // First call to LookupAccountSid to get the buffer sizes.
  1100. bRtnBool = LookupAccountSid(
  1101. NULL, // local computer
  1102. pSidOwner,
  1103. AcctName,
  1104. (LPDWORD)&dwAcctName,
  1105. DomainName,
  1106. (LPDWORD)&dwDomainName,
  1107. &eUse);
  1108. // Reallocate memory for the buffers.
  1109. AcctName = (LPTSTR)GlobalAlloc(
  1110. GMEM_FIXED,
  1111. dwAcctName);
  1112. // Check GetLastError for GlobalAlloc error condition.
  1113. if (AcctName == NULL)
  1114. {
  1115. DWORD dwErrorCode = 0;
  1116. dwErrorCode = GetLastError();
  1117. Dbg(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
  1118. return FALSE;
  1119. }
  1120. DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName);
  1121. // Check GetLastError for GlobalAlloc error condition.
  1122. if (DomainName == NULL)
  1123. {
  1124. DWORD dwErrorCode = 0;
  1125. dwErrorCode = GetLastError();
  1126. Dbg(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
  1127. return FALSE;
  1128. }
  1129. // Second call to LookupAccountSid to get the account name.
  1130. bRtnBool = LookupAccountSid(
  1131. NULL, // name of local or remote computer
  1132. pSidOwner, // security identifier
  1133. AcctName, // account name buffer
  1134. (LPDWORD)&dwAcctName, // size of account name buffer
  1135. DomainName, // domain name
  1136. (LPDWORD)&dwDomainName, // size of domain name buffer
  1137. &eUse); // SID type
  1138. // Check GetLastError for LookupAccountSid error condition.
  1139. if (bRtnBool == FALSE)
  1140. {
  1141. DWORD dwErrorCode = 0;
  1142. dwErrorCode = GetLastError();
  1143. if (dwErrorCode == ERROR_NONE_MAPPED)
  1144. Dbg(TEXT("Account owner not found for specified SID.\n"));
  1145. else
  1146. Dbg(TEXT("Error in LookupAccountSid.\n"));
  1147. return FALSE;
  1148. } else if (bRtnBool == TRUE)
  1149. // Print the account name.
  1150. sprintf(lpszOwnerAccount, "Account owner = %s", AcctName);
  1151. return TRUE;
  1152. }
  1153. BOOL CTWProcHelper::CustomAccessCheck(LPTSTR lpszFileName)
  1154. {
  1155. BOOL bRet = FALSE;
  1156. DWORD dwAccessDesired = GENERIC_READ | GENERIC_WRITE;
  1157. GENERIC_MAPPING GenericMapping;
  1158. PSECURITY_DESCRIPTOR pSD = NULL;
  1159. if(!GetSecurityDescriptorOfFile(lpszFileName, &pSD))
  1160. {
  1161. PrintError("GetSecurityDescriptorOfFile failed.");
  1162. if(pSD)
  1163. TWHeapFree(pSD);
  1164. return FALSE;
  1165. }
  1166. //mapping of generic access types to specific and standard access types
  1167. //将通用访问类型映射到特定的标准访问类型
  1168. //将通用权限控制标志和特定类型对象权限控制标志挂钩,即通用读写的映射,对于文件来说就是FILE_***
  1169. GenericMapping.GenericRead = FILE_GENERIC_READ;
  1170. GenericMapping.GenericWrite = FILE_GENERIC_WRITE;
  1171. GenericMapping.GenericExecute = FILE_GENERIC_EXECUTE;
  1172. GenericMapping.GenericAll = FILE_ALL_ACCESS;
  1173. DWORD dwAccessAllow;
  1174. bRet = ImpersonateAndCheckAccess(pSD, dwAccessDesired, &GenericMapping, &dwAccessAllow);
  1175. if(pSD) TWHeapFree(pSD);
  1176. return bRet;
  1177. }
  1178. BOOL CTWProcHelper::GetSecurityDescriptorOfFile(LPCSTR lpszFileName, PSECURITY_DESCRIPTOR *ppSD)
  1179. {
  1180. BOOL bRes = FALSE;
  1181. DWORD dwNeeded = 0;
  1182. //请求的安全信息类型
  1183. SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION |
  1184. GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
  1185. bRes = GetFileSecurity(lpszFileName, si, *ppSD, 0, &dwNeeded);
  1186. if(!bRes)
  1187. {
  1188. if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  1189. {
  1190. *ppSD = (PSECURITY_DESCRIPTOR *)TWHeapAlloc(dwNeeded);
  1191. if(!GetFileSecurity(lpszFileName, si, *ppSD, dwNeeded, &dwNeeded))
  1192. {
  1193. PrintError("GetFileSecurity failed.");
  1194. return FALSE;
  1195. }
  1196. return TRUE;
  1197. }
  1198. }
  1199. return FALSE;
  1200. }
  1201. BOOL CTWProcHelper::ImpersonateAndCheckAccess(
  1202. PSECURITY_DESCRIPTOR pSD, // security descriptor to check
  1203. DWORD dwAccessDesired, // access rights to check
  1204. PGENERIC_MAPPING pGeneric, // generic mapping for object
  1205. PDWORD pdwAccessAllowed // returns allowed access rights
  1206. )
  1207. {
  1208. HANDLE hToken;
  1209. HANDLE hImpersonatedToken = NULL;
  1210. DWORD dwResult = -1;
  1211. PRIVILEGE_SET PrivilegeSet;
  1212. DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET );
  1213. BOOL fAccessGranted=FALSE;
  1214. *pdwAccessAllowed = 0;
  1215. // Get an impersonation token with the client's security context.
  1216. if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))
  1217. {
  1218. PrintError("Warning: OpenProcessToken for GetCurrentThread failed.");
  1219. if (GetLastError() != ERROR_NO_TOKEN)
  1220. {
  1221. goto Cleanup;
  1222. }
  1223. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
  1224. {
  1225. dwResult = GetLastError();
  1226. PrintError("OpenProcessToken for GetCurrentProcess failed.");
  1227. goto Cleanup;
  1228. }
  1229. }
  1230. if(!DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken))
  1231. {
  1232. dwResult = GetLastError();
  1233. PrintError("DuplicateToken failed.");
  1234. goto Cleanup;
  1235. }
  1236. // Use the GENERIC_MAPPING structure to convert any
  1237. // generic access rights to object-specific access rights.
  1238. // 函数返回后 dwAccessDesired 中无通用占用位和未定义位集
  1239. MapGenericMask(&dwAccessDesired, pGeneric);
  1240. // Check the client's access rights.
  1241. if( !AccessCheck(
  1242. pSD, // security descriptor to check
  1243. hImpersonatedToken, // impersonation token
  1244. dwAccessDesired, // requested access rights
  1245. pGeneric, // pointer to GENERIC_MAPPING
  1246. &PrivilegeSet, // receives privileges used in check
  1247. &dwPrivSetSize, // size of PrivilegeSet buffer
  1248. pdwAccessAllowed, // receives mask of allowed access rights
  1249. &fAccessGranted )) // receives results of access check
  1250. {
  1251. dwResult = GetLastError();
  1252. if(dwResult == ERROR_INVALID_SECURITY_DESCR )
  1253. {
  1254. PrintError("The security descriptor does not contain owner and group SIDs.");
  1255. }
  1256. else
  1257. {
  1258. PrintError("AccessCheck failed.");
  1259. }
  1260. goto Cleanup;
  1261. }
  1262. Cleanup:
  1263. RevertToSelf();
  1264. if (hToken != INVALID_HANDLE_VALUE)
  1265. CloseHandle(hToken);
  1266. if (hImpersonatedToken != INVALID_HANDLE_VALUE)
  1267. CloseHandle(hImpersonatedToken);
  1268. return fAccessGranted;
  1269. }
  1270. BOOL CTWProcHelper::SearchTokenGroupsForSID(VOID)
  1271. {
  1272. DWORD i, dwSize = 0, dwResult = 0;
  1273. HANDLE hToken;
  1274. PTOKEN_GROUPS pGroupInfo;
  1275. SID_NAME_USE SidType;
  1276. char lpName[MAX_NAME];
  1277. char lpDomain[MAX_NAME];
  1278. PSID pSID = NULL;
  1279. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
  1280. // Open a handle to the access token for the calling process.
  1281. if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken ))
  1282. {
  1283. Dbg( "OpenProcessToken Error %u\n", GetLastError() );
  1284. return FALSE;
  1285. }
  1286. // Call GetTokenInformation to get the buffer size.
  1287. if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
  1288. {
  1289. dwResult = GetLastError();
  1290. if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
  1291. Dbg( "GetTokenInformation Error %u\n", dwResult );
  1292. return FALSE;
  1293. }
  1294. }
  1295. // Allocate the buffer.
  1296. pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );
  1297. // Call GetTokenInformation again to get the group information.
  1298. if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo,
  1299. dwSize, &dwSize ) )
  1300. {
  1301. Dbg( "GetTokenInformation Error %u\n", GetLastError() );
  1302. return FALSE;
  1303. }
  1304. // Create a SID for the BUILTIN\Administrators group.
  1305. if(! AllocateAndInitializeSid( &SIDAuth, 2,
  1306. SECURITY_BUILTIN_DOMAIN_RID,
  1307. DOMAIN_ALIAS_RID_ADMINS,
  1308. 0, 0, 0, 0, 0, 0,
  1309. &pSID) )
  1310. {
  1311. Dbg( "AllocateAndInitializeSid Error %u\n", GetLastError() );
  1312. return FALSE;
  1313. }
  1314. // Loop through the group SIDs looking for the administrator SID.
  1315. for(i=0; i<pGroupInfo->GroupCount; i++)
  1316. {
  1317. if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) )
  1318. {
  1319. // Lookup the account name and print it.
  1320. dwSize = MAX_NAME;
  1321. if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid,
  1322. lpName, &dwSize, lpDomain,
  1323. &dwSize, &SidType ) )
  1324. {
  1325. dwResult = GetLastError();
  1326. if( dwResult == ERROR_NONE_MAPPED )
  1327. strcpy_s (lpName, dwSize, "NONE_MAPPED" );
  1328. else
  1329. {
  1330. Dbg("LookupAccountSid Error %u\n", GetLastError());
  1331. return FALSE;
  1332. }
  1333. }
  1334. Dbg( "Current user is a member of the %s\\%s group\n",
  1335. lpDomain, lpName );
  1336. // Find out whether the SID is enabled in the token.
  1337. if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)
  1338. Dbg("The group SID is enabled.\n");
  1339. else if (pGroupInfo->Groups[i].Attributes &
  1340. SE_GROUP_USE_FOR_DENY_ONLY)
  1341. Dbg("The group SID is a deny-only SID.\n");
  1342. else
  1343. Dbg("The group SID is not enabled.\n");
  1344. }
  1345. // Loop through the groups to find the logon SID.
  1346. if ((pGroupInfo->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
  1347. {
  1348. DWORD dwLength = GetLengthSid(pGroupInfo->Groups[i].Sid);
  1349. //*ppsid = (PSID) HeapAlloc(GetProcessHeap(),
  1350. // HEAP_ZERO_MEMORY, dwLength);
  1351. //if (*ppsid == NULL)
  1352. // goto Cleanup;
  1353. //if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
  1354. //{
  1355. // HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
  1356. // goto Cleanup;
  1357. //}
  1358. dwSize = MAX_NAME;
  1359. if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid,
  1360. lpName, &dwSize, lpDomain,
  1361. &dwSize, &SidType ) )
  1362. {
  1363. dwResult = GetLastError();
  1364. if( dwResult == ERROR_NONE_MAPPED )
  1365. strcpy_s (lpName, dwSize, "NONE_MAPPED" );
  1366. else
  1367. {
  1368. Dbg("LookupAccountSid Error %u\n", GetLastError());
  1369. return FALSE;
  1370. }
  1371. }
  1372. Dbg( "Current logon user is a member of the %s\\%s group\n",
  1373. lpDomain, lpName );
  1374. }
  1375. }
  1376. if (pSID)
  1377. FreeSid(pSID);
  1378. if ( pGroupInfo )
  1379. GlobalFree( pGroupInfo );
  1380. return TRUE;
  1381. }
  1382. BOOL CTWProcHelper::AddUserAccount()
  1383. {
  1384. #ifndef UNICODE
  1385. #define UNICODE
  1386. #define NOT_UNICODE_BEFORE
  1387. #endif
  1388. BOOL bRet = FALSE;
  1389. USER_INFO_1 ui;
  1390. DWORD dwLevel = 1;
  1391. DWORD dwError = 0;
  1392. NET_API_STATUS nStatus;
  1393. //
  1394. // Set up the USER_INFO_1 structure.
  1395. // USER_PRIV_USER: name identifies a user,
  1396. // rather than an administrator or a guest.
  1397. // UF_SCRIPT: required
  1398. //
  1399. ui.usri1_name = L"cmbzephyr";
  1400. ui.usri1_password = L"Cmb@1111";
  1401. ui.usri1_priv = USER_PRIV_USER;
  1402. ui.usri1_home_dir = NULL;
  1403. ui.usri1_comment = L"cmbzephyr";
  1404. ui.usri1_flags = UF_SCRIPT|UF_DONT_EXPIRE_PASSWD|UF_PASSWD_CANT_CHANGE;
  1405. ui.usri1_script_path = NULL;
  1406. //
  1407. // Call the NetUserAdd function, specifying level 1.
  1408. //
  1409. nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);
  1410. //
  1411. // If the call succeeds, inform the user.
  1412. //
  1413. #ifdef NOT_UNICODE_BEFORE
  1414. #undef UNICODE
  1415. #endif
  1416. if (nStatus == NERR_Success || NERR_UserExists == nStatus)
  1417. {
  1418. if(NERR_UserExists == nStatus)
  1419. {
  1420. Dbg("User has been added already");
  1421. }
  1422. else
  1423. {
  1424. Dbg("User has been successfully added");
  1425. }
  1426. bRet = TRUE;
  1427. }
  1428. //
  1429. // Otherwise, print the system error.
  1430. //
  1431. else
  1432. Dbg("A system error has occurred: %d", nStatus);
  1433. return bRet;
  1434. }
  1435. BOOL CTWProcHelper::AddMemberToGroup()
  1436. {
  1437. #ifndef UNICODE
  1438. #define UNICODE
  1439. #define NOT_UNICODE_BEFORE
  1440. #endif
  1441. BOOL bRet = FALSE;
  1442. NET_API_STATUS nStatus;
  1443. DWORD dwLevel = 1;
  1444. DWORD dwError = 0;
  1445. LOCALGROUP_MEMBERS_INFO_3 memberInfo = {0};
  1446. memberInfo.lgrmi3_domainandname = L"cmbzephyr";
  1447. nStatus = NetLocalGroupAddMembers(NULL, L"Users", 3, (LPBYTE)&memberInfo, 1);
  1448. //
  1449. // If the call succeeds, inform the user.
  1450. //
  1451. #ifdef NOT_UNICODE_BEFORE
  1452. #undef UNICODE
  1453. #endif
  1454. if (nStatus == NERR_Success)
  1455. {
  1456. Dbg("User is added to group successfully");
  1457. bRet = TRUE;
  1458. }
  1459. //
  1460. // Otherwise, print the system error.
  1461. //
  1462. else
  1463. {
  1464. if(ERROR_MEMBER_IN_ALIAS == nStatus)
  1465. {
  1466. Dbg("The specified account name is already a member of the group.");
  1467. }
  1468. else
  1469. {
  1470. Dbg("A system error has occurred: %d", nStatus);
  1471. }
  1472. }
  1473. return bRet;
  1474. }
  1475. //winlogon.exe
  1476. BOOL CTWProcHelper::GetTokenByName(HANDLE &hToken, LPSTR lpName)
  1477. {
  1478. if(!lpName)
  1479. {
  1480. return FALSE;
  1481. }
  1482. HANDLE hProcessSnap = NULL;
  1483. BOOL bRet = FALSE;
  1484. PROCESSENTRY32 pe32 = {0};
  1485. hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  1486. if (hProcessSnap == INVALID_HANDLE_VALUE)
  1487. return (FALSE);
  1488. pe32.dwSize = sizeof(PROCESSENTRY32);
  1489. if (Process32First(hProcessSnap, &pe32))
  1490. {
  1491. do
  1492. {
  1493. if(!strcmp(_strupr(pe32.szExeFile), _strupr(lpName)))
  1494. {
  1495. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
  1496. FALSE, pe32.th32ProcessID);
  1497. bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
  1498. CloseHandle (hProcessSnap);
  1499. return (bRet);
  1500. }
  1501. }
  1502. while (Process32Next(hProcessSnap, &pe32));
  1503. }
  1504. CloseHandle (hProcessSnap);
  1505. return (bRet);
  1506. }
  1507. BOOL CTWProcHelper::CreateSystemProcess(LPTSTR szProcessName)
  1508. {
  1509. HANDLE hProcess;
  1510. HANDLE hToken, hNewToken;
  1511. PACL pOldDAcl = NULL;
  1512. PACL pNewDAcl = NULL;
  1513. BOOL bDAcl;
  1514. BOOL bDefDAcl;
  1515. DWORD dwRet;
  1516. PACL pSacl = NULL;
  1517. PSID pSidOwner = NULL;
  1518. PSID pSidPrimary = NULL;
  1519. DWORD dwAclSize = 0;
  1520. DWORD dwSaclSize = 0;
  1521. DWORD dwSidOwnLen = 0;
  1522. DWORD dwSidPrimLen = 0;
  1523. DWORD dwSDLen;
  1524. EXPLICIT_ACCESS ea;
  1525. PSECURITY_DESCRIPTOR pOrigSd = NULL;
  1526. PSECURITY_DESCRIPTOR pNewSd = NULL;
  1527. STARTUPINFO si;
  1528. PROCESS_INFORMATION pi;
  1529. BOOL bError;
  1530. // Get the current process - IEExplore.exe
  1531. hProcess = GetCurrentProcess();
  1532. // Open IE process token and specify the access types to IE token
  1533. if ( !OpenProcessToken( hProcess, READ_CONTROL | WRITE_DAC, &hToken ) )
  1534. {
  1535. Dbg( "OpenProcessToken() = %d\n", GetLastError() );
  1536. bError = TRUE;
  1537. goto Cleanup;
  1538. }
  1539. // Create a new access control information that includes all access permissions.
  1540. ZeroMemory( &ea, sizeof( EXPLICIT_ACCESS ) );
  1541. BuildExplicitAccessWithName( &ea,
  1542. "CURRENT_USER", // Note: if you specified other trustee name, it would fail at subsequent code
  1543. TOKEN_ALL_ACCESS,
  1544. GRANT_ACCESS,
  1545. 0 );
  1546. if ( !GetKernelObjectSecurity( hToken,
  1547. DACL_SECURITY_INFORMATION,
  1548. pOrigSd,
  1549. 0,
  1550. &dwSDLen ) )
  1551. {
  1552. // We first get the length of original security descriptor to IE token
  1553. if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  1554. {
  1555. pOrigSd = ( PSECURITY_DESCRIPTOR )
  1556. HeapAlloc( GetProcessHeap(),
  1557. HEAP_ZERO_MEMORY,
  1558. dwSDLen );
  1559. if ( pOrigSd == NULL )
  1560. {
  1561. Dbg( "Allocate pSd memory to failed!\n" );
  1562. bError = TRUE;
  1563. goto Cleanup;
  1564. }
  1565. if ( !GetKernelObjectSecurity( hToken,
  1566. DACL_SECURITY_INFORMATION,
  1567. pOrigSd,
  1568. dwSDLen,
  1569. &dwSDLen ) )
  1570. {
  1571. Dbg( "GetKernelObjectSecurity() = %d\n",
  1572. GetLastError() );
  1573. bError = TRUE;
  1574. goto Cleanup;
  1575. }
  1576. }
  1577. else
  1578. {
  1579. Dbg( "GetKernelObjectSecurity() = %d\n", GetLastError() );
  1580. bError = TRUE;
  1581. goto Cleanup;
  1582. }
  1583. }
  1584. // Getting ACL of original security descriptor
  1585. if ( !GetSecurityDescriptorDacl( pOrigSd, &bDAcl, &pOldDAcl, &bDefDAcl ) )
  1586. {
  1587. Dbg( "GetSecurityDescriptorDacl() = %d\n", GetLastError() );
  1588. bError = TRUE;
  1589. goto Cleanup;
  1590. }
  1591. // Using the created access control information - EXPLICIT_ACCESS,
  1592. // and the original ACL to generate a new ACL
  1593. dwRet = SetEntriesInAcl( 1, &ea, pOldDAcl, &pNewDAcl );
  1594. if ( dwRet != ERROR_SUCCESS )
  1595. {
  1596. Dbg( "SetEntriesInAcl() = %d\n", GetLastError() );
  1597. pNewDAcl = NULL;
  1598. bError = TRUE;
  1599. goto Cleanup;
  1600. }
  1601. // Create a new security descriptor that refers
  1602. // to original security descriptor.
  1603. if ( !MakeAbsoluteSD( pOrigSd,
  1604. pNewSd,
  1605. &dwSDLen,
  1606. pOldDAcl,
  1607. &dwAclSize,
  1608. pSacl,
  1609. &dwSaclSize,
  1610. pSidOwner,
  1611. &dwSidOwnLen,
  1612. pSidPrimary,
  1613. &dwSidPrimLen ) )
  1614. {
  1615. if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  1616. {
  1617. pOldDAcl = ( PACL ) HeapAlloc( GetProcessHeap(),
  1618. HEAP_ZERO_MEMORY,
  1619. dwAclSize );
  1620. pSacl = ( PACL ) HeapAlloc( GetProcessHeap(),
  1621. HEAP_ZERO_MEMORY,
  1622. dwSaclSize );
  1623. pSidOwner = ( PSID ) HeapAlloc( GetProcessHeap(),
  1624. HEAP_ZERO_MEMORY,
  1625. dwSidOwnLen );
  1626. pSidPrimary = ( PSID ) HeapAlloc( GetProcessHeap(),
  1627. HEAP_ZERO_MEMORY,
  1628. dwSidPrimLen );
  1629. pNewSd = ( PSECURITY_DESCRIPTOR )
  1630. HeapAlloc( GetProcessHeap(),
  1631. HEAP_ZERO_MEMORY,
  1632. dwSDLen );
  1633. if ( pOldDAcl == NULL ||
  1634. pSacl == NULL ||
  1635. pSidOwner == NULL ||
  1636. pSidPrimary == NULL ||
  1637. pNewSd == NULL )
  1638. {
  1639. Dbg( "Allocate SID or ACL to failed!\n" );
  1640. bError = TRUE;
  1641. goto Cleanup;
  1642. }
  1643. if ( !MakeAbsoluteSD( pOrigSd,
  1644. pNewSd,
  1645. &dwSDLen,
  1646. pOldDAcl,
  1647. &dwAclSize,
  1648. pSacl,
  1649. &dwSaclSize,
  1650. pSidOwner,
  1651. &dwSidOwnLen,
  1652. pSidPrimary,
  1653. &dwSidPrimLen ) )
  1654. {
  1655. Dbg( "MakeAbsoluteSD() = %d\n", GetLastError() );
  1656. bError = TRUE;
  1657. goto Cleanup;
  1658. }
  1659. }
  1660. else
  1661. {
  1662. Dbg( "MakeAbsoluteSD() = %d\n", GetLastError() );
  1663. bError = TRUE;
  1664. goto Cleanup;
  1665. }
  1666. }
  1667. // Well, we have owned a new security descriptor & a new ACL,
  1668. // all we have to do is fetch the new ACL into the new security descriptor!
  1669. if ( !SetSecurityDescriptorDacl( pNewSd, bDAcl, pNewDAcl, bDefDAcl ) )
  1670. {
  1671. Dbg( "SetSecurityDescriptorDacl() = %d\n", GetLastError() );
  1672. bError = TRUE;
  1673. goto Cleanup;
  1674. }
  1675. //
  1676. // Injects the new security descriptor into IE token
  1677. //
  1678. if ( !SetKernelObjectSecurity( hToken, DACL_SECURITY_INFORMATION, pNewSd ) )
  1679. {
  1680. Dbg( "SetKernelObjectSecurity() = %d\n", GetLastError() );
  1681. bError = TRUE;
  1682. goto Cleanup;
  1683. }
  1684. //
  1685. // When we open IE process again, the hToken has all access permissions.
  1686. //
  1687. if ( !OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken ) )
  1688. {
  1689. Dbg( "OpenProcessToken() = %d\n", GetLastError() );
  1690. bError = TRUE;
  1691. goto Cleanup;
  1692. }
  1693. //
  1694. // Then, make a duplicate from IE token
  1695. //
  1696. if ( !DuplicateTokenEx( hToken,
  1697. TOKEN_ALL_ACCESS,
  1698. NULL,
  1699. SecurityImpersonation,
  1700. TokenPrimary,
  1701. &hNewToken ) )
  1702. {
  1703. Dbg( "DuplicateTokenEx() = %d\n", GetLastError() );
  1704. bError = TRUE;
  1705. goto Cleanup;
  1706. }
  1707. ZeroMemory( &si, sizeof( STARTUPINFO ) );
  1708. si.cb = sizeof( STARTUPINFO );
  1709. // Now, we impersonate the security context of a
  1710. // logged-on user using the token.
  1711. // Note: if you didn't, the below CreateProcessAsUser
  1712. // will report 1314 no permission error.
  1713. ImpersonateLoggedOnUser( hNewToken );
  1714. // Finally, we use the token to create new process.
  1715. if ( !CreateProcessAsUser( hNewToken,
  1716. NULL,
  1717. szProcessName,
  1718. NULL,
  1719. NULL,
  1720. FALSE,
  1721. NULL, //NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
  1722. NULL,
  1723. NULL,
  1724. &si,
  1725. &pi) )
  1726. {
  1727. Dbg( "CreateProcessAsUser() = %d\n", GetLastError() );
  1728. bError = TRUE;
  1729. goto Cleanup;
  1730. }
  1731. bError = FALSE;
  1732. Cleanup:
  1733. if ( pOrigSd )
  1734. {
  1735. HeapFree( GetProcessHeap(), 0, pOrigSd );
  1736. }
  1737. if ( pNewSd )
  1738. {
  1739. HeapFree( GetProcessHeap(), 0, pNewSd );
  1740. }
  1741. if ( pSidPrimary )
  1742. {
  1743. HeapFree( GetProcessHeap(), 0, pSidPrimary );
  1744. }
  1745. if ( pSidOwner )
  1746. {
  1747. HeapFree( GetProcessHeap(), 0, pSidOwner );
  1748. }
  1749. if ( pSacl )
  1750. {
  1751. HeapFree( GetProcessHeap(), 0, pSacl );
  1752. }
  1753. if ( pOldDAcl )
  1754. {
  1755. HeapFree( GetProcessHeap(), 0, pOldDAcl );
  1756. }
  1757. if (!bError)
  1758. {
  1759. CloseHandle( pi.hProcess );
  1760. CloseHandle( pi.hThread );
  1761. CloseHandle( hToken );
  1762. CloseHandle( hNewToken );
  1763. CloseHandle( hProcess );
  1764. }
  1765. if ( bError )
  1766. {
  1767. return FALSE;
  1768. }
  1769. return TRUE;
  1770. }
  1771. BOOL CTWProcHelper::GetPrivilegeLUIDWithSID(PSID pSID, PLUID *pLUID, PDWORD pDwCount)
  1772. {
  1773. LOG_FUNCTION();
  1774. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  1775. NTSTATUS ntsResult;
  1776. LSA_HANDLE lsahPolicyHandle;
  1777. // Object attributes are reserved, so initialize to zeros.
  1778. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  1779. // Get a handle to the Policy object.
  1780. ntsResult = LsaOpenPolicy(
  1781. NULL, //Name of the target system.
  1782. &ObjectAttributes, //Object attributes.
  1783. POLICY_ALL_ACCESS, //Desired access permissions.
  1784. &lsahPolicyHandle //Receives the policy handle.
  1785. );
  1786. if (ntsResult != STATUS_SUCCESS)
  1787. {
  1788. Dbg("OpenPolicy failed returned %lu", LsaNtStatusToWinError(ntsResult));
  1789. return FALSE;
  1790. }
  1791. PLSA_UNICODE_STRING UserRights = NULL;
  1792. ULONG uRightCount;
  1793. ntsResult = LsaEnumerateAccountRights(lsahPolicyHandle, pSID, &UserRights, &uRightCount);
  1794. if (ntsResult != STATUS_SUCCESS)
  1795. {
  1796. Dbg("LsaEnumerateAccountRights failed returned %lu", LsaNtStatusToWinError(ntsResult));
  1797. LsaClose(lsahPolicyHandle);
  1798. return FALSE;
  1799. }
  1800. Dbg("LsaEnumerateAccountRights returned Right count: %lu", uRightCount);
  1801. (*pDwCount) = 0;
  1802. //pLUID = (PLUID)HeapAlloc(GetProcessHeap(), 0, uRightCount*sizeof(LUID));
  1803. (*pLUID) = (PLUID)LocalAlloc(LPTR, uRightCount*sizeof(LUID));
  1804. if((*pLUID) == NULL)
  1805. {
  1806. Dbg("HeapAlloc for PLUID failed returned %u", GetLastError());
  1807. LsaClose(lsahPolicyHandle);
  1808. return FALSE;
  1809. }
  1810. for(ULONG uIdx=0; UserRights != NULL && uIdx<uRightCount; uIdx++)
  1811. {
  1812. int nLenOfMultiChars = WideCharToMultiByte(CP_ACP, 0, UserRights[uIdx].Buffer, UserRights[uIdx].Length,
  1813. NULL, 0, NULL, NULL);
  1814. PTSTR pMultiCharStr = (PTSTR)HeapAlloc(GetProcessHeap(), 0, nLenOfMultiChars*sizeof(char));
  1815. if(pMultiCharStr != NULL)
  1816. {
  1817. WideCharToMultiByte(CP_ACP, 0, UserRights[uIdx].Buffer, UserRights[uIdx].Length,
  1818. pMultiCharStr, nLenOfMultiChars, NULL, NULL);
  1819. LUID luid;
  1820. if(!LookupPrivilegeValue(NULL, pMultiCharStr, &luid))
  1821. {
  1822. Dbg("LookupPrivilegeValue about %s failed, GLE=%u.", pMultiCharStr, GetLastError());
  1823. HeapFree(GetProcessHeap(), 0, pMultiCharStr);
  1824. continue;
  1825. }
  1826. //Dbg("LookupPrivilegeValue: %s", pMultiCharStr);
  1827. (*pLUID)[(*pDwCount)++] = luid;
  1828. HeapFree(GetProcessHeap(), 0, pMultiCharStr);
  1829. }
  1830. }
  1831. if((ntsResult = LsaFreeMemory(UserRights)) != STATUS_SUCCESS)
  1832. {
  1833. Dbg("LsaFreeMemory failed returned %lu", LsaNtStatusToWinError(ntsResult));
  1834. }
  1835. LsaClose(lsahPolicyHandle);
  1836. return TRUE;
  1837. }
  1838. BOOL CTWProcHelper::GetPIDByName(LPCTSTR lpszPName, DWORD& dwProcessID)
  1839. {
  1840. if(lpszPName == NULL)
  1841. return FALSE;
  1842. HANDLE hProcessSnap = NULL;
  1843. BOOL bRet = FALSE;
  1844. PROCESSENTRY32 pe32 = {0};
  1845. hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  1846. if (hProcessSnap == INVALID_HANDLE_VALUE)
  1847. {
  1848. PrintError(("CreateToolhelp32Snapshot (of processes)") );
  1849. return (FALSE);
  1850. }
  1851. pe32.dwSize = sizeof(PROCESSENTRY32);
  1852. // Retrieve information about the first process,
  1853. // and exit if unsuccessful
  1854. if( !Process32First( hProcessSnap, &pe32 ) )
  1855. {
  1856. PrintError(("Process32First") ); // show cause of failure
  1857. CloseHandle( hProcessSnap ); // clean the snapshot object
  1858. return(FALSE);
  1859. }
  1860. do
  1861. {
  1862. if(!strcmp((pe32.szExeFile), lpszPName))
  1863. {
  1864. CloseHandle(hProcessSnap);
  1865. dwProcessID = pe32.th32ProcessID;
  1866. return TRUE;
  1867. }
  1868. }
  1869. while (Process32Next(hProcessSnap, &pe32));
  1870. CloseHandle (hProcessSnap);
  1871. //PrintInfo("Not found process");
  1872. return FALSE;
  1873. }
  1874. BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);
  1875. BOOL AddAceToDesktop(HDESK hdesk, PSID psid);
  1876. BOOL GetLogonSID (HANDLE hToken, PSID *ppsid);
  1877. VOID FreeLogonSID (PSID *ppsid);
  1878. BOOL StartInteractiveClientProcess (
  1879. LPTSTR lpszUsername, // client to log on
  1880. LPTSTR lpszDomain, // domain of client's account
  1881. LPTSTR lpszPassword, // client's password
  1882. LPTSTR lpCommandLine, // command line to execute
  1883. LPSTARTUPINFO psi,
  1884. DWORD fdwCreate,
  1885. PDWORD pDwProcessId
  1886. )
  1887. {
  1888. HANDLE hToken;
  1889. HDESK hdesk = NULL;
  1890. HWINSTA hwinsta = NULL, hwinstaSave = NULL;
  1891. PSID pSid = NULL;
  1892. STARTUPINFO si;
  1893. PROCESS_INFORMATION pi;
  1894. BOOL bResult = FALSE;
  1895. // Log the client on to the local computer.
  1896. if (!LogonUser(
  1897. lpszUsername,
  1898. lpszDomain,
  1899. lpszPassword,
  1900. LOGON32_LOGON_INTERACTIVE,
  1901. LOGON32_PROVIDER_DEFAULT,
  1902. &hToken) )
  1903. {
  1904. Dbg("LogonUser failed GLE=%u.", GetLastError());
  1905. goto Cleanup;
  1906. }
  1907. // Save a handle to the caller's current window station.
  1908. if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
  1909. {
  1910. Dbg("GetProcessWindowStation failed GLE=%u.", GetLastError());
  1911. goto Cleanup;
  1912. }
  1913. // Get a handle to the interactive window station.
  1914. hwinsta = OpenWindowStation(
  1915. _T("winsta0"), // the interactive window station
  1916. FALSE, // handle is not inheritable
  1917. READ_CONTROL | WRITE_DAC); // rights to read/write the DACL
  1918. if (hwinsta == NULL)
  1919. {
  1920. Dbg("OpenWindowStation failed GLE=%u.", GetLastError());
  1921. goto Cleanup;
  1922. }
  1923. // To get the correct default desktop, set the caller's
  1924. // window station to the interactive window station.
  1925. if (!SetProcessWindowStation(hwinsta))
  1926. {
  1927. Dbg("SetProcessWindowStation failed GLE=%u.", GetLastError());
  1928. goto Cleanup;
  1929. }
  1930. // Get a handle to the interactive desktop.
  1931. hdesk = OpenDesktop(
  1932. _T("default"), // the interactive window station
  1933. 0, // no interaction with other desktop processes
  1934. FALSE, // handle is not inheritable
  1935. READ_CONTROL | // request the rights to read and write the DACL
  1936. WRITE_DAC |
  1937. DESKTOP_WRITEOBJECTS |
  1938. DESKTOP_READOBJECTS);
  1939. // Restore the caller's window station.
  1940. if (!SetProcessWindowStation(hwinstaSave))
  1941. {
  1942. Dbg("SetProcessWindowStation failed GLE=%u.", GetLastError());
  1943. goto Cleanup;
  1944. }
  1945. if (hdesk == NULL)
  1946. {
  1947. Dbg("hdesk failed GLE=%u.", GetLastError());
  1948. goto Cleanup;
  1949. }
  1950. // Get the SID for the client's logon session.
  1951. if (!GetLogonSID(hToken, &pSid))
  1952. {
  1953. Dbg("GetLogonSID failed GLE=%u.", GetLastError());
  1954. goto Cleanup;
  1955. }
  1956. // Allow logon SID full access to interactive window station.
  1957. if (! AddAceToWindowStation(hwinsta, pSid) )
  1958. {
  1959. Dbg("AddAceToWindowStation failed GLE=%u.", GetLastError());
  1960. goto Cleanup;
  1961. }
  1962. // Allow logon SID full access to interactive desktop.
  1963. if (! AddAceToDesktop(hdesk, pSid) )
  1964. {
  1965. Dbg("AddAceToDesktop failed GLE=%u.", GetLastError());
  1966. goto Cleanup;
  1967. }
  1968. // Impersonate client to ensure access to executable file.
  1969. if (! ImpersonateLoggedOnUser(hToken) )
  1970. {
  1971. Dbg("ImpersonateLoggedOnUser failed GLE=%u.", GetLastError());
  1972. goto Cleanup;
  1973. }
  1974. // Initialize the STARTUPINFO structure.
  1975. // Specify that the process runs in the interactive desktop.
  1976. ZeroMemory(&si, sizeof(STARTUPINFO));
  1977. si.cb= sizeof(STARTUPINFO);
  1978. si.lpDesktop = TEXT("winsta0\\default");
  1979. si.hStdError = psi->hStdError;
  1980. si.hStdOutput = psi->hStdOutput;
  1981. si.hStdInput = psi->hStdInput;
  1982. si.dwFlags = psi->dwFlags;
  1983. si.wShowWindow = psi->wShowWindow;
  1984. // Launch the process in the client's logon session.
  1985. bResult = CreateProcessAsUser(
  1986. hToken, // client's access token
  1987. NULL, // file to execute
  1988. lpCommandLine, // command line
  1989. NULL, // pointer to process SECURITY_ATTRIBUTES
  1990. NULL, // pointer to thread SECURITY_ATTRIBUTES
  1991. FALSE, // handles are not inheritable
  1992. fdwCreate, // creation flags
  1993. NULL, // pointer to new environment block
  1994. NULL, // name of current directory
  1995. &si, // pointer to STARTUPINFO structure
  1996. &pi // receives information about new process
  1997. );
  1998. // End impersonation of client.
  1999. RevertToSelf();
  2000. if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)
  2001. {
  2002. //WaitForSingleObject(pi.hProcess, INFINITE);
  2003. if((fdwCreate & CREATE_SUSPENDED) == CREATE_SUSPENDED)
  2004. {
  2005. *pDwProcessId = pi.dwProcessId;
  2006. ResumeThread(pi.hThread);
  2007. }
  2008. CloseHandle(pi.hProcess);
  2009. }
  2010. else
  2011. {
  2012. Dbg("CreateProcessAsUser failed GLE=%u.", GetLastError());
  2013. }
  2014. if (pi.hThread != INVALID_HANDLE_VALUE)
  2015. CloseHandle(pi.hThread);
  2016. Cleanup:
  2017. if (hwinstaSave != NULL)
  2018. SetProcessWindowStation (hwinstaSave);
  2019. // Free the buffer for the logon SID.
  2020. if (pSid)
  2021. FreeLogonSID(&pSid);
  2022. // Close the handles to the interactive window station and desktop.
  2023. if (hwinsta)
  2024. CloseWindowStation(hwinsta);
  2025. if (hdesk)
  2026. CloseDesktop(hdesk);
  2027. // Close the handle to the client's access token.
  2028. if (hToken != INVALID_HANDLE_VALUE)
  2029. CloseHandle(hToken);
  2030. return bResult;
  2031. }
  2032. BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
  2033. {
  2034. ACCESS_ALLOWED_ACE *pace = NULL;
  2035. ACL_SIZE_INFORMATION aclSizeInfo;
  2036. BOOL bDaclExist;
  2037. BOOL bDaclPresent;
  2038. BOOL bSuccess = FALSE;
  2039. DWORD dwNewAclSize;
  2040. DWORD dwSidSize = 0;
  2041. DWORD dwSdSizeNeeded;
  2042. PACL pacl;
  2043. PACL pNewAcl = NULL;
  2044. PSECURITY_DESCRIPTOR psd = NULL;
  2045. PSECURITY_DESCRIPTOR psdNew = NULL;
  2046. PVOID pTempAce;
  2047. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
  2048. unsigned int i;
  2049. __try
  2050. {
  2051. // Obtain the DACL for the window station.
  2052. if (!GetUserObjectSecurity(
  2053. hwinsta,
  2054. &si,
  2055. psd,
  2056. dwSidSize,
  2057. &dwSdSizeNeeded)
  2058. )
  2059. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  2060. {
  2061. psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
  2062. GetProcessHeap(),
  2063. HEAP_ZERO_MEMORY,
  2064. dwSdSizeNeeded);
  2065. if (psd == NULL)
  2066. __leave;
  2067. psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
  2068. GetProcessHeap(),
  2069. HEAP_ZERO_MEMORY,
  2070. dwSdSizeNeeded);
  2071. if (psdNew == NULL)
  2072. __leave;
  2073. dwSidSize = dwSdSizeNeeded;
  2074. if (!GetUserObjectSecurity(
  2075. hwinsta,
  2076. &si,
  2077. psd,
  2078. dwSidSize,
  2079. &dwSdSizeNeeded)
  2080. )
  2081. __leave;
  2082. }
  2083. else
  2084. __leave;
  2085. // Create a new DACL.
  2086. if (!InitializeSecurityDescriptor(
  2087. psdNew,
  2088. SECURITY_DESCRIPTOR_REVISION)
  2089. )
  2090. __leave;
  2091. // Get the DACL from the security descriptor.
  2092. if (!GetSecurityDescriptorDacl(
  2093. psd,
  2094. &bDaclPresent,
  2095. &pacl,
  2096. &bDaclExist)
  2097. )
  2098. __leave;
  2099. // Initialize the ACL.
  2100. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
  2101. aclSizeInfo.AclBytesInUse = sizeof(ACL);
  2102. // Call only if the DACL is not NULL.
  2103. if (pacl != NULL)
  2104. {
  2105. // get the file ACL size info
  2106. if (!GetAclInformation(
  2107. pacl,
  2108. (LPVOID)&aclSizeInfo,
  2109. sizeof(ACL_SIZE_INFORMATION),
  2110. AclSizeInformation)
  2111. )
  2112. __leave;
  2113. }
  2114. // Compute the size of the new ACL.
  2115. dwNewAclSize = aclSizeInfo.AclBytesInUse +
  2116. (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
  2117. (2*sizeof(DWORD));
  2118. // Allocate memory for the new ACL.
  2119. pNewAcl = (PACL)HeapAlloc(
  2120. GetProcessHeap(),
  2121. HEAP_ZERO_MEMORY,
  2122. dwNewAclSize);
  2123. if (pNewAcl == NULL)
  2124. __leave;
  2125. // Initialize the new DACL.
  2126. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
  2127. __leave;
  2128. // If DACL is present, copy it to a new DACL.
  2129. if (bDaclPresent)
  2130. {
  2131. // Copy the ACEs to the new ACL.
  2132. if (aclSizeInfo.AceCount)
  2133. {
  2134. for (i=0; i < aclSizeInfo.AceCount; i++)
  2135. {
  2136. // Get an ACE.
  2137. if (!GetAce(pacl, i, &pTempAce))
  2138. __leave;
  2139. // Add the ACE to the new ACL.
  2140. if (!AddAce(
  2141. pNewAcl,
  2142. ACL_REVISION,
  2143. MAXDWORD,
  2144. pTempAce,
  2145. ((PACE_HEADER)pTempAce)->AceSize)
  2146. )
  2147. __leave;
  2148. }
  2149. }
  2150. }
  2151. // Add the first ACE to the window station.
  2152. pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
  2153. GetProcessHeap(),
  2154. HEAP_ZERO_MEMORY,
  2155. sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
  2156. sizeof(DWORD));
  2157. if (pace == NULL)
  2158. __leave;
  2159. pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
  2160. pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
  2161. INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
  2162. pace->Header.AceSize = LOWORD(sizeof(ACCESS_ALLOWED_ACE) +
  2163. GetLengthSid(psid) - sizeof(DWORD));
  2164. pace->Mask = GENERIC_ACCESS;
  2165. if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
  2166. __leave;
  2167. if (!AddAce(
  2168. pNewAcl,
  2169. ACL_REVISION,
  2170. MAXDWORD,
  2171. (LPVOID)pace,
  2172. pace->Header.AceSize)
  2173. )
  2174. __leave;
  2175. // Add the second ACE to the window station.
  2176. pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
  2177. pace->Mask = WINSTA_ALL;
  2178. if (!AddAce(
  2179. pNewAcl,
  2180. ACL_REVISION,
  2181. MAXDWORD,
  2182. (LPVOID)pace,
  2183. pace->Header.AceSize)
  2184. )
  2185. __leave;
  2186. // Set a new DACL for the security descriptor.
  2187. if (!SetSecurityDescriptorDacl(
  2188. psdNew,
  2189. TRUE,
  2190. pNewAcl,
  2191. FALSE)
  2192. )
  2193. __leave;
  2194. // Set the new security descriptor for the window station.
  2195. if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
  2196. __leave;
  2197. // Indicate success.
  2198. bSuccess = TRUE;
  2199. }
  2200. __finally
  2201. {
  2202. // Free the allocated buffers.
  2203. if (pace != NULL)
  2204. HeapFree(GetProcessHeap(), 0, (LPVOID)pace);
  2205. if (pNewAcl != NULL)
  2206. HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
  2207. if (psd != NULL)
  2208. HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
  2209. if (psdNew != NULL)
  2210. HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
  2211. }
  2212. return bSuccess;
  2213. }
  2214. BOOL GetLogonSID (HANDLE hToken, PSID *ppsid)
  2215. {
  2216. BOOL bSuccess = FALSE;
  2217. DWORD dwIndex;
  2218. DWORD dwLength = 0;
  2219. PTOKEN_GROUPS ptg = NULL;
  2220. // Verify the parameter passed in is not NULL.
  2221. if (NULL == ppsid)
  2222. goto Cleanup;
  2223. // Get required buffer size and allocate the TOKEN_GROUPS buffer.
  2224. if (!GetTokenInformation(
  2225. hToken, // handle to the access token
  2226. TokenGroups, // get information about the token's groups
  2227. (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
  2228. 0, // size of buffer
  2229. &dwLength // receives required buffer size
  2230. ))
  2231. {
  2232. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  2233. goto Cleanup;
  2234. ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),
  2235. HEAP_ZERO_MEMORY, dwLength);
  2236. if (ptg == NULL)
  2237. goto Cleanup;
  2238. }
  2239. // Get the token group information from the access token.
  2240. if (!GetTokenInformation(
  2241. hToken, // handle to the access token
  2242. TokenGroups, // get information about the token's groups
  2243. (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer
  2244. dwLength, // size of buffer
  2245. &dwLength // receives required buffer size
  2246. ))
  2247. {
  2248. goto Cleanup;
  2249. }
  2250. // Loop through the groups to find the logon SID.
  2251. for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
  2252. if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
  2253. == SE_GROUP_LOGON_ID)
  2254. {
  2255. // Found the logon SID; make a copy of it.
  2256. dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);
  2257. *ppsid = (PSID) HeapAlloc(GetProcessHeap(),
  2258. HEAP_ZERO_MEMORY, dwLength);
  2259. if (*ppsid == NULL)
  2260. goto Cleanup;
  2261. if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))
  2262. {
  2263. HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
  2264. goto Cleanup;
  2265. }
  2266. break;
  2267. }
  2268. bSuccess = TRUE;
  2269. Cleanup:
  2270. // Free the buffer for the token groups.
  2271. if (ptg != NULL)
  2272. HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);
  2273. return bSuccess;
  2274. }
  2275. VOID FreeLogonSID (PSID *ppsid)
  2276. {
  2277. HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);
  2278. }
  2279. BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
  2280. {
  2281. ACL_SIZE_INFORMATION aclSizeInfo;
  2282. BOOL bDaclExist;
  2283. BOOL bDaclPresent;
  2284. BOOL bSuccess = FALSE;
  2285. DWORD dwNewAclSize;
  2286. DWORD dwSidSize = 0;
  2287. DWORD dwSdSizeNeeded;
  2288. PACL pacl;
  2289. PACL pNewAcl = NULL;
  2290. PSECURITY_DESCRIPTOR psd = NULL;
  2291. PSECURITY_DESCRIPTOR psdNew = NULL;
  2292. PVOID pTempAce;
  2293. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
  2294. unsigned int i;
  2295. __try
  2296. {
  2297. // Obtain the security descriptor for the desktop object.
  2298. if (!GetUserObjectSecurity(
  2299. hdesk,
  2300. &si,
  2301. psd,
  2302. dwSidSize,
  2303. &dwSdSizeNeeded))
  2304. {
  2305. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  2306. {
  2307. psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
  2308. GetProcessHeap(),
  2309. HEAP_ZERO_MEMORY,
  2310. dwSdSizeNeeded );
  2311. if (psd == NULL)
  2312. __leave;
  2313. psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
  2314. GetProcessHeap(),
  2315. HEAP_ZERO_MEMORY,
  2316. dwSdSizeNeeded);
  2317. if (psdNew == NULL)
  2318. __leave;
  2319. dwSidSize = dwSdSizeNeeded;
  2320. if (!GetUserObjectSecurity(
  2321. hdesk,
  2322. &si,
  2323. psd,
  2324. dwSidSize,
  2325. &dwSdSizeNeeded)
  2326. )
  2327. __leave;
  2328. }
  2329. else
  2330. __leave;
  2331. }
  2332. // Create a new security descriptor.
  2333. if (!InitializeSecurityDescriptor(
  2334. psdNew,
  2335. SECURITY_DESCRIPTOR_REVISION)
  2336. )
  2337. __leave;
  2338. // Obtain the DACL from the security descriptor.
  2339. if (!GetSecurityDescriptorDacl(
  2340. psd,
  2341. &bDaclPresent,
  2342. &pacl,
  2343. &bDaclExist)
  2344. )
  2345. __leave;
  2346. // Initialize.
  2347. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
  2348. aclSizeInfo.AclBytesInUse = sizeof(ACL);
  2349. // Call only if NULL DACL.
  2350. if (pacl != NULL)
  2351. {
  2352. // Determine the size of the ACL information.
  2353. if (!GetAclInformation(
  2354. pacl,
  2355. (LPVOID)&aclSizeInfo,
  2356. sizeof(ACL_SIZE_INFORMATION),
  2357. AclSizeInformation)
  2358. )
  2359. __leave;
  2360. }
  2361. // Compute the size of the new ACL.
  2362. dwNewAclSize = aclSizeInfo.AclBytesInUse +
  2363. sizeof(ACCESS_ALLOWED_ACE) +
  2364. GetLengthSid(psid) - sizeof(DWORD);
  2365. // Allocate buffer for the new ACL.
  2366. pNewAcl = (PACL)HeapAlloc(
  2367. GetProcessHeap(),
  2368. HEAP_ZERO_MEMORY,
  2369. dwNewAclSize);
  2370. if (pNewAcl == NULL)
  2371. __leave;
  2372. // Initialize the new ACL.
  2373. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
  2374. __leave;
  2375. // If DACL is present, copy it to a new DACL.
  2376. if (bDaclPresent)
  2377. {
  2378. // Copy the ACEs to the new ACL.
  2379. if (aclSizeInfo.AceCount)
  2380. {
  2381. for (i=0; i < aclSizeInfo.AceCount; i++)
  2382. {
  2383. // Get an ACE.
  2384. if (!GetAce(pacl, i, &pTempAce))
  2385. __leave;
  2386. // Add the ACE to the new ACL.
  2387. if (!AddAce(
  2388. pNewAcl,
  2389. ACL_REVISION,
  2390. MAXDWORD,
  2391. pTempAce,
  2392. ((PACE_HEADER)pTempAce)->AceSize)
  2393. )
  2394. __leave;
  2395. }
  2396. }
  2397. }
  2398. // Add ACE to the DACL.
  2399. if (!AddAccessAllowedAce(
  2400. pNewAcl,
  2401. ACL_REVISION,
  2402. DESKTOP_ALL,
  2403. psid)
  2404. )
  2405. __leave;
  2406. // Set new DACL to the new security descriptor.
  2407. if (!SetSecurityDescriptorDacl(
  2408. psdNew,
  2409. TRUE,
  2410. pNewAcl,
  2411. FALSE)
  2412. )
  2413. __leave;
  2414. // Set the new security descriptor for the desktop object.
  2415. if (!SetUserObjectSecurity(hdesk, &si, psdNew))
  2416. __leave;
  2417. // Indicate success.
  2418. bSuccess = TRUE;
  2419. }
  2420. __finally
  2421. {
  2422. // Free buffers.
  2423. if (pNewAcl != NULL)
  2424. HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
  2425. if (psd != NULL)
  2426. HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
  2427. if (psdNew != NULL)
  2428. HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
  2429. }
  2430. return bSuccess;
  2431. }