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.

429 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. immsec.c
  5. Abstract:
  6. security code called by IMEs
  7. Author:
  8. Chae Seong Lim [cslim] 23-Dec-1997
  9. Takao Kitano [takaok] 01-May-1996
  10. Revision History:
  11. Chae Seong Lim [cslim] 971223 Korean IME version
  12. Hiroaki Kanokogi [hiroakik] 960624 Modified for MSIME96
  13. Hiroaki Kanokogi [hiroakik] 960911 NT #11911
  14. --*/
  15. #include "private.h"
  16. #include "immsec.h"
  17. #include "osver.h"
  18. #define MEMALLOC(x) LocalAlloc(LMEM_FIXED, x)
  19. #define MEMFREE(x) LocalFree(x)
  20. //
  21. // internal functions
  22. //
  23. PSID MyCreateSid( DWORD dwSubAuthority );
  24. //
  25. // debug functions
  26. //
  27. #ifdef DEBUG
  28. #define ERROROUT(x) ErrorOut( x )
  29. #define WARNOUT(x) WarnOut( x )
  30. #else
  31. #define ERROROUT(x)
  32. #define WARNOUT(x)
  33. #endif
  34. #ifdef DEBUG
  35. VOID WarnOut( PTSTR pStr )
  36. {
  37. OutputDebugString( pStr );
  38. }
  39. VOID ErrorOut( PTSTR pStr )
  40. {
  41. DWORD dwError;
  42. DWORD dwResult;
  43. static TCHAR buf1[512];
  44. static TCHAR buf2[512];
  45. dwError = GetLastError();
  46. dwResult = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
  47. NULL,
  48. dwError,
  49. MAKELANGID( LANG_ENGLISH, LANG_NEUTRAL ),
  50. buf1,
  51. 512,
  52. NULL );
  53. if (dwResult > 0)
  54. {
  55. wsprintfA(buf2, "%s:%s(0x%x)", pStr, buf1, dwError);
  56. }
  57. else
  58. {
  59. wsprintfA(buf2, "%s:(0x%x)", pStr, dwError);
  60. }
  61. OutputDebugString( buf2 );
  62. }
  63. #endif
  64. //
  65. // GetIMESecurityAttributes()
  66. //
  67. // The purpose of this function:
  68. //
  69. // Allocate and set the security attributes that is
  70. // appropriate for named objects created by an IME.
  71. // The security attributes will give GENERIC_ALL
  72. // access to the following users:
  73. //
  74. // o Users who log on for interactive operation
  75. // o The user account used by the operating system
  76. //
  77. // Return value:
  78. //
  79. // If the function succeeds, the return value is a
  80. // pointer to SECURITY_ATTRIBUTES. If the function fails,
  81. // the return value is NULL. To get extended error
  82. // information, call GetLastError().
  83. //
  84. // Remarks:
  85. //
  86. // FreeIMESecurityAttributes() should be called to free up the
  87. // SECURITY_ATTRIBUTES allocated by this function.
  88. //
  89. static PSECURITY_ATTRIBUTES g_pSAIME = NULL;
  90. PSECURITY_ATTRIBUTES GetIMESecurityAttributes(VOID)
  91. {
  92. if (IsOnNT())
  93. return (g_pSAIME == NULL) ? (g_pSAIME = CreateSecurityAttributes()) : g_pSAIME;
  94. else
  95. return NULL;
  96. }
  97. //
  98. // FreeIMESecurityAttributes()
  99. //
  100. // The purpose of this function:
  101. //
  102. // Frees the memory objects allocated by previous
  103. // GetIMESecurityAttributes() call.
  104. //
  105. VOID FreeIMESecurityAttributes()
  106. {
  107. if (g_pSAIME != NULL)
  108. FreeSecurityAttributes(g_pSAIME);
  109. g_pSAIME = NULL;
  110. }
  111. //
  112. // CreateSecurityAttributes()
  113. //
  114. // The purpose of this function:
  115. //
  116. // Allocate and set the security attributes that is
  117. // appropriate for named objects created by an IME.
  118. // The security attributes will give GENERIC_ALL
  119. // access to the following users:
  120. //
  121. // o Users who log on for interactive operation
  122. // o The user account used by the operating system
  123. //
  124. // Return value:
  125. //
  126. // If the function succeeds, the return value is a
  127. // pointer to SECURITY_ATTRIBUTES. If the function fails,
  128. // the return value is NULL. To get extended error
  129. // information, call GetLastError().
  130. //
  131. // Remarks:
  132. //
  133. // FreeSecurityAttributes() should be called to free up the
  134. // SECURITY_ATTRIBUTES allocated by this function.
  135. //
  136. PSECURITY_ATTRIBUTES CreateSecurityAttributes()
  137. {
  138. PSECURITY_ATTRIBUTES psa;
  139. PSECURITY_DESCRIPTOR psd;
  140. PACL pacl;
  141. ULONG AclSize;
  142. PSID psid1, psid2, psid3, psid4;
  143. BOOL fResult;
  144. psid1 = MyCreateSid(SECURITY_INTERACTIVE_RID);
  145. if (psid1 == NULL)
  146. return NULL;
  147. psid2 = MyCreateSid(SECURITY_LOCAL_SYSTEM_RID);
  148. if (psid2 == NULL)
  149. goto Fail5;
  150. psid3 = MyCreateSid(SECURITY_SERVICE_RID);
  151. if (psid3 == NULL)
  152. goto Fail4;
  153. psid4 = MyCreateSid(SECURITY_NETWORK_RID);
  154. if (psid4 == NULL)
  155. goto Fail3;
  156. //
  157. // allocate and initialize an access control list (ACL) that will
  158. // contain the SIDs we've just created.
  159. //
  160. AclSize = sizeof(ACL) +
  161. (4 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG))) +
  162. GetLengthSid(psid1) +
  163. GetLengthSid(psid2) +
  164. GetLengthSid(psid3) +
  165. GetLengthSid(psid4);
  166. pacl = (PACL)MEMALLOC(AclSize);
  167. if (pacl == NULL)
  168. {
  169. ERROROUT(TEXT("CreateSecurityAttributes:LocalAlloc for ACL failed"));
  170. goto Fail2;
  171. }
  172. fResult = InitializeAcl(pacl, AclSize, ACL_REVISION);
  173. if (!fResult)
  174. {
  175. ERROROUT(TEXT("CreateSecurityAttributes:InitializeAcl failed"));
  176. goto Fail;
  177. }
  178. //
  179. // adds an access-allowed ACE for interactive users to the ACL
  180. //
  181. fResult = AddAccessAllowedAce(pacl,
  182. ACL_REVISION,
  183. GENERIC_ALL,
  184. psid1);
  185. if (!fResult)
  186. {
  187. ERROROUT(TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed"));
  188. goto Fail;
  189. }
  190. //
  191. // adds an access-allowed ACE for operating system to the ACL
  192. //
  193. fResult = AddAccessAllowedAce(pacl,
  194. ACL_REVISION,
  195. GENERIC_ALL,
  196. psid2);
  197. if (!fResult)
  198. {
  199. ERROROUT(TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed"));
  200. goto Fail;
  201. }
  202. //
  203. // adds an access-allowed ACE for operating system to the ACL
  204. //
  205. fResult = AddAccessAllowedAce(pacl,
  206. ACL_REVISION,
  207. GENERIC_ALL,
  208. psid3);
  209. if (!fResult)
  210. {
  211. ERROROUT( TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed") );
  212. goto Fail;
  213. }
  214. //
  215. // adds an access-allowed ACE for operating system to the ACL
  216. //
  217. fResult = AddAccessAllowedAce(pacl,
  218. ACL_REVISION,
  219. GENERIC_ALL,
  220. psid4);
  221. if (!fResult)
  222. {
  223. ERROROUT( TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed") );
  224. goto Fail;
  225. }
  226. //
  227. // Those SIDs have been copied into the ACL. We don't need'em any more.
  228. //
  229. FreeSid(psid1);
  230. FreeSid(psid2);
  231. FreeSid(psid3);
  232. FreeSid(psid4);
  233. //
  234. // Let's make sure that our ACL is valid.
  235. //
  236. if (!IsValidAcl(pacl))
  237. {
  238. WARNOUT(TEXT("CreateSecurityAttributes:IsValidAcl returns fFalse!"));
  239. MEMFREE(pacl);
  240. return NULL;
  241. }
  242. //
  243. // allocate security attribute
  244. //
  245. psa = (PSECURITY_ATTRIBUTES)MEMALLOC(sizeof(SECURITY_ATTRIBUTES));
  246. if (psa == NULL)
  247. {
  248. ERROROUT(TEXT("CreateSecurityAttributes:LocalAlloc for psa failed"));
  249. MEMFREE(pacl);
  250. return NULL;
  251. }
  252. //
  253. // allocate and initialize a new security descriptor
  254. //
  255. psd = MEMALLOC(SECURITY_DESCRIPTOR_MIN_LENGTH);
  256. if (psd == NULL)
  257. {
  258. ERROROUT(TEXT("CreateSecurityAttributes:LocalAlloc for psd failed"));
  259. MEMFREE(pacl);
  260. MEMFREE(psa);
  261. return NULL;
  262. }
  263. if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
  264. {
  265. ERROROUT(TEXT("CreateSecurityAttributes:InitializeSecurityDescriptor failed"));
  266. MEMFREE(pacl);
  267. MEMFREE(psa);
  268. MEMFREE(psd);
  269. return NULL;
  270. }
  271. fResult = SetSecurityDescriptorDacl(psd, fTrue, pacl, fFalse );
  272. // The discretionary ACL is referenced by, not copied
  273. // into, the security descriptor. We shouldn't free up ACL
  274. // after the SetSecurityDescriptorDacl call.
  275. if (!fResult)
  276. {
  277. ERROROUT(TEXT("CreateSecurityAttributes:SetSecurityDescriptorDacl failed"));
  278. MEMFREE(pacl);
  279. MEMFREE(psa);
  280. MEMFREE(psd);
  281. return NULL;
  282. }
  283. if (!IsValidSecurityDescriptor(psd))
  284. {
  285. WARNOUT(TEXT("CreateSecurityAttributes:IsValidSecurityDescriptor failed!"));
  286. MEMFREE(pacl);
  287. MEMFREE(psa);
  288. MEMFREE(psd);
  289. return NULL;
  290. }
  291. //
  292. // everything is done
  293. //
  294. psa->nLength = sizeof(SECURITY_ATTRIBUTES);
  295. psa->lpSecurityDescriptor = (PVOID)psd;
  296. psa->bInheritHandle = fTrue;
  297. return psa;
  298. Fail:
  299. MEMFREE(pacl);
  300. Fail2:
  301. FreeSid(psid4);
  302. Fail3:
  303. FreeSid(psid3);
  304. Fail4:
  305. FreeSid(psid2);
  306. Fail5:
  307. FreeSid(psid1);
  308. return NULL;
  309. }
  310. PSID MyCreateSid(DWORD dwSubAuthority)
  311. {
  312. PSID psid;
  313. BOOL fResult;
  314. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  315. //
  316. // allocate and initialize an SID
  317. //
  318. fResult = AllocateAndInitializeSid(&SidAuthority,
  319. 1,
  320. dwSubAuthority,
  321. 0,0,0,0,0,0,0,
  322. &psid );
  323. if (!fResult)
  324. {
  325. ERROROUT(TEXT("MyCreateSid:AllocateAndInitializeSid failed"));
  326. return NULL;
  327. }
  328. if (!IsValidSid(psid))
  329. {
  330. WARNOUT(TEXT("MyCreateSid:AllocateAndInitializeSid returns bogus sid"));
  331. FreeSid(psid);
  332. return NULL;
  333. }
  334. return psid;
  335. }
  336. //
  337. // FreeSecurityAttributes()
  338. //
  339. // The purpose of this function:
  340. //
  341. // Frees the memory objects allocated by previous
  342. // CreateSecurityAttributes() call.
  343. //
  344. VOID FreeSecurityAttributes( PSECURITY_ATTRIBUTES psa )
  345. {
  346. BOOL fResult;
  347. BOOL fDaclPresent;
  348. BOOL fDaclDefaulted;
  349. PACL pacl;
  350. fResult = GetSecurityDescriptorDacl(psa->lpSecurityDescriptor,
  351. &fDaclPresent,
  352. &pacl,
  353. &fDaclDefaulted);
  354. if (fResult)
  355. {
  356. if (pacl != NULL)
  357. MEMFREE(pacl);
  358. }
  359. else
  360. {
  361. ERROROUT( TEXT("FreeSecurityAttributes:GetSecurityDescriptorDacl failed") );
  362. }
  363. MEMFREE(psa->lpSecurityDescriptor);
  364. MEMFREE(psa);
  365. }