791 lines
20 KiB
C
791 lines
20 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991-1994 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
logclear.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Contains functions used to log an event indicating who cleared the log.
|
|||
|
This is only called after the security log has been cleared.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Dan Lafferty (danl) 01-July-1994
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User Mode -Win32
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
01-July-1994 danl & robertre
|
|||
|
Created - Rob supplied the code which I fitted into the eventlog.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <nt.h>
|
|||
|
#include <ntrtl.h>
|
|||
|
#include <nturtl.h>
|
|||
|
#include <windows.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <msaudite.h>
|
|||
|
#include <eventp.h>
|
|||
|
#include <tstr.h>
|
|||
|
#include <winsock2.h>
|
|||
|
|
|||
|
#define NUM_STRINGS 6
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// LOCAL FUNCTION PROTOTYPES
|
|||
|
//
|
|||
|
BOOL
|
|||
|
GetUserInfo(
|
|||
|
IN HANDLE Token,
|
|||
|
OUT LPWSTR *UserName,
|
|||
|
OUT LPWSTR *DomainName,
|
|||
|
OUT LPWSTR *AuthenticationId,
|
|||
|
OUT PSID *UserSid
|
|||
|
);
|
|||
|
|
|||
|
LPWSTR
|
|||
|
ElfpGetComputerName(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
LPWSTR
|
|||
|
GetNameFromIPAddress(
|
|||
|
LPWSTR pszComputerNameFromBinding);
|
|||
|
|
|||
|
BOOL
|
|||
|
IsLocal(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
ElfpGenerateLogClearedEvent(
|
|||
|
IELF_HANDLE LogHandle
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function generates an event indicating that the log was cleared.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
LogHandle -- This is a handle to the log that the event is to be placed in.
|
|||
|
It is intended that this function only be called when the SecurityLog
|
|||
|
has been cleared. So it is expected the LogHandle will always be
|
|||
|
a handle to the security log.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None -- Either it works or it doesn't. If it doesn't, there isn't much
|
|||
|
we can do about it.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LPWSTR UserName = NULL;
|
|||
|
LPWSTR DomainName = NULL;
|
|||
|
LPWSTR AuthenticationId = NULL;
|
|||
|
LPWSTR ClientUserName = NULL;
|
|||
|
LPWSTR ClientDomainName = NULL;
|
|||
|
LPWSTR ClientAuthenticationId = NULL;
|
|||
|
PSID UserSid = NULL;
|
|||
|
PSID ClientSid = NULL;
|
|||
|
LPWSTR ComputerName = NULL;
|
|||
|
DWORD i;
|
|||
|
BOOL Result;
|
|||
|
HANDLE Token;
|
|||
|
PUNICODE_STRING StringPtrArray[NUM_STRINGS];
|
|||
|
UNICODE_STRING StringArray[NUM_STRINGS];
|
|||
|
NTSTATUS Status;
|
|||
|
LARGE_INTEGER Time;
|
|||
|
ULONG EventTime;
|
|||
|
ULONG LogHandleGrantedAccess;
|
|||
|
UNICODE_STRING ComputerNameU;
|
|||
|
DWORD dwStatus;
|
|||
|
|
|||
|
//
|
|||
|
// Get information about the Eventlog service (i.e., LocalSystem)
|
|||
|
//
|
|||
|
Result = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGenerateLogClearedEvent: OpenProcessToken failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
Result = GetUserInfo(Token,
|
|||
|
&UserName,
|
|||
|
&DomainName,
|
|||
|
&AuthenticationId,
|
|||
|
&UserSid);
|
|||
|
|
|||
|
CloseHandle(Token);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGenerateLogClearedEvent: GetUserInfo failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
ELF_LOG3(TRACE,
|
|||
|
"ElfpGenerateLogClearedEvent: GetUserInfo returned: \n"
|
|||
|
"\tUserName = %ws,\n"
|
|||
|
"\tDomainName = %ws,\n"
|
|||
|
"\tAuthenticationId = %ws\n",
|
|||
|
UserName,
|
|||
|
DomainName,
|
|||
|
AuthenticationId);
|
|||
|
|
|||
|
//
|
|||
|
// Now impersonate in order to get the client's information.
|
|||
|
// This call should never fail.
|
|||
|
//
|
|||
|
dwStatus = RpcImpersonateClient(NULL);
|
|||
|
|
|||
|
if (dwStatus != RPC_S_OK)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGenerateLogClearedEvent: RpcImpersonateClient failed %d\n",
|
|||
|
dwStatus);
|
|||
|
goto CleanExit;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
Result = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &Token);
|
|||
|
|
|||
|
if (Result)
|
|||
|
{
|
|||
|
Result = GetUserInfo(Token,
|
|||
|
&ClientUserName,
|
|||
|
&ClientDomainName,
|
|||
|
&ClientAuthenticationId,
|
|||
|
&ClientSid);
|
|||
|
|
|||
|
CloseHandle(Token);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGenerateLogClearedEvent: GetUserInfo (call 2) failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
goto CleanExit;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// We're impersonating here, so this should never
|
|||
|
// happen but just in case, use dashes
|
|||
|
//
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGenerateLogClearedEvent: OpenThreadToken failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
ASSERT(FALSE);
|
|||
|
|
|||
|
ClientUserName = L"-";
|
|||
|
ClientDomainName = L"-";
|
|||
|
ClientAuthenticationId = L"-";
|
|||
|
}
|
|||
|
|
|||
|
ELF_LOG3(TRACE,
|
|||
|
"ElfpGenerateLogClearedEvent: GetUserInfo (call 2) returned: \n"
|
|||
|
"\tUserName = %ws,\n"
|
|||
|
"\tDomainName = %ws,\n"
|
|||
|
"\tAuthenticationId = %ws\n",
|
|||
|
ClientUserName,
|
|||
|
ClientDomainName,
|
|||
|
ClientAuthenticationId);
|
|||
|
|
|||
|
RtlInitUnicodeString(&StringArray[0], UserName);
|
|||
|
RtlInitUnicodeString(&StringArray[1], DomainName);
|
|||
|
RtlInitUnicodeString(&StringArray[2], AuthenticationId);
|
|||
|
RtlInitUnicodeString(&StringArray[3], ClientUserName);
|
|||
|
RtlInitUnicodeString(&StringArray[4], ClientDomainName);
|
|||
|
RtlInitUnicodeString(&StringArray[5], ClientAuthenticationId);
|
|||
|
|
|||
|
//
|
|||
|
// Create an array of pointers to UNICODE_STRINGs.
|
|||
|
//
|
|||
|
for (i = 0; i < NUM_STRINGS; i++)
|
|||
|
{
|
|||
|
StringPtrArray[i] = &StringArray[i];
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Generate the time of the event. This is done on the client side
|
|||
|
// since that is where the event occurred.
|
|||
|
//
|
|||
|
NtQuerySystemTime(&Time);
|
|||
|
RtlTimeToSecondsSince1970(&Time, &EventTime);
|
|||
|
|
|||
|
//
|
|||
|
// Generate the ComputerName of the client.
|
|||
|
// We have to do this in the client side since this call may be
|
|||
|
// remoted to another server and we would not necessarily have
|
|||
|
// the computer name there.
|
|||
|
//
|
|||
|
|
|||
|
ComputerName = ElfpGetComputerName();
|
|||
|
if(ComputerName == NULL)
|
|||
|
goto CleanExit; // ElfpGetComputerName dumps error msg
|
|||
|
RtlInitUnicodeString(&ComputerNameU, ComputerName);
|
|||
|
|
|||
|
//
|
|||
|
// Since all processes other than LSA are given read-only access
|
|||
|
// to the security log, we have to explicitly give the current
|
|||
|
// process the right to write the "Log cleared" event
|
|||
|
//
|
|||
|
LogHandleGrantedAccess = LogHandle->GrantedAccess;
|
|||
|
LogHandle->GrantedAccess |= ELF_LOGFILE_WRITE;
|
|||
|
|
|||
|
Status = ElfrReportEventW (
|
|||
|
LogHandle, // Log Handle
|
|||
|
EventTime, // Time
|
|||
|
EVENTLOG_AUDIT_SUCCESS, // Event Type
|
|||
|
(USHORT)SE_CATEGID_SYSTEM, // Event Category
|
|||
|
SE_AUDITID_AUDIT_LOG_CLEARED, // EventID
|
|||
|
NUM_STRINGS, // NumStrings
|
|||
|
0, // DataSize
|
|||
|
&ComputerNameU, // ComputerNameU
|
|||
|
UserSid, // UserSid
|
|||
|
StringPtrArray, // *Strings
|
|||
|
NULL, // Data
|
|||
|
0, // Flags
|
|||
|
NULL, // RecordNumber
|
|||
|
NULL); // TimeWritten
|
|||
|
|
|||
|
LogHandle->GrantedAccess = LogHandleGrantedAccess;
|
|||
|
|
|||
|
CleanExit:
|
|||
|
|
|||
|
//
|
|||
|
// We only come down this path if we know for sure that these
|
|||
|
// first three have been allocated.
|
|||
|
//
|
|||
|
ElfpFreeBuffer(UserName);
|
|||
|
ElfpFreeBuffer(DomainName);
|
|||
|
ElfpFreeBuffer(AuthenticationId);
|
|||
|
|
|||
|
ElfpFreeBuffer(UserSid);
|
|||
|
ElfpFreeBuffer(ClientUserName);
|
|||
|
ElfpFreeBuffer(ClientDomainName);
|
|||
|
ElfpFreeBuffer(ClientAuthenticationId);
|
|||
|
ElfpFreeBuffer(ClientSid);
|
|||
|
ElfpFreeBuffer(ComputerName);
|
|||
|
//
|
|||
|
// Stop impersonating
|
|||
|
//
|
|||
|
dwStatus = RpcRevertToSelf();
|
|||
|
|
|||
|
if (dwStatus != RPC_S_OK)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGenerateLogClearedEvent: RpcRevertToSelf failed %d\n",
|
|||
|
GetLastError());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
GetUserInfo(
|
|||
|
IN HANDLE Token,
|
|||
|
OUT LPWSTR *UserName,
|
|||
|
OUT LPWSTR *DomainName,
|
|||
|
OUT LPWSTR *AuthenticationId,
|
|||
|
OUT PSID *UserSid
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function gathers information about the user identified with the
|
|||
|
token.
|
|||
|
|
|||
|
Arguments:
|
|||
|
Token - This token identifies the entity for which we are gathering
|
|||
|
information.
|
|||
|
UserName - This is the entity's user name.
|
|||
|
DomainName - This is the entity's domain name.
|
|||
|
AuthenticationId - This is the entity's Authentication ID.
|
|||
|
UserSid - This is the entity's SID.
|
|||
|
|
|||
|
NOTE:
|
|||
|
Memory is allocated by this routine for UserName, DomainName,
|
|||
|
AuthenticationId, and UserSid. It is the caller's responsibility to
|
|||
|
free this memory.
|
|||
|
|
|||
|
Return Value:
|
|||
|
TRUE - If the operation was successful. It is possible that
|
|||
|
UserSid did not get allocated in the successful case. Therefore,
|
|||
|
the caller should test prior to freeing.
|
|||
|
FALSE - If unsuccessful. No memory is allocated in this case.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PTOKEN_USER Buffer = NULL;
|
|||
|
LPWSTR Domain = NULL;
|
|||
|
LPWSTR AccountName = NULL;
|
|||
|
SID_NAME_USE Use;
|
|||
|
BOOL Result;
|
|||
|
DWORD RequiredLength;
|
|||
|
DWORD AccountNameSize;
|
|||
|
DWORD DomainNameSize;
|
|||
|
TOKEN_STATISTICS Statistics;
|
|||
|
WCHAR LogonIdString[256];
|
|||
|
DWORD Status = ERROR_SUCCESS;
|
|||
|
|
|||
|
|
|||
|
*UserSid = NULL;
|
|||
|
|
|||
|
Result = GetTokenInformation(Token, TokenUser, NULL, 0, &RequiredLength);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|||
|
{
|
|||
|
ELF_LOG1(TRACE,
|
|||
|
"GetUserInfo: GetTokenInformation needs %d bytes\n",
|
|||
|
RequiredLength);
|
|||
|
|
|||
|
Buffer = ElfpAllocateBuffer(RequiredLength);
|
|||
|
|
|||
|
if (Buffer == NULL)
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"GetUserInfo: Unable to allocate memory for token\n");
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
Result = GetTokenInformation(Token,
|
|||
|
TokenUser,
|
|||
|
Buffer,
|
|||
|
RequiredLength,
|
|||
|
&RequiredLength);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: GetTokenInformation (call 2) failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: GetTokenInformation (call 1) failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
AccountNameSize = 0;
|
|||
|
DomainNameSize = 0;
|
|||
|
|
|||
|
Result = LookupAccountSidW(L"",
|
|||
|
Buffer->User.Sid,
|
|||
|
NULL,
|
|||
|
&AccountNameSize,
|
|||
|
NULL,
|
|||
|
&DomainNameSize,
|
|||
|
&Use);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|||
|
{
|
|||
|
AccountName = ElfpAllocateBuffer((AccountNameSize + 1) * sizeof(WCHAR));
|
|||
|
Domain = ElfpAllocateBuffer((DomainNameSize + 1) * sizeof(WCHAR));
|
|||
|
|
|||
|
if (AccountName == NULL)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: Unable to allocate %d bytes for AccountName\n",
|
|||
|
AccountNameSize);
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
|
|||
|
if (Domain == NULL)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: Unable to allocate %d bytes for Domain\n",
|
|||
|
DomainNameSize);
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
|
|||
|
Result = LookupAccountSidW(L"",
|
|||
|
Buffer->User.Sid,
|
|||
|
AccountName,
|
|||
|
&AccountNameSize,
|
|||
|
Domain,
|
|||
|
&DomainNameSize,
|
|||
|
&Use
|
|||
|
);
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: LookupAccountSid (call 2) failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: LookupAccountsid (call 1) failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"GetUserInfo: LookupAccountSid succeeded unexpectedly\n");
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
|
|||
|
ELF_LOG2(TRACE,
|
|||
|
"GetUserInfo: Name = %ws\\%ws\n",
|
|||
|
Domain,
|
|||
|
AccountName);
|
|||
|
|
|||
|
Result = GetTokenInformation(Token,
|
|||
|
TokenStatistics,
|
|||
|
&Statistics,
|
|||
|
sizeof(Statistics),
|
|||
|
&RequiredLength);
|
|||
|
|
|||
|
if (!Result)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"GetUserInfo: GetTokenInformation (call 3) failed %d\n",
|
|||
|
GetLastError());
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
|
|||
|
swprintf(LogonIdString,
|
|||
|
L"(0x%X,0x%X)",
|
|||
|
Statistics.AuthenticationId.HighPart,
|
|||
|
Statistics.AuthenticationId.LowPart);
|
|||
|
|
|||
|
ELF_LOG1(TRACE,
|
|||
|
"GetUserInfo: LogonIdString = %ws\n",
|
|||
|
LogonIdString);
|
|||
|
|
|||
|
*AuthenticationId = ElfpAllocateBuffer(WCSSIZE(LogonIdString));
|
|||
|
|
|||
|
if (*AuthenticationId == NULL)
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"GetUserInfo: Unable to allocate memory for AuthenticationId\n");
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
|
|||
|
wcscpy(*AuthenticationId, LogonIdString);
|
|||
|
|
|||
|
//
|
|||
|
// Return accumulated information
|
|||
|
//
|
|||
|
*UserSid = ElfpAllocateBuffer(GetLengthSid(Buffer->User.Sid));
|
|||
|
|
|||
|
if (*UserSid == NULL)
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"GetUserInfo: Unable to allocate memory for UserSid\n");
|
|||
|
|
|||
|
goto ErrorCleanup;
|
|||
|
}
|
|||
|
|
|||
|
Result = CopySid(GetLengthSid(Buffer->User.Sid),
|
|||
|
*UserSid,
|
|||
|
Buffer->User.Sid);
|
|||
|
|
|||
|
ElfpFreeBuffer(Buffer);
|
|||
|
|
|||
|
*DomainName = Domain;
|
|||
|
*UserName = AccountName;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
ErrorCleanup:
|
|||
|
|
|||
|
ElfpFreeBuffer(Buffer);
|
|||
|
ElfpFreeBuffer(Domain);
|
|||
|
ElfpFreeBuffer(AccountName);
|
|||
|
ElfpFreeBuffer(*UserSid);
|
|||
|
ElfpFreeBuffer(*AuthenticationId);
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
LPWSTR
|
|||
|
GetNameFromIPAddress(
|
|||
|
LPWSTR pszComputerNameFromBinding)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Examines a string and determines if it looks like an ip address. If it
|
|||
|
does, then it converts it to a fqdn
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Machine name: Could be xxx.xxx.xxx.xxx or anything else!
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
If successful, returns a fully qualified domain name which the caller
|
|||
|
will free. Returns NULL if there are any problems.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
LPWSTR pComputerName = NULL;
|
|||
|
DWORD dwAddr;
|
|||
|
char cName[17]; // should be plenty of room
|
|||
|
size_t NumConv;
|
|||
|
HOSTENT FAR * pEnt;
|
|||
|
DWORD dwSize;
|
|||
|
WORD wVersionRequested;
|
|||
|
WSADATA wsaData;
|
|||
|
int error;
|
|||
|
|
|||
|
NumConv = wcstombs(cName, pszComputerNameFromBinding, 16);
|
|||
|
if(NumConv == -1 || NumConv == 0)
|
|||
|
return NULL;
|
|||
|
|
|||
|
// convert the string into a network order dword representation
|
|||
|
|
|||
|
dwAddr = inet_addr(cName);
|
|||
|
if(dwAddr == INADDR_NONE)
|
|||
|
return NULL;
|
|||
|
|
|||
|
// initialize sockets.
|
|||
|
|
|||
|
wVersionRequested = MAKEWORD( 2, 2 );
|
|||
|
|
|||
|
error = WSAStartup( wVersionRequested, &wsaData );
|
|||
|
if(error != 0)
|
|||
|
{
|
|||
|
ELF_LOG1(TRACE,
|
|||
|
"GetNameFromIPAddress: failed to initialize sockets, error = 0x%x\n", error);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
pEnt = gethostbyaddr((char FAR *)&dwAddr, 4, PF_INET);
|
|||
|
if(pEnt == NULL || pEnt->h_name == NULL)
|
|||
|
{
|
|||
|
ELF_LOG1(TRACE,
|
|||
|
"GetNameFromIPAddress: failed gethostbyaddr, error = 0x%x\n",
|
|||
|
WSAGetLastError());
|
|||
|
WSACleanup();
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
dwSize = strlen(pEnt->h_name) + 1 ;
|
|||
|
pComputerName = ElfpAllocateBuffer(2*dwSize);
|
|||
|
if(pComputerName == NULL)
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"GetNameFromIPAddress: failed trying to allocate memory\n");
|
|||
|
WSACleanup();
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
pComputerName[0] = 0;
|
|||
|
mbstowcs(pComputerName, pEnt->h_name, dwSize);
|
|||
|
WSACleanup();
|
|||
|
return pComputerName;
|
|||
|
}
|
|||
|
|
|||
|
BOOL
|
|||
|
IsLocal(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines if the caller is local.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NONE
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if definately local.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
UINT LocalFlag;
|
|||
|
RPC_STATUS RpcStatus;
|
|||
|
RpcStatus = I_RpcBindingIsClientLocal(0, &LocalFlag);
|
|||
|
|
|||
|
if( RpcStatus != RPC_S_OK )
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"IsLocal: I_RpcBindingIsClientLocal failed %d\n",
|
|||
|
RpcStatus);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
if(LocalFlag == 0)
|
|||
|
return FALSE;
|
|||
|
else
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
LPWSTR
|
|||
|
ElfpGetComputerName(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine gets the LPWSTR name of the computer.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NONE
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns a pointer to the computer name, or a NULL. Note that the caller
|
|||
|
is expected to free this via
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
RPC_STATUS RpcStatus;
|
|||
|
handle_t hServerBinding = NULL;
|
|||
|
LPWSTR pszBinding = NULL;
|
|||
|
LPWSTR pszComputerNameFromBinding = NULL;
|
|||
|
LPWSTR pszComputerName = NULL;
|
|||
|
DWORD dwSize;
|
|||
|
BOOL bOK;
|
|||
|
|
|||
|
// Check if the connection is local. If it is, then just
|
|||
|
// call GetComputerName
|
|||
|
|
|||
|
if(IsLocal())
|
|||
|
{
|
|||
|
dwSize = MAX_COMPUTERNAME_LENGTH + 1 ;
|
|||
|
pszComputerName = ElfpAllocateBuffer(2*dwSize);
|
|||
|
if(pszComputerName == NULL)
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"ElfpGetComputerName: failed trying to allocate memory\n");
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
bOK = GetComputerNameW(pszComputerName, &dwSize);
|
|||
|
if(bOK == FALSE)
|
|||
|
{
|
|||
|
ElfpFreeBuffer(pszComputerName);
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGetComputerName: failed calling GetComputerNameW, last error 0x%x\n",
|
|||
|
GetLastError());
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
return pszComputerName;
|
|||
|
}
|
|||
|
|
|||
|
RpcStatus = RpcBindingServerFromClient( NULL, &hServerBinding );
|
|||
|
if( RpcStatus != RPC_S_OK )
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGetComputerName: RpcBindingServerFromClient failed %d\n",
|
|||
|
RpcStatus);
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
// This gets us something like "ncacn_np:xxx.xxx.xxx.xxx" or
|
|||
|
// "ncacn_np:localMachine"
|
|||
|
|
|||
|
RpcStatus = RpcBindingToStringBinding( hServerBinding, &pszBinding );
|
|||
|
if( RpcStatus != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGetComputerName: RpcBindingToStringBinding failed %d\n",
|
|||
|
RpcStatus);
|
|||
|
goto CleanExitGetCompName;
|
|||
|
}
|
|||
|
|
|||
|
// Acquire just the network address. That will be something like
|
|||
|
// "xxx.xxx.xxx.xxx" or "mymachine"
|
|||
|
|
|||
|
RpcStatus = RpcStringBindingParse( pszBinding,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
&pszComputerNameFromBinding,
|
|||
|
NULL,
|
|||
|
NULL );
|
|||
|
if( RpcStatus != ERROR_SUCCESS || pszComputerNameFromBinding == NULL)
|
|||
|
{
|
|||
|
ELF_LOG1(ERROR,
|
|||
|
"ElfpGetComputerName: RpcStringBindingParse failed %d\n",
|
|||
|
RpcStatus);
|
|||
|
goto CleanExitGetCompName;
|
|||
|
}
|
|||
|
|
|||
|
// sometimes the name is an ip address. If it is, then the following determines
|
|||
|
// that and returns the right string.
|
|||
|
|
|||
|
pszComputerName = GetNameFromIPAddress(pszComputerNameFromBinding);
|
|||
|
if(pszComputerName == NULL)
|
|||
|
{
|
|||
|
dwSize = wcslen(pszComputerNameFromBinding) + 1;
|
|||
|
pszComputerName = ElfpAllocateBuffer(2*dwSize);
|
|||
|
if(pszComputerName == NULL)
|
|||
|
{
|
|||
|
ELF_LOG0(ERROR,
|
|||
|
"ElfpGetComputerName: failed trying to allocate memory\n");
|
|||
|
}
|
|||
|
else
|
|||
|
wcscpy(pszComputerName, pszComputerNameFromBinding);
|
|||
|
}
|
|||
|
|
|||
|
CleanExitGetCompName:
|
|||
|
if(hServerBinding)
|
|||
|
RpcStatus = RpcBindingFree(&hServerBinding);
|
|||
|
if(pszBinding)
|
|||
|
RpcStatus = RpcStringFree(&pszBinding);
|
|||
|
if(pszComputerNameFromBinding)
|
|||
|
RpcStatus = RpcStringFree(&pszComputerNameFromBinding);
|
|||
|
return pszComputerName;
|
|||
|
}
|