DWORD RPCAllocateString( PCSTR pszInputString, PSTR* ppszOutputString ) { DWORD dwError = 0; DWORD dwLen = 0; char * pszOutputString = NULL; if (!pszInputString || !*pszInputString){ dwError = EINVAL; BAIL_ON_EVT_ERROR(dwError); } dwLen = (DWORD)strlen(pszInputString); dwError = RPCAllocateMemory(dwLen+1, (PVOID *)&pszOutputString); BAIL_ON_EVT_ERROR(dwError); strcpy(pszOutputString, pszInputString); error: *ppszOutputString = pszOutputString; return(dwError); }
DWORD LwmEvtOpenServer( PLW_EVT_CLIENT_CONNECTION_CONTEXT* ppConn ) { DWORD dwError = 0; if (!ppConn) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_EVT_ERROR(dwError); } pthread_once(&gOnceControl, LwmEvtOpenServerOnce); dwError = gdwOnceError; BAIL_ON_EVT_ERROR(dwError); *ppConn = &gContext; cleanup: return dwError; error: if (ppConn) { *ppConn = NULL; } goto cleanup; }
static DWORD LwmEvtSrvCreateError( DWORD ErrorCode, PCWSTR pErrorMessage, PEVT_IPC_GENERIC_ERROR* ppError ) { DWORD dwError = 0; PEVT_IPC_GENERIC_ERROR pError = NULL; dwError = LwAllocateMemory(sizeof(*pError), (PVOID*) &pError); BAIL_ON_EVT_ERROR(dwError); if (pErrorMessage) { dwError = LwAllocateWc16String( (PWSTR*)&pError->pErrorMessage, pErrorMessage); BAIL_ON_EVT_ERROR(dwError); } pError->Error = ErrorCode; *ppError = pError; error: return dwError; }
DWORD LwmEvtSrvDeleteRecords( LWMsgCall* pCall, const LWMsgParams* pIn, LWMsgParams* pOut, void* data ) { DWORD dwError = 0; PCWSTR pFilter = pIn->data; PEVT_IPC_GENERIC_ERROR pError = NULL; sqlite3 *pDb = NULL; PLWMSG_LW_EVENTLOG_CONNECTION pConn = NULL; dwError = LwmEvtSrvGetConnection( pCall, &pConn); if (dwError) { } else if (!pConn->WriteAllowed) { dwError = ERROR_ACCESS_DENIED; } else { dwError = LwEvtDbOpen(&pDb); BAIL_ON_EVT_ERROR(dwError); dwError = LwEvtDbDeleteRecords( pDb, pFilter); } if (!dwError) { pOut->tag = EVT_R_GENERIC_SUCCESS; pOut->data = NULL; } else { dwError = LwmEvtSrvCreateError(dwError, NULL, &pError); BAIL_ON_EVT_ERROR(dwError); pOut->tag = EVT_R_GENERIC_ERROR; pOut->data = pError; } cleanup: if (pDb != NULL) { LwEvtDbClose(pDb); } return MAP_LW_ERROR_IPC(dwError); error: goto cleanup; }
int main( int argc, char* argv[] ) { DWORD dwError = 0; handle_t bindingHandle = 0; HANDLE hEventLog = 0; PSTR pszBindingString = NULL; DWORD eventTableCategoryId = (DWORD) -1; PSTR pszFilename = NULL; evt_init_logging_to_file(LOG_LEVEL_VERBOSE, ""); dwError = ParseArgs(argc, argv, &pszFilename, &eventTableCategoryId); BAIL_ON_EVT_ERROR(dwError); if (IsNullOrEmptyString(pszFilename)) { EVT_LOG_ERROR("No path to the file containing events was specified."); ShowUsage(); BAIL_ON_EVT_ERROR((dwError = EINVAL)); } TRY { dwError = LWIOpenEventLog(&bindingHandle, &hEventLog, &pszBindingString, "127.0.0.1", "127.0.0.1"); BAIL_ON_EVT_ERROR(dwError); dwError = ParseAndAddEvents(bindingHandle, hEventLog, pszFilename, eventTableCategoryId, AddEventRecord); BAIL_ON_EVT_ERROR(dwError); } CATCH_ALL { exc_get_status (THIS_CATCH, &dwError); EVT_LOG_ERROR("Unexpected error . Error code [%d]\n", dwError); BAIL_ON_EVT_ERROR(dwError); } ENDTRY; error: if (bindingHandle && hEventLog && pszBindingString) LWICloseEventLog(bindingHandle, hEventLog, pszBindingString); if(dwError != 0) { EVT_LOG_ERROR("Failed to import events. Error code [%d]\n", dwError); } return dwError; }
DWORD LwmEvtGetRecordCount( PLW_EVT_CLIENT_CONNECTION_CONTEXT pConn, IN PCWSTR pSqlFilter, OUT PDWORD pNumMatched ) { DWORD dwError = 0; PEVT_IPC_GENERIC_ERROR pError = NULL; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; LWMsgCall* pCall = NULL; dwError = LwmEvtAcquireCall(pConn, &pCall); BAIL_ON_EVT_ERROR(dwError); in.tag = EVT_Q_GET_RECORD_COUNT; in.data = (PVOID)pSqlFilter; dwError = MAP_LWMSG_ERROR(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_EVT_ERROR(dwError); switch (out.tag) { case EVT_R_GET_RECORD_COUNT: *pNumMatched = *(PDWORD)out.data; break; case EVT_R_GENERIC_ERROR: pError = (PEVT_IPC_GENERIC_ERROR) out.data; dwError = pError->Error; BAIL_ON_EVT_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_EVT_ERROR(dwError); } cleanup: if (pCall) { lwmsg_call_destroy_params(pCall, &out); lwmsg_call_release(pCall); } return dwError; error: if (pNumMatched) { *pNumMatched = 0; } goto cleanup; }
DWORD EVTOpenConfig( PCSTR pszConfigKey, PCSTR pszPolicyKey, PEVT_CONFIG_REG *ppReg ) { DWORD dwError = 0; PEVT_CONFIG_REG pReg = NULL; dwError = LwAllocateMemory(sizeof(EVT_CONFIG_REG), (PVOID*)&pReg); BAIL_ON_EVT_ERROR(dwError); dwError = LwAllocateString(pszConfigKey, &(pReg->pszConfigKey)); BAIL_ON_EVT_ERROR(dwError); dwError = LwAllocateString(pszPolicyKey, &(pReg->pszPolicyKey)); BAIL_ON_EVT_ERROR(dwError); dwError = RegOpenServer(&(pReg->hConnection)); if ( dwError ) { dwError = 0; goto error; } dwError = RegOpenKeyExA( pReg->hConnection, NULL, HKEY_THIS_MACHINE, 0, KEY_READ, &(pReg->hKey)); if (dwError) { dwError = 0; goto error; } cleanup: *ppReg = pReg; return dwError; error: EVTCloseConfig(pReg); pReg = NULL; goto cleanup; }
DWORD LwmEvtWriteRecords( PLW_EVT_CLIENT_CONNECTION_CONTEXT pConn, IN DWORD Count, IN PLW_EVENTLOG_RECORD pRecords ) { DWORD dwError = 0; PEVT_IPC_GENERIC_ERROR pError = NULL; EVT_IPC_RECORD_ARRAY req = { 0 }; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; LWMsgCall* pCall = NULL; dwError = LwmEvtAcquireCall(pConn, &pCall); BAIL_ON_EVT_ERROR(dwError); req.Count = Count; req.pRecords = pRecords; in.tag = EVT_Q_WRITE_RECORDS; in.data = &req; dwError = MAP_LWMSG_ERROR(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_EVT_ERROR(dwError); switch (out.tag) { case EVT_R_GENERIC_SUCCESS: break; case EVT_R_GENERIC_ERROR: pError = (PEVT_IPC_GENERIC_ERROR) out.data; dwError = pError->Error; BAIL_ON_EVT_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_EVT_ERROR(dwError); } cleanup: if (pCall) { lwmsg_call_destroy_params(pCall, &out); lwmsg_call_release(pCall); } return dwError; error: goto cleanup; }
NTSTATUS EVTSvcmStop( PLW_SVCM_INSTANCE pInstance ) { DWORD dwError = 0; EVT_LOG_INFO("Eventlog Service exiting..."); gbExitNow = TRUE; if (gbRegisteredTcpIp) { dwError = EVTUnregisterAllEndpoints(); BAIL_ON_EVT_ERROR(dwError); dwError = EVTStopListen(); BAIL_ON_EVT_ERROR(dwError); } dwError = LwmEvtSrvStopListenThread(); BAIL_ON_EVT_ERROR(dwError); if (gbRegisteredTcpIp) { dwError = LwMapErrnoToLwError(dcethread_interrupt(gNetworkThread)); BAIL_ON_EVT_ERROR(dwError); dwError = LwMapErrnoToLwError(dcethread_join(gNetworkThread, NULL)); BAIL_ON_EVT_ERROR(dwError); } cleanup: LwEvtDbShutdownEventDatabase(); EVTSetConfigDefaults(); EVTFreeSecurityDescriptor(gServerInfo.pAccess); gServerInfo.pAccess = NULL; return LwWin32ErrorToNtStatus(dwError); error: EVT_LOG_ERROR("Eventlog exiting due to error [code:%d]", dwError); goto cleanup; }
static DWORD EVTAddAllowAces( PACL pDacl, DWORD dwCount, PSID* ppSidArray, ACCESS_MASK dwAccessMask ) { DWORD dwInputIndex = 0; DWORD dwError = 0; for (dwInputIndex = 0; dwInputIndex < dwCount; dwInputIndex++) { dwError = LwNtStatusToWin32Error( RtlAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, dwAccessMask, ppSidArray[dwInputIndex])); BAIL_ON_EVT_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
DWORD EVTReadConfigBoolean( PEVT_CONFIG_REG pReg, PCSTR pszName, BOOLEAN bUsePolicy, PBOOLEAN pbValue ) { DWORD dwError = 0; DWORD dwValue = *pbValue == TRUE ? 0x00000001 : 0x00000000; dwError = EVTReadConfigDword( pReg, pszName, bUsePolicy, 0, -1, &dwValue); BAIL_ON_EVT_ERROR(dwError); *pbValue = dwValue ? TRUE : FALSE; cleanup: return dwError; error: goto cleanup; }
DWORD LWICheckSecurity( handle_t hBindingHandle, ACCESS_MASK dwAccessMask ) { DWORD dwError = ERROR_SUCCESS; volatile unsigned32 rpcError; PACCESS_TOKEN pUserToken = NULL; TRY { rpc_binding_inq_access_token_caller( hBindingHandle, &pUserToken, (unsigned32*)&rpcError); } CATCH_ALL ENDTRY; BAIL_ON_DCE_ERROR(dwError, rpcError); dwError = EVTCheckAllowed( pUserToken, dwAccessMask); BAIL_ON_EVT_ERROR(dwError); error: if (pUserToken) { RtlReleaseAccessToken(&pUserToken); } return dwError; }
NTSTATUS EVTSvcmStart( PLW_SVCM_INSTANCE pInstance, ULONG ArgCount, PWSTR* ppArgs, ULONG FdCount, int* pFds ) { DWORD dwError = 0; BOOLEAN bRegisterTcpIp = TRUE; dwError = EVTSetServerDefaults(); BAIL_ON_EVT_ERROR(dwError); dwError = LwEvtDbCreateDB(gServerInfo.bReplaceDB); BAIL_ON_EVT_ERROR(dwError); if (gServerInfo.bReplaceDB) { goto cleanup; } dwError = EVTReadEventLogConfigSettings(); if (dwError != 0) { EVT_LOG_ERROR("Failed to read eventlog configuration. Error code: [%u]\n", dwError); dwError = 0; } dwError = EVTGetRegisterTcpIp(&bRegisterTcpIp); BAIL_ON_EVT_ERROR(dwError); dwError = LwEvtDbInitEventDatabase(); BAIL_ON_EVT_ERROR(dwError); dwError = LwmEvtSrvStartListenThread(); BAIL_ON_EVT_ERROR(dwError); dwError = EVTRegisterInterface(); BAIL_ON_EVT_ERROR(dwError); if (bRegisterTcpIp) { dwError = LwMapErrnoToLwError(dcethread_create( &gNetworkThread, NULL, EVTNetworkThread, &gbExitNow)); BAIL_ON_EVT_ERROR(dwError); gbRegisteredTcpIp = TRUE; } cleanup: return LwWin32ErrorToNtStatus(dwError); error: goto cleanup; }
LWMsgStatus LwmEvtSrvConstructSession( LWMsgSecurityToken* pToken, void* pData, void** ppSessionData ) { DWORD dwError = 0; PLWMSG_LW_EVENTLOG_CONNECTION pConn = NULL; uid_t uid = 0; gid_t gid = 0; if (strcmp(lwmsg_security_token_get_type(pToken), "local")) { EVT_LOG_WARNING("Unsupported authentication type"); dwError = ERROR_NOT_SUPPORTED; BAIL_ON_EVT_ERROR(dwError); } dwError = LwAllocateMemory( sizeof(*pConn), (PVOID*)&pConn); BAIL_ON_EVT_ERROR(dwError); dwError = MAP_LWMSG_ERROR(lwmsg_local_token_get_eid( pToken, &uid, &gid)); BAIL_ON_EVT_ERROR(dwError); pConn->Uid = uid; pConn->Gid = gid; *ppSessionData = pConn; cleanup: return MAP_LW_ERROR_IPC(dwError); error: LW_SAFE_FREE_MEMORY(pConn); *ppSessionData = NULL; goto cleanup; }
static DWORD EVTReadEventLogConfigSettings() { DWORD dwError = 0; BOOLEAN bLocked = FALSE; EVT_LOG_INFO("Read Eventlog configuration settings"); dwError = EVTSetConfigDefaults(); BAIL_ON_EVT_ERROR(dwError); EVT_LOCK_SERVERINFO; bLocked = TRUE; dwError = EVTProcessConfig( "Services\\eventlog\\Parameters", "Policy\\Services\\eventlog\\Parameters", gConfigDescription, sizeof(gConfigDescription)/sizeof(gConfigDescription[0])); LW_SAFE_FREE_STRING(gServerInfo.pszAllowReadTo); LW_SAFE_FREE_STRING(gServerInfo.pszAllowWriteTo); LW_SAFE_FREE_STRING(gServerInfo.pszAllowDeleteTo); gServerInfo.pszAllowReadTo = gpszAllowReadTo; gServerInfo.pszAllowWriteTo = gpszAllowWriteTo; gServerInfo.pszAllowDeleteTo = gpszAllowDeleteTo; gpszAllowReadTo = NULL; gpszAllowWriteTo = NULL; gpszAllowDeleteTo = NULL; EVTFreeSecurityDescriptor(gServerInfo.pAccess); gServerInfo.pAccess = NULL; EVT_UNLOCK_SERVERINFO; bLocked = FALSE; EVTLogConfigReload(); cleanup: LW_SAFE_FREE_STRING(gpszAllowReadTo); LW_SAFE_FREE_STRING(gpszAllowWriteTo); LW_SAFE_FREE_STRING(gpszAllowDeleteTo); if (bLocked) { EVT_UNLOCK_SERVERINFO; } return dwError; error: goto cleanup; }
DWORD LWICheckGSSSecurity( gss_ctx_id_t gss_ctx, PEVTALLOWEDDATA pAllowedData ) { DWORD dwError = ERROR_SUCCESS; PSTR pszClientName = NULL; PSTR pszServerName = NULL; // We require LSASS in order to parse the configuration data. // If we were not able to do so earlier, try it again here. if ( pAllowedData->configData && !pAllowedData->pAllowedTo ) { dwError = EVTAccessGetData( pAllowedData->configData, &pAllowedData->pAllowedTo); BAIL_ON_EVT_ERROR(dwError); } dwError = LWIGetGSSSecurityContextInfo(gss_ctx, &pszClientName); BAIL_ON_EVT_ERROR(dwError); dwError = EVTAccessCheckData( pszClientName, pAllowedData->pAllowedTo); BAIL_ON_EVT_ERROR(dwError); cleanup: EVT_SAFE_FREE_STRING(pszClientName); EVT_SAFE_FREE_STRING(pszServerName); return dwError; error: goto cleanup; }
DWORD LwmEvtAcquireCall( HANDLE hConnection, LWMsgCall** ppCall ) { DWORD dwError = 0; PLW_EVT_CLIENT_CONNECTION_CONTEXT pContext = hConnection; dwError = MAP_LWMSG_ERROR(lwmsg_peer_acquire_call(pContext->pClient, ppCall)); BAIL_ON_EVT_ERROR(dwError); error: return dwError; }
VOID LwmEvtOpenServerOnce( VOID ) { DWORD dwError = 0; dwError = MAP_LWMSG_ERROR(lwmsg_protocol_new(NULL, &gContext.pProtocol)); BAIL_ON_EVT_ERROR(dwError); dwError = MAP_LWMSG_ERROR(lwmsg_protocol_add_protocol_spec(gContext.pProtocol, LwEvtIPCGetProtocolSpec())); BAIL_ON_EVT_ERROR(dwError); dwError = MAP_LWMSG_ERROR(lwmsg_peer_new(NULL, gContext.pProtocol, &gContext.pClient)); BAIL_ON_EVT_ERROR(dwError); dwError = MAP_LWMSG_ERROR(lwmsg_peer_add_connect_endpoint( gContext.pClient, LWMSG_ENDPOINT_DIRECT, "eventlog")); BAIL_ON_EVT_ERROR(dwError); dwError = MAP_LWMSG_ERROR(lwmsg_peer_add_connect_endpoint( gContext.pClient, LWMSG_ENDPOINT_LOCAL, CACHEDIR "/" EVT_SERVER_FILENAME)); BAIL_ON_EVT_ERROR(dwError); dwError = MAP_LWMSG_ERROR(lwmsg_peer_connect(gContext.pClient, &gContext.pSession)); BAIL_ON_EVT_ERROR(dwError); cleanup: gdwOnceError = dwError; return; error: if (gContext.pClient) { lwmsg_peer_delete(gContext.pClient); gContext.pClient = NULL; } if (gContext.pProtocol) { lwmsg_protocol_delete(gContext.pProtocol); gContext.pProtocol = NULL; } goto cleanup; }
VOID EVTLogConfigReload( VOID ) { DWORD dwError = 0; PSTR pszDescription = NULL; dwError = LwAllocateStringPrintf( &pszDescription, " Current config settings are...\r\n" \ " Max Disk Usage : %d\r\n" \ " Max Number Of Events: %d\r\n" \ " Max Event Lifespan: %d\r\n" \ " Remove Events As Needed: %s\r\n" \ " Register TCP/IP RPC endpoints: %s\r\n" \ " Allow Read To : %s\r\n" \ " Allow Write To : %s\r\n" \ " Allow Delete To : %s\r\n", gServerInfo.dwMaxLogSize, gServerInfo.dwMaxRecords, gServerInfo.dwMaxAge, gServerInfo.bRemoveAsNeeded? "true" : "false", gServerInfo.bRegisterTcpIp ? "true" : "false", gServerInfo.pszAllowReadTo ? gServerInfo.pszAllowReadTo: "", gServerInfo.pszAllowWriteTo ? gServerInfo.pszAllowWriteTo: "", gServerInfo.pszAllowDeleteTo ? gServerInfo.pszAllowDeleteTo: ""); BAIL_ON_EVT_ERROR(dwError); EVT_LOG_INFO("%s", pszDescription); cleanup: LW_SAFE_FREE_STRING(pszDescription); return; error: goto cleanup; }
DWORD EVTReadConfigEnum( PEVT_CONFIG_REG pReg, PCSTR pszName, BOOLEAN bUsePolicy, DWORD dwMin, DWORD dwMax, const PCSTR *ppszEnumNames, PDWORD pdwValue ) { DWORD dwError = 0; PSTR pszValue = NULL; DWORD dwEnumIndex; dwError = EVTReadConfigString( pReg, pszName, bUsePolicy, &pszValue); BAIL_ON_EVT_ERROR(dwError); if (pszValue != NULL ) { for (dwEnumIndex = 0; dwEnumIndex <= dwMax - dwMin; dwEnumIndex++) { if(!strcasecmp(pszValue, ppszEnumNames[dwEnumIndex])) { *pdwValue = dwEnumIndex + dwMin; goto cleanup; } } } cleanup: LW_SAFE_FREE_STRING(pszValue); return dwError; error: goto cleanup; }
static int ParseArgs( int argc, char* argv[], PSTR* ppszFilepath, DWORD* eventTableCategoryId) { DWORD dwError = 0; PSTR pszArg = NULL; PSTR pszFilepath = NULL; if(argc <= 1 || argc > 3) { ShowUsage(); exit(0); } pszArg = argv[1]; if (pszArg == NULL || *pszArg == '\0' || strcmp(pszArg, "--help") == 0 || strcmp(pszArg, "-h") == 0) { ShowUsage(); exit(0); } dwError = EVTAllocateString(pszArg, &pszFilepath); BAIL_ON_EVT_ERROR(dwError); if(argc == 3) { *eventTableCategoryId = atoi(argv[2]); } *ppszFilepath = pszFilepath; cleanup: return dwError; error: EVT_SAFE_FREE_STRING(pszFilepath); *ppszFilepath = NULL; goto cleanup; }
DWORD EVTReadConfigString( PEVT_CONFIG_REG pReg, PCSTR pszName, BOOLEAN bUsePolicy, PSTR *ppszValue ) { DWORD dwError = 0; BOOLEAN bGotValue = FALSE; PSTR pszValue = NULL; char szValue[MAX_VALUE_LENGTH]; DWORD dwType; DWORD dwSize; if ( bUsePolicy ) { dwSize = sizeof(szValue); memset(szValue, 0, dwSize); dwError = RegGetValueA( pReg->hConnection, pReg->hKey, pReg->pszPolicyKey, pszName, RRF_RT_REG_SZ, &dwType, szValue, &dwSize); if (!dwError) bGotValue = TRUE; } if (!bGotValue ) { dwSize = sizeof(szValue); memset(szValue, 0, dwSize); dwError = RegGetValueA( pReg->hConnection, pReg->hKey, pReg->pszConfigKey, pszName, RRF_RT_REG_SZ, &dwType, szValue, &dwSize); if (!dwError) bGotValue = TRUE; } if (bGotValue) { dwError = LwAllocateString(szValue, &pszValue); BAIL_ON_EVT_ERROR(dwError); LW_SAFE_FREE_STRING(*ppszValue); *ppszValue = pszValue; pszValue = NULL; } dwError = 0; cleanup: LW_SAFE_FREE_STRING(pszValue); return dwError; error: goto cleanup; }
DWORD LwEvtCreateEventlogRpcBinding( const char * hostname, handle_t * event_binding ) { DWORD winerror = 0; DWORD dwError = 0; const char * protocol; const char * endpoint; char * pszBindingString = NULL; char *hostPrincipal = NULL; size_t hostPrincipalSize = 0; int ret = 0; handle_t eventBinding_local = 0; BOOLEAN bLocalHost = FALSE; /* Connect using tcp */ protocol = "ncacn_ip_tcp"; endpoint = NULL; EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() hostname=%s, *event_binding=%.16X\n", hostname, *event_binding); RPC_STRING_BINDING_COMPOSE((char*) protocol, (char*) hostname, (char*) endpoint, &pszBindingString, &winerror); BAIL_ON_DCE_ERROR(dwError, winerror); if (pszBindingString == NULL || *pszBindingString == '\0') { BAIL_ON_DCE_ERROR(dwError, RPC_S_INVALID_STRING_BINDING); } EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() pszBindingString=%s, running rbfsb\n", pszBindingString); RPC_BINDING_FROM_STRING_BINDING(pszBindingString, &eventBinding_local, &winerror); BAIL_ON_DCE_ERROR(dwError, winerror); EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() eventBinding_local=%.16X, finished rbfsb\n", eventBinding_local); if (hostname != NULL && !bLocalHost) { /* Set up authentication if we are connecting to a remote host */ hostPrincipalSize = strlen(hostname) + 6; dwError = LwAllocateMemory(hostPrincipalSize, (PVOID*)&hostPrincipal); BAIL_ON_EVT_ERROR(dwError); ret = snprintf(hostPrincipal, hostPrincipalSize, "host/%s", hostname); if (ret < 0 || ret >= hostPrincipalSize) { BAIL_ON_EVT_ERROR(ERROR_INSUFFICIENT_BUFFER); } EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() using host principal [%s]\n", hostPrincipal); winerror = RpcBindingSetAuthInfo(eventBinding_local, (unsigned char*)hostPrincipal, rpc_c_protect_level_pkt_privacy, rpc_c_authn_gss_negotiate, NULL, rpc_c_authz_name); BAIL_ON_DCE_ERROR(dwError, winerror); EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() eventBinding_local=%.16X, auth info set" "winerror=0x%08x\n", eventBinding_local, winerror); } *event_binding = eventBinding_local; EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() finished successfully\n"); cleanup: if (hostPrincipal) { LwFreeMemory(hostPrincipal); } if (pszBindingString) { DWORD tempstatus = 0; RPC_STRING_FREE(&pszBindingString, &tempstatus); } return dwError; error: EVT_LOG_VERBOSE("client::eventlogbinding.c: CreateEventlogRpcBinding() label error: winerror=%d\n", winerror); goto cleanup; }
DWORD EVTCheckAllowed( PACCESS_TOKEN pUserToken, ACCESS_MASK dwAccessMask, BOOLEAN* pAllowed ) { DWORD dwError = 0; PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL; // Do not free PSECURITY_DESCRIPTOR_ABSOLUTE pDescriptor = NULL; PSTR pszAllowReadTo = NULL; PSTR pszAllowWriteTo = NULL; PSTR pszAllowDeleteTo = NULL; BOOLEAN bLocked = FALSE; BOOLEAN bFullyResolved = FALSE; GENERIC_MAPPING GenericMapping = {0}; NTSTATUS ntStatus = STATUS_SUCCESS; ACCESS_MASK dwGrantedAccess = 0; BOOLEAN allowed = FALSE; EVT_LOCK_SERVERINFO; bLocked = TRUE; if (!gServerInfo.pAccess) { dwError = LwAllocateString( gServerInfo.pszAllowReadTo ? gServerInfo.pszAllowReadTo : "", &pszAllowReadTo); BAIL_ON_EVT_ERROR(dwError); dwError = LwAllocateString( gServerInfo.pszAllowWriteTo ? gServerInfo.pszAllowWriteTo : "", &pszAllowWriteTo); BAIL_ON_EVT_ERROR(dwError); dwError = LwAllocateString( gServerInfo.pszAllowDeleteTo ? gServerInfo.pszAllowDeleteTo : "", &pszAllowDeleteTo); BAIL_ON_EVT_ERROR(dwError); EVT_UNLOCK_SERVERINFO; bLocked = FALSE; dwError = EVTCreateAccessDescriptor( pszAllowReadTo, pszAllowWriteTo, pszAllowDeleteTo, &pAbsolute, &bFullyResolved); BAIL_ON_EVT_ERROR(dwError); EVT_LOCK_SERVERINFO; bLocked = TRUE; if (bFullyResolved && !gServerInfo.pAccess) { gServerInfo.pAccess = pAbsolute; pAbsolute = NULL; } else { pDescriptor = pAbsolute; } } if (pDescriptor == NULL) { pDescriptor = gServerInfo.pAccess; } if (!RtlAccessCheck(pDescriptor, pUserToken, dwAccessMask, 0, &GenericMapping, &dwGrantedAccess, &ntStatus)) { dwError = LwNtStatusToWin32Error(ntStatus); if (dwError == ERROR_ACCESS_DENIED) { dwError = 0; } BAIL_ON_EVT_ERROR(dwError); } else { allowed = TRUE; } *pAllowed = allowed; cleanup: if (bLocked) { EVT_UNLOCK_SERVERINFO; } LW_SAFE_FREE_STRING(pszAllowReadTo); LW_SAFE_FREE_STRING(pszAllowWriteTo); LW_SAFE_FREE_STRING(pszAllowDeleteTo); EVTFreeSecurityDescriptor(pAbsolute); return (dwError); error: goto cleanup; }
DWORD LWIGetGSSSecurityContextInfo( gss_ctx_id_t gss_ctx, PSTR *pszClientName ) { DWORD dwError = ERROR_SUCCESS; int gss_rc = 0; OM_uint32 minor_status = 0; gss_name_t src = GSS_C_NO_NAME; gss_buffer_desc src_name = GSS_C_EMPTY_BUFFER; gss_OID src_type = GSS_C_NULL_OID; PSTR pszClient = NULL; /* Fetch security context information to make it available on the server side (e.g. for security checks) */ gss_rc = gss_inquire_context(&minor_status, gss_ctx, &src, NULL, NULL, NULL, NULL, NULL, NULL); if (gss_rc == GSS_S_COMPLETE) { /* * Get calling principal name */ gss_rc = gss_display_name(&minor_status, src, &src_name, &src_type); if (gss_rc != GSS_S_COMPLETE) { /* * TODO: error handling */ } dwError = EVTStrndup(src_name.value, src_name.length, &pszClient); BAIL_ON_EVT_ERROR(dwError); } else { /* error handling */ } *pszClientName = pszClient; cleanup: gss_release_buffer(&minor_status, &src_name); if (src) { gss_release_name(&minor_status, &src); } return dwError; error: EVT_SAFE_FREE_STRING(pszClient); *pszClientName = NULL; goto cleanup; }
DWORD LwmEvtReadRecords( PLW_EVT_CLIENT_CONNECTION_CONTEXT pConn, IN DWORD MaxResults, IN PCWSTR pSqlFilter, OUT PDWORD pCount, OUT PLW_EVENTLOG_RECORD* ppRecords ) { DWORD dwError = 0; PEVT_IPC_GENERIC_ERROR pError = NULL; EVT_IPC_READ_RECORDS_REQ req = { 0 }; PEVT_IPC_RECORD_ARRAY pRes = NULL; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; LWMsgCall* pCall = NULL; dwError = LwmEvtAcquireCall(pConn, &pCall); BAIL_ON_EVT_ERROR(dwError); req.MaxResults = MaxResults; req.pFilter = pSqlFilter; in.tag = EVT_Q_READ_RECORDS; in.data = &req; dwError = MAP_LWMSG_ERROR(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_EVT_ERROR(dwError); switch (out.tag) { case EVT_R_READ_RECORDS: pRes = (PEVT_IPC_RECORD_ARRAY)out.data; *pCount = pRes->Count; *ppRecords = pRes->pRecords; pRes->Count = 0; pRes->pRecords = NULL; break; case EVT_R_GENERIC_ERROR: pError = (PEVT_IPC_GENERIC_ERROR) out.data; dwError = pError->Error; BAIL_ON_EVT_ERROR(dwError); break; default: dwError = LW_ERROR_INTERNAL; BAIL_ON_EVT_ERROR(dwError); } cleanup: if (pCall) { lwmsg_call_destroy_params(pCall, &out); lwmsg_call_release(pCall); } return dwError; error: *pCount = 0; *ppRecords = NULL; goto cleanup; }
static DWORD EVTNamesToSids( PLW_MAP_SECURITY_CONTEXT pContext, DWORD dwCount, PSTR* ppszArray, PDWORD pdwSidCount, PSID** pppSidArray ) { DWORD dwError = 0; PSID pSid = NULL; DWORD dwInputIndex = 0; DWORD dwOutputIndex = 0; PSID* ppSidArray = NULL; dwError = LwAllocateMemory( sizeof(PSID) * dwCount, (PVOID)&ppSidArray); BAIL_ON_EVT_ERROR(dwError); for (dwInputIndex = 0; dwInputIndex < dwCount; dwInputIndex++) { dwError = LwNtStatusToWin32Error( LwMapSecurityGetSidFromName( pContext, &pSid, TRUE, ppszArray[dwInputIndex])); if (dwError == LW_ERROR_NO_SUCH_USER || dwError == ERROR_NOT_FOUND) { dwError = LwNtStatusToWin32Error( LwMapSecurityGetSidFromName( pContext, &pSid, FALSE, ppszArray[dwInputIndex])); } if (dwError == LW_ERROR_NO_SUCH_GROUP || dwError == ERROR_NOT_FOUND) { dwError = 0; } BAIL_ON_EVT_ERROR(dwError); if (pSid) { ppSidArray[dwOutputIndex] = pSid; dwOutputIndex++; } } *pppSidArray = ppSidArray; *pdwSidCount = dwOutputIndex; cleanup: return dwError; error: EVTFreeSidArray( pContext, dwCount, ppSidArray); goto cleanup; }
static DWORD EVTStringSplit( PCSTR pszInput, PDWORD pdwCount, PSTR** pppszArray ) { DWORD dwError = 0; DWORD dwCount = 0; PCSTR pszStart = NULL; PCSTR pszEnd = NULL; PSTR* ppszArray = NULL; PSTR pszAdd = NULL; for (pszStart = pszInput; *pszStart != 0; pszStart++) { if (*pszStart == ',') dwCount++; } dwCount++; dwError = LwAllocateMemory( (dwCount+1)*sizeof(PCSTR), (PVOID *)&ppszArray); dwCount = 0; pszStart = pszInput; while (TRUE) { pszEnd = strchr(pszStart, ','); if ( pszEnd ) { dwError = LwStrndup( pszStart, pszEnd - pszStart, &pszAdd); BAIL_ON_EVT_ERROR(dwError); } else { dwError = LwAllocateString( pszStart, &pszAdd); BAIL_ON_EVT_ERROR(dwError); } LwStripWhitespace(pszAdd, TRUE, TRUE); if (pszAdd[0]) { ppszArray[dwCount++] = pszAdd; pszAdd = NULL; } else { LW_SAFE_FREE_STRING(pszAdd); } if (pszEnd) { pszStart = pszEnd + 1; } else { break; } } *pppszArray = ppszArray; *pdwCount = dwCount; cleanup: LW_SAFE_FREE_STRING(pszAdd); return dwError; error: LwFreeStringArray( ppszArray, dwCount); goto cleanup; }
DWORD EVTProcessConfig( PCSTR pszConfigKey, PCSTR pszPolicyKey, PEVT_CONFIG_TABLE pConfig, DWORD dwConfigEntries ) { DWORD dwError = 0; DWORD dwEntry; PEVT_CONFIG_REG pReg = NULL; dwError = EVTOpenConfig(pszConfigKey, pszPolicyKey, &pReg); BAIL_ON_EVT_ERROR(dwError); if ( pReg == NULL ) { goto error; } for (dwEntry = 0; dwEntry < dwConfigEntries; dwEntry++) { dwError = 0; switch (pConfig[dwEntry].Type) { case EVTTypeString: dwError = EVTReadConfigString( pReg, pConfig[dwEntry].pszName, pConfig[dwEntry].bUsePolicy, pConfig[dwEntry].pValue); break; case EVTTypeDword: dwError = EVTReadConfigDword( pReg, pConfig[dwEntry].pszName, pConfig[dwEntry].bUsePolicy, pConfig[dwEntry].dwMin, pConfig[dwEntry].dwMax, pConfig[dwEntry].pValue); break; case EVTTypeBoolean: dwError = EVTReadConfigBoolean( pReg, pConfig[dwEntry].pszName, pConfig[dwEntry].bUsePolicy, pConfig[dwEntry].pValue); break; case EVTTypeEnum: dwError = EVTReadConfigEnum( pReg, pConfig[dwEntry].pszName, pConfig[dwEntry].bUsePolicy, pConfig[dwEntry].dwMin, pConfig[dwEntry].dwMax, pConfig[dwEntry].ppszEnumNames, pConfig[dwEntry].pValue); break; default: break; } BAIL_ON_NON_LWREG_ERROR(dwError); dwError = 0; } cleanup: EVTCloseConfig(pReg); pReg = NULL; return dwError; error: goto cleanup; }
static DWORD EVTCreateAccessDescriptor( PCSTR pszAllowReadTo, PCSTR pszAllowWriteTo, PCSTR pszAllowDeleteTo, PSECURITY_DESCRIPTOR_ABSOLUTE* ppDescriptor, PBOOLEAN pbFullyResolved ) { PSECURITY_DESCRIPTOR_ABSOLUTE pDescriptor = NULL; DWORD dwCount = 0; PSTR* ppszArray = NULL; DWORD dwReadCount = 0; DWORD dwWriteCount = 0; DWORD dwDeleteCount = 0; PSID* ppReadList = NULL; PSID* ppWriteList = NULL; PSID* ppDeleteList = NULL; PACL pDacl = NULL; DWORD dwDaclSize = 0; PLW_MAP_SECURITY_CONTEXT pContext = NULL; DWORD dwError = 0; PSID pLocalSystem = NULL; PSID pAdministrators = NULL; BOOLEAN bFullyResolved = TRUE; dwError = LwAllocateWellKnownSid( WinLocalSystemSid, NULL, &pLocalSystem, NULL); BAIL_ON_EVT_ERROR(dwError); dwError = LwAllocateWellKnownSid( WinBuiltinAdministratorsSid, NULL, &pAdministrators, NULL); BAIL_ON_EVT_ERROR(dwError); dwError = LwNtStatusToWin32Error( LwMapSecurityCreateContext( &pContext)); BAIL_ON_EVT_ERROR(dwError); dwError = LwAllocateMemory( SECURITY_DESCRIPTOR_ABSOLUTE_MIN_SIZE, (PVOID*)&pDescriptor); BAIL_ON_EVT_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlCreateSecurityDescriptorAbsolute( pDescriptor, SECURITY_DESCRIPTOR_REVISION)); BAIL_ON_EVT_ERROR(dwError); dwError = EVTStringSplit( pszAllowReadTo, &dwCount, &ppszArray); BAIL_ON_EVT_ERROR(dwError); dwError = EVTNamesToSids( pContext, dwCount, ppszArray, &dwReadCount, &ppReadList); BAIL_ON_EVT_ERROR(dwError); if (dwReadCount < dwCount) { bFullyResolved = FALSE; } LwFreeStringArray( ppszArray, dwCount); ppszArray = NULL; dwError = EVTStringSplit( pszAllowWriteTo, &dwCount, &ppszArray); BAIL_ON_EVT_ERROR(dwError); dwError = EVTNamesToSids( pContext, dwCount, ppszArray, &dwWriteCount, &ppWriteList); BAIL_ON_EVT_ERROR(dwError); if (dwWriteCount < dwCount) { bFullyResolved = FALSE; } LwFreeStringArray( ppszArray, dwCount); ppszArray = NULL; dwError = EVTStringSplit( pszAllowDeleteTo, &dwCount, &ppszArray); BAIL_ON_EVT_ERROR(dwError); dwError = EVTNamesToSids( pContext, dwCount, ppszArray, &dwDeleteCount, &ppDeleteList); BAIL_ON_EVT_ERROR(dwError); if (dwDeleteCount < dwCount) { bFullyResolved = FALSE; } LwFreeStringArray( ppszArray, dwCount); ppszArray = NULL; dwDaclSize = ACL_HEADER_SIZE + EVTGetAllowAcesSize(dwReadCount, ppReadList) + EVTGetAllowAcesSize(dwWriteCount, ppWriteList) + EVTGetAllowAcesSize(dwDeleteCount, ppDeleteList); dwError = LwAllocateMemory( dwDaclSize, OUT_PPVOID(&pDacl)); BAIL_ON_EVT_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlCreateAcl(pDacl, dwDaclSize, ACL_REVISION)); BAIL_ON_EVT_ERROR(dwError); dwError = EVTAddAllowAces( pDacl, dwReadCount, ppReadList, EVENTLOG_READ_RECORD); BAIL_ON_EVT_ERROR(dwError); dwError = EVTAddAllowAces( pDacl, dwWriteCount, ppWriteList, EVENTLOG_WRITE_RECORD); BAIL_ON_EVT_ERROR(dwError); dwError = EVTAddAllowAces( pDacl, dwWriteCount, ppWriteList, EVENTLOG_DELETE_RECORD); BAIL_ON_EVT_ERROR(dwError); dwError = LwNtStatusToWin32Error( RtlSetDaclSecurityDescriptor( pDescriptor, TRUE, pDacl, FALSE)); BAIL_ON_EVT_ERROR(dwError); pDacl = NULL; dwError = LwNtStatusToWin32Error( RtlSetOwnerSecurityDescriptor( pDescriptor, pLocalSystem, FALSE)); BAIL_ON_EVT_ERROR(dwError); pLocalSystem = NULL; dwError = LwNtStatusToWin32Error( RtlSetGroupSecurityDescriptor( pDescriptor, pAdministrators, FALSE)); BAIL_ON_EVT_ERROR(dwError); pAdministrators = NULL; *ppDescriptor = pDescriptor; if (pbFullyResolved) { *pbFullyResolved = bFullyResolved; } cleanup: if (ppszArray) { LwFreeStringArray( ppszArray, dwCount); } EVTFreeSidArray( pContext, dwReadCount, ppReadList); EVTFreeSidArray( pContext, dwWriteCount, ppWriteList); EVTFreeSidArray( pContext, dwDeleteCount, ppDeleteList); LwMapSecurityFreeContext(&pContext); return dwError; error: EVTFreeSecurityDescriptor(pDescriptor); *ppDescriptor = NULL; if (pbFullyResolved) { *pbFullyResolved = FALSE; } LW_SAFE_FREE_MEMORY(pDacl); LW_SAFE_FREE_MEMORY(pLocalSystem); LW_SAFE_FREE_MEMORY(pAdministrators); goto cleanup; }