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.

600 lines
16 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 <windows.h>
  16. #include "hwxobj.h"
  17. #define _USEINIME_
  18. //#ifndef _USEINIME_ // .IME does not need
  19. //#include <dbgmgr.h>
  20. //#include <misc/memalloc.h>
  21. //#endif // _USEINIME_
  22. #include "immsec.h"
  23. #define MEMALLOC(x) LocalAlloc(LMEM_FIXED, x)
  24. #define MEMFREE(x) LocalFree(x)
  25. //
  26. // internal functions
  27. //
  28. PSID MyCreateSid( DWORD dwSubAuthority );
  29. #ifndef _USEINIME_
  30. POSVERSIONINFO GetVersionInfo(VOID);
  31. #endif // _USEINIME_
  32. //
  33. // debug functions
  34. //
  35. #ifdef DEBUG
  36. #define ERROROUT(x) ErrorOut( x )
  37. #define WARNOUT(x) WarnOut( x )
  38. #else
  39. #define ERROROUT(x)
  40. #define WARNOUT(x)
  41. #endif
  42. #ifdef DEBUG
  43. VOID WarnOut( PTSTR pStr )
  44. {
  45. OutputDebugString( pStr );
  46. }
  47. VOID ErrorOut( PTSTR pStr )
  48. {
  49. DWORD dwError;
  50. DWORD dwResult;
  51. static TCHAR buf1[512];
  52. static TCHAR buf2[512];
  53. dwError = GetLastError();
  54. dwResult = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
  55. NULL,
  56. dwError,
  57. MAKELANGID( LANG_ENGLISH, LANG_NEUTRAL ),
  58. buf1,
  59. 512,
  60. NULL );
  61. if ( dwResult > 0 ) {
  62. wsprintfA(buf2, "%s:%s(0x%x)", pStr, buf1, dwError);
  63. } else {
  64. wsprintfA(buf2, "%s:(0x%x)", pStr, dwError);
  65. }
  66. OutputDebugString( buf2 );
  67. }
  68. #endif
  69. //
  70. // GetIMESecurityAttributes()
  71. //
  72. // The purpose of this function:
  73. //
  74. // Allocate and set the security attributes that is
  75. // appropriate for named objects created by an IME.
  76. // The security attributes will give GENERIC_ALL
  77. // access to the following users:
  78. //
  79. // o Users who log on for interactive operation
  80. // o The user account used by the operating system
  81. //
  82. // Return value:
  83. //
  84. // If the function succeeds, the return value is a
  85. // pointer to SECURITY_ATTRIBUTES. If the function fails,
  86. // the return value is NULL. To get extended error
  87. // information, call GetLastError().
  88. //
  89. // Remarks:
  90. //
  91. // FreeIMESecurityAttributes() should be called to free up the
  92. // SECURITY_ATTRIBUTES allocated by this function.
  93. //
  94. static PSECURITY_ATTRIBUTES pSAIME = NULL;
  95. static PSECURITY_ATTRIBUTES pSAIME_UserDic = NULL;
  96. static INT nNT95 = 0; //0...Not examined, 1...NT, 2...Not NT
  97. PSECURITY_ATTRIBUTES GetIMESecurityAttributes(VOID)
  98. {
  99. if (nNT95 == 0)
  100. nNT95 = IsWinNT() ? 1 : 2;
  101. if (nNT95==1)
  102. return (pSAIME==NULL) ? (pSAIME=CreateSecurityAttributes()) : pSAIME;
  103. else
  104. return NULL;
  105. // To avoid CreateSecurityAttributes from being called every time when OS is not NT.
  106. }
  107. #if NOT_USED
  108. PSECURITY_ATTRIBUTES GetIMESecurityAttributesEx(VOID)
  109. {
  110. if (nNT95 == 0)
  111. nNT95 = IsWinNT() ? 1 : 2; //IsNT is not for multi-threaded programs, right?
  112. if (nNT95==1)
  113. return (pSAIME_UserDic==NULL) ? (pSAIME_UserDic=CreateSecurityAttributesEx()) : pSAIME_UserDic;
  114. else
  115. return NULL;
  116. // To avoid CreateSecurityAttributes from being called every time when OS is not NT.
  117. }
  118. #endif
  119. //
  120. // FreeIMESecurityAttributes()
  121. //
  122. // The purpose of this function:
  123. //
  124. // Frees the memory objects allocated by previous
  125. // GetIMESecurityAttributes() call.
  126. //
  127. VOID FreeIMESecurityAttributes()
  128. {
  129. if (pSAIME!=NULL)
  130. FreeSecurityAttributes(pSAIME);
  131. if (pSAIME_UserDic!=NULL)
  132. FreeSecurityAttributes(pSAIME_UserDic);
  133. pSAIME = NULL;
  134. pSAIME_UserDic = NULL;
  135. }
  136. //
  137. // CreateSecurityAttributes()
  138. //
  139. // The purpose of this function:
  140. //
  141. // Allocate and set the security attributes that is
  142. // appropriate for named objects created by an IME.
  143. // The security attributes will give GENERIC_ALL
  144. // access to the following users:
  145. //
  146. // o Users who log on for interactive operation
  147. // o The user account used by the operating system
  148. //
  149. // Return value:
  150. //
  151. // If the function succeeds, the return value is a
  152. // pointer to SECURITY_ATTRIBUTES. If the function fails,
  153. // the return value is NULL. To get extended error
  154. // information, call GetLastError().
  155. //
  156. // Remarks:
  157. //
  158. // FreeSecurityAttributes() should be called to free up the
  159. // SECURITY_ATTRIBUTES allocated by this function.
  160. //
  161. PSECURITY_ATTRIBUTES CreateSecurityAttributes()
  162. {
  163. PSECURITY_ATTRIBUTES psa;
  164. PSECURITY_DESCRIPTOR psd;
  165. PACL pacl;
  166. DWORD cbacl;
  167. PSID psid1, psid2;
  168. BOOL fResult;
  169. psid1 = MyCreateSid( SECURITY_INTERACTIVE_RID );
  170. if ( psid1 == NULL ) {
  171. return NULL;
  172. }
  173. psid2 = MyCreateSid( SECURITY_LOCAL_SYSTEM_RID );
  174. if ( psid2 == NULL ) {
  175. FreeSid ( psid1 );
  176. return NULL;
  177. }
  178. //
  179. // allocate and initialize an access control list (ACL) that will
  180. // contain the SIDs we've just created.
  181. //
  182. cbacl = sizeof(ACL) +
  183. (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) * 2 +
  184. GetLengthSid(psid1) + GetLengthSid(psid2);
  185. pacl = (PACL)MEMALLOC( cbacl );
  186. if ( pacl == NULL ) {
  187. ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for ACL failed") );
  188. FreeSid ( psid1 );
  189. FreeSid ( psid2 );
  190. return NULL;
  191. }
  192. fResult = InitializeAcl( pacl, cbacl, ACL_REVISION );
  193. if ( ! fResult ) {
  194. ERROROUT( TEXT("CreateSecurityAttributes:InitializeAcl failed") );
  195. FreeSid ( psid1 );
  196. FreeSid ( psid2 );
  197. MEMFREE( pacl );
  198. return NULL;
  199. }
  200. //
  201. // adds an access-allowed ACE for interactive users to the ACL
  202. //
  203. fResult = AddAccessAllowedAce( pacl,
  204. ACL_REVISION,
  205. GENERIC_ALL,
  206. psid1 );
  207. if ( !fResult ) {
  208. ERROROUT( TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed") );
  209. MEMFREE( pacl );
  210. FreeSid ( psid1 );
  211. FreeSid ( psid2 );
  212. return NULL;
  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. psid2 );
  221. if ( !fResult ) {
  222. ERROROUT( TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed") );
  223. MEMFREE( pacl );
  224. FreeSid ( psid1 );
  225. FreeSid ( psid2 );
  226. return NULL;
  227. }
  228. //
  229. // Those SIDs have been copied into the ACL. We don't need'em any more.
  230. //
  231. FreeSid ( psid1 );
  232. FreeSid ( psid2 );
  233. //
  234. // Let's make sure that our ACL is valid.
  235. //
  236. if (!IsValidAcl(pacl)) {
  237. WARNOUT( TEXT("CreateSecurityAttributes:IsValidAcl returns fFalse!"));
  238. MEMFREE( pacl );
  239. return NULL;
  240. }
  241. //
  242. // allocate security attribute
  243. //
  244. psa = (PSECURITY_ATTRIBUTES)MEMALLOC( sizeof( SECURITY_ATTRIBUTES ) );
  245. if ( psa == NULL ) {
  246. ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psa failed") );
  247. MEMFREE( pacl );
  248. return NULL;
  249. }
  250. //
  251. // allocate and initialize a new security descriptor
  252. //
  253. psd = MEMALLOC( SECURITY_DESCRIPTOR_MIN_LENGTH );
  254. if ( psd == NULL ) {
  255. ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psd failed") );
  256. MEMFREE( pacl );
  257. MEMFREE( psa );
  258. return NULL;
  259. }
  260. if ( ! InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION ) ) {
  261. ERROROUT( TEXT("CreateSecurityAttributes:InitializeSecurityDescriptor failed") );
  262. MEMFREE( pacl );
  263. MEMFREE( psa );
  264. MEMFREE( psd );
  265. return NULL;
  266. }
  267. fResult = SetSecurityDescriptorDacl( psd,
  268. TRUE,
  269. pacl,
  270. FALSE );
  271. // The discretionary ACL is referenced by, not copied
  272. // into, the security descriptor. We shouldn't free up ACL
  273. // after the SetSecurityDescriptorDacl call.
  274. if ( ! fResult ) {
  275. ERROROUT( TEXT("CreateSecurityAttributes:SetSecurityDescriptorDacl failed") );
  276. MEMFREE( pacl );
  277. MEMFREE( psa );
  278. MEMFREE( psd );
  279. return NULL;
  280. }
  281. if (!IsValidSecurityDescriptor(psd)) {
  282. WARNOUT( TEXT("CreateSecurityAttributes:IsValidSecurityDescriptor failed!") );
  283. MEMFREE( pacl );
  284. MEMFREE( psa );
  285. MEMFREE( psd );
  286. return NULL;
  287. }
  288. //
  289. // everything is done
  290. //
  291. psa->nLength = sizeof( SECURITY_ATTRIBUTES );
  292. psa->lpSecurityDescriptor = (PVOID)psd;
  293. psa->bInheritHandle = FALSE;
  294. return psa;
  295. }
  296. PSID MyCreateSid( DWORD dwSubAuthority )
  297. {
  298. PSID psid;
  299. BOOL fResult;
  300. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
  301. //
  302. // allocate and initialize an SID
  303. //
  304. fResult = AllocateAndInitializeSid( &SidAuthority,
  305. 1,
  306. dwSubAuthority,
  307. 0,0,0,0,0,0,0,
  308. &psid );
  309. if ( ! fResult ) {
  310. ERROROUT( TEXT("MyCreateSid:AllocateAndInitializeSid failed") );
  311. return NULL;
  312. }
  313. if ( ! IsValidSid( psid ) ) {
  314. WARNOUT( TEXT("MyCreateSid:AllocateAndInitializeSid returns bogus sid"));
  315. FreeSid( psid );
  316. return NULL;
  317. }
  318. return psid;
  319. }
  320. //
  321. // FreeSecurityAttributes()
  322. //
  323. // The purpose of this function:
  324. //
  325. // Frees the memory objects allocated by previous
  326. // CreateSecurityAttributes() call.
  327. //
  328. VOID FreeSecurityAttributes( PSECURITY_ATTRIBUTES psa )
  329. {
  330. BOOL fResult;
  331. BOOL fDaclPresent;
  332. BOOL fDaclDefaulted;
  333. PACL pacl;
  334. fResult = GetSecurityDescriptorDacl( psa->lpSecurityDescriptor,
  335. &fDaclPresent,
  336. &pacl,
  337. &fDaclDefaulted );
  338. if ( fResult ) {
  339. if ( pacl != NULL )
  340. MEMFREE( pacl );
  341. } else {
  342. ERROROUT( TEXT("FreeSecurityAttributes:GetSecurityDescriptorDacl failed") );
  343. }
  344. MEMFREE( psa->lpSecurityDescriptor );
  345. MEMFREE( psa );
  346. }
  347. #if NOT_USED
  348. //
  349. // Function Below is added to give GENERIC_ALL to everyone for UserDictionary
  350. // which is accessed from network (not interactive).
  351. // 960911 HiroakiK NT #11911
  352. //
  353. //
  354. // CreateSecurityAttributesEx()
  355. //
  356. // The purpose of this function:
  357. //
  358. // Allocate and set the security attributes that is
  359. // appropriate for named objects created by an IME.
  360. // The security attributes will give GENERIC_ALL
  361. // access for everyone
  362. // ^^^^^^^^
  363. //
  364. // Return value:
  365. //
  366. // If the function succeeds, the return value is a
  367. // pointer to SECURITY_ATTRIBUTES. If the function fails,
  368. // the return value is NULL. To get extended error
  369. // information, call GetLastError().
  370. //
  371. // Remarks:
  372. //
  373. // FreeSecurityAttributes() should be called to free up the
  374. // SECURITY_ATTRIBUTES allocated by this function.
  375. //
  376. PSECURITY_ATTRIBUTES CreateSecurityAttributesEx()
  377. {
  378. PSECURITY_ATTRIBUTES psa;
  379. PSECURITY_DESCRIPTOR psd;
  380. PACL pacl;
  381. DWORD cbacl;
  382. PSID psid;
  383. BOOL fResult;
  384. //
  385. // create a sid for everyone access
  386. //
  387. psid = MyCreateSidEx();
  388. if ( psid == NULL ) {
  389. return NULL;
  390. }
  391. //
  392. // allocate and initialize an access control list (ACL) that will
  393. // contain the SID we've just created.
  394. //
  395. cbacl = sizeof(ACL) +
  396. (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
  397. GetLengthSid(psid);
  398. pacl = (PACL)MEMALLOC( cbacl );
  399. if ( pacl == NULL ) {
  400. ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for ACL failed") );
  401. FreeSid ( psid );
  402. return NULL;
  403. }
  404. fResult = InitializeAcl( pacl, cbacl, ACL_REVISION );
  405. if ( ! fResult ) {
  406. ERROROUT( TEXT("CreateSecurityAttributes:InitializeAcl failed") );
  407. FreeSid ( psid );
  408. MEMFREE( pacl );
  409. return NULL;
  410. }
  411. //
  412. // adds an access-allowed ACE for interactive users to the ACL
  413. //
  414. fResult = AddAccessAllowedAce( pacl,
  415. ACL_REVISION,
  416. GENERIC_ALL,
  417. psid );
  418. if ( !fResult ) {
  419. ERROROUT( TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed") );
  420. MEMFREE( pacl );
  421. FreeSid ( psid );
  422. return NULL;
  423. }
  424. //
  425. // Those SIDs have been copied into the ACL. We don't need'em any more.
  426. //
  427. FreeSid ( psid );
  428. //
  429. // Let's make sure that our ACL is valid.
  430. //
  431. if (!IsValidAcl(pacl)) {
  432. WARNOUT( TEXT("CreateSecurityAttributes:IsValidAcl returns fFalse!"));
  433. MEMFREE( pacl );
  434. return NULL;
  435. }
  436. //
  437. // allocate security attribute
  438. //
  439. psa = (PSECURITY_ATTRIBUTES)MEMALLOC( sizeof( SECURITY_ATTRIBUTES ) );
  440. if ( psa == NULL ) {
  441. ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psa failed") );
  442. MEMFREE( pacl );
  443. return NULL;
  444. }
  445. //
  446. // allocate and initialize a new security descriptor
  447. //
  448. psd = MEMALLOC( SECURITY_DESCRIPTOR_MIN_LENGTH );
  449. if ( psd == NULL ) {
  450. ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psd failed") );
  451. MEMFREE( pacl );
  452. MEMFREE( psa );
  453. return NULL;
  454. }
  455. if ( ! InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION ) ) {
  456. ERROROUT( TEXT("CreateSecurityAttributes:InitializeSecurityDescriptor failed") );
  457. MEMFREE( pacl );
  458. MEMFREE( psa );
  459. MEMFREE( psd );
  460. return NULL;
  461. }
  462. fResult = SetSecurityDescriptorDacl( psd,
  463. TRUE,
  464. pacl,
  465. FALSE );
  466. // The discretionary ACL is referenced by, not copied
  467. // into, the security descriptor. We shouldn't free up ACL
  468. // after the SetSecurityDescriptorDacl call.
  469. if ( ! fResult ) {
  470. ERROROUT( TEXT("CreateSecurityAttributes:SetSecurityDescriptorDacl failed") );
  471. MEMFREE( pacl );
  472. MEMFREE( psa );
  473. MEMFREE( psd );
  474. return NULL;
  475. }
  476. if (!IsValidSecurityDescriptor(psd)) {
  477. WARNOUT( TEXT("CreateSecurityAttributes:IsValidSecurityDescriptor failed!") );
  478. MEMFREE( pacl );
  479. MEMFREE( psa );
  480. MEMFREE( psd );
  481. return NULL;
  482. }
  483. //
  484. // everything is done
  485. //
  486. psa->nLength = sizeof( SECURITY_ATTRIBUTES );
  487. psa->lpSecurityDescriptor = (PVOID)psd;
  488. psa->bInheritHandle = FALSE;
  489. return psa;
  490. }
  491. PSID MyCreateSidEx(VOID)
  492. {
  493. PSID psid;
  494. BOOL fResult;
  495. SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_WORLD_SID_AUTHORITY;
  496. //
  497. // allocate and initialize an SID
  498. //
  499. fResult = AllocateAndInitializeSid( &SidAuthority,
  500. 1,
  501. SECURITY_WORLD_RID,
  502. 0,0,0,0,0,0,0,
  503. &psid );
  504. if ( ! fResult ) {
  505. ERROROUT( TEXT("MyCreateSid:AllocateAndInitializeSid failed") );
  506. return NULL;
  507. }
  508. if ( ! IsValidSid( psid ) ) {
  509. WARNOUT( TEXT("MyCreateSid:AllocateAndInitializeSid returns bogus sid"));
  510. FreeSid( psid );
  511. return NULL;
  512. }
  513. return psid;
  514. }
  515. #endif