windows-nt/Source/XPSP1/NT/windows/feime/cht/immsec.c
2020-09-26 16:20:57 +08:00

334 lines
7.9 KiB
C

/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
immsec.c
Abstract:
security code called by IMEs
Author:
Takao Kitano [takaok] 01-May-1996
Revision History:
--*/
#include <windows.h>
#include <stdio.h>
#include "immsec.h"
#define MEMALLOC(x) LocalAlloc(LMEM_FIXED, x)
#define MEMFREE(x) LocalFree(x)
//
// internal functions
//
PSID MyCreateSid();
POSVERSIONINFO GetVersionInfo();
//
// debug functions
//
#ifdef DEBUG
#define ERROROUT(x) ErrorOut( x )
#define WARNOUT(x) WarnOut( x )
#else
#define ERROROUT(x)
#define WARNOUT(x)
#endif
#ifdef DEBUG
VOID WarnOut( PTSTR pStr )
{
OutputDebugString( pStr );
}
VOID ErrorOut( PTSTR pStr )
{
DWORD dwError;
DWORD dwResult;
TCHAR buf1[512];
TCHAR buf2[512];
dwError = GetLastError();
dwResult = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID( LANG_ENGLISH, LANG_NEUTRAL ),
buf1,
512,
NULL );
if ( dwResult > 0 ) {
sprintf( buf2, "%s:%s(0x%x)", pStr, buf1, dwError);
} else {
sprintf( buf2, "%s:(0x%x)", pStr, dwError);
}
OutputDebugString( buf2 );
}
#endif
//
// CreateSecurityAttributes()
//
// The purpose of this function:
//
// Allocate and set the security attributes that is
// appropriate for named objects created by an IME.
// The security attributes will give GENERIC_ALL
// access for everyone
//
//
// Return value:
//
// If the function succeeds, the return value is a
// pointer to SECURITY_ATTRIBUTES. If the function fails,
// the return value is NULL. To get extended error
// information, call GetLastError().
//
// Remarks:
//
// FreeSecurityAttributes() should be called to free up the
// SECURITY_ATTRIBUTES allocated by this function.
//
PSECURITY_ATTRIBUTES CreateSecurityAttributes()
{
PSECURITY_ATTRIBUTES psa;
PSECURITY_DESCRIPTOR psd;
PACL pacl;
DWORD cbacl;
PSID psid;
BOOL fResult;
INT i,j;
if (!IsNT())
return NULL;
//
// create a sid for everyone access
//
psid = MyCreateSid();
if ( psid == NULL ) {
return NULL;
}
//
// allocate and initialize an access control list (ACL) that will
// contain the SID we've just created.
//
cbacl = sizeof(ACL) +
(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
GetLengthSid(psid);
pacl = MEMALLOC( cbacl );
if ( pacl == NULL ) {
ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for ACL failed") );
FreeSid ( psid );
return NULL;
}
fResult = InitializeAcl( pacl, cbacl, ACL_REVISION );
if ( ! fResult ) {
ERROROUT( TEXT("CreateSecurityAttributes:InitializeAcl failed") );
FreeSid ( psid );
MEMFREE( pacl );
return NULL;
}
//
// adds an access-allowed ACE for interactive users to the ACL
//
fResult = AddAccessAllowedAce( pacl,
ACL_REVISION,
GENERIC_ALL,
psid );
if ( !fResult ) {
ERROROUT( TEXT("CreateSecurityAttributes:AddAccessAllowedAce failed") );
MEMFREE( pacl );
FreeSid ( psid );
return NULL;
}
//
// Those SIDs have been copied into the ACL. We don't need'em any more.
//
FreeSid ( psid );
//
// Let's make sure that our ACL is valid.
//
if (!IsValidAcl(pacl)) {
WARNOUT( TEXT("CreateSecurityAttributes:IsValidAcl returns FALSE!"));
MEMFREE( pacl );
return NULL;
}
//
// allocate security attribute
//
psa = (PSECURITY_ATTRIBUTES)MEMALLOC( sizeof( SECURITY_ATTRIBUTES ) );
if ( psa == NULL ) {
ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psa failed") );
MEMFREE( pacl );
return NULL;
}
//
// allocate and initialize a new security descriptor
//
psd = MEMALLOC( SECURITY_DESCRIPTOR_MIN_LENGTH );
if ( psd == NULL ) {
ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psd failed") );
MEMFREE( pacl );
MEMFREE( psa );
return NULL;
}
if ( ! InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION ) ) {
ERROROUT( TEXT("CreateSecurityAttributes:InitializeSecurityDescriptor failed") );
MEMFREE( pacl );
MEMFREE( psa );
MEMFREE( psd );
return NULL;
}
fResult = SetSecurityDescriptorDacl( psd,
TRUE,
pacl,
FALSE );
// The discretionary ACL is referenced by, not copied
// into, the security descriptor. We shouldn't free up ACL
// after the SetSecurityDescriptorDacl call.
if ( ! fResult ) {
ERROROUT( TEXT("CreateSecurityAttributes:SetSecurityDescriptorDacl failed") );
MEMFREE( pacl );
MEMFREE( psa );
MEMFREE( psd );
return NULL;
}
if (!IsValidSecurityDescriptor(psd)) {
WARNOUT( TEXT("CreateSecurityAttributes:IsValidSecurityDescriptor failed!") );
MEMFREE( pacl );
MEMFREE( psa );
MEMFREE( psd );
return NULL;
}
//
// everything is done
//
psa->nLength = sizeof( SECURITY_ATTRIBUTES );
psa->lpSecurityDescriptor = (PVOID)psd;
psa->bInheritHandle = FALSE;
return psa;
}
PSID MyCreateSid()
{
PSID psid;
BOOL fResult;
SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_WORLD_SID_AUTHORITY;
//
// allocate and initialize an SID
//
fResult = AllocateAndInitializeSid( &SidAuthority,
1,
SECURITY_WORLD_RID,
0,0,0,0,0,0,0,
&psid );
if ( ! fResult ) {
ERROROUT( TEXT("MyCreateSid:AllocateAndInitializeSid failed") );
return NULL;
}
if ( ! IsValidSid( psid ) ) {
WARNOUT( TEXT("MyCreateSid:AllocateAndInitializeSid returns bogus sid"));
FreeSid( psid );
return NULL;
}
return psid;
}
//
// FreeSecurityAttributes()
//
// The purpose of this function:
//
// Frees the memory objects allocated by previous
// CreateSecurityAttributes() call.
//
VOID FreeSecurityAttributes( PSECURITY_ATTRIBUTES psa )
{
BOOL fResult;
BOOL fDaclPresent;
BOOL fDaclDefaulted;
PACL pacl;
if (psa == NULL)
return;
fResult = GetSecurityDescriptorDacl( psa->lpSecurityDescriptor,
&fDaclPresent,
&pacl,
&fDaclDefaulted );
if ( fResult ) {
if ( pacl != NULL )
MEMFREE( pacl );
} else {
ERROROUT( TEXT("FreeSecurityAttributes:GetSecurityDescriptorDacl failed") );
}
MEMFREE( psa->lpSecurityDescriptor );
MEMFREE( psa );
}
//
// IsNT()
//
// Return value:
//
// TRUE if the current system is Windows NT
//
// Remarks:
//
// The implementation of this function is not multi-thread safe.
// You need to modify the function if you call the function in
// multi-thread environment.
//
BOOL IsNT()
{
return GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_NT;
}
POSVERSIONINFO GetVersionInfo()
{
static BOOL fFirstCall = TRUE;
static OSVERSIONINFO os;
if ( fFirstCall ) {
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if ( GetVersionEx( &os ) ) {
fFirstCall = FALSE;
}
}
return &os;
}