static VOID LWNetSrvPingCLdapProcessConnections( IN DWORD dwDsFlags, IN LWNET_UNIX_MS_TIME_T CurrentTime, IN DWORD dwSingleConnTimeoutMilliseconds, IN DWORD dwActualConnCount, IN struct pollfd *Readfds, IN OUT PLWNET_CLDAP_CONNECTION_CONTEXT pConnections, OUT PLWNET_DC_INFO* ppDcInfo, OUT PBOOLEAN pbFailedFindWritable ) { DWORD dwError = 0; DWORD dwIndexConn = dwActualConnCount; BOOLEAN bFailedFindWritable = FALSE; BOOLEAN bFailed = FALSE; PLWNET_DC_INFO pDcInfo = NULL; while (dwIndexConn > 0) { dwIndexConn--; if (Readfds[dwIndexConn].revents) { dwError = LWNetSrvPingCLdapProcess( &pConnections[dwIndexConn], dwDsFlags, CurrentTime, &pDcInfo, &bFailed); bFailedFindWritable = bFailed ? TRUE : bFailedFindWritable; if (dwError) { LWNET_LOG_VERBOSE("CLDAP error: %d, %s", dwError, pConnections[dwIndexConn].pServerInfo->pszName); dwError = 0; } else if (pDcInfo) { break; } } else if (pConnections[dwIndexConn].StartTime + dwSingleConnTimeoutMilliseconds < CurrentTime) { LWNET_LOG_VERBOSE("CLDAP timed out: %s", pConnections[dwIndexConn].pServerInfo->pszName); LWNetSrvPingCLdapEnd(&pConnections[dwIndexConn]); } } *ppDcInfo = pDcInfo; }
NTSTATUS LWNetSvcmStop( PLW_SVCM_INSTANCE pInstance ) { LWNET_LOG_VERBOSE("LWNet main cleaning up"); // Post service stopped event to eventlog LWNetSrvLogProcessStoppedEvent(ERROR_SUCCESS); LWNetSrvStopListenThread(); LWNetSrvApiShutdown(); LWNET_LOG_INFO("LWNET Service exiting..."); return STATUS_SUCCESS; }
DWORD LWNetDnsGetAddressForServer( IN PDLINKEDLIST pAdditionalsList, IN PCSTR pszHostname, OUT PSTR* ppszAddress ) { DWORD dwError = 0; PSTR pszAddress = NULL; PDLINKEDLIST pListMember = NULL; pListMember = pAdditionalsList; while (pListMember) { PDNS_RECORD pRecord = (PDNS_RECORD)pListMember->pItem; if ( (pRecord->wType == ns_t_a ) && !strcasecmp( pRecord->pszName, pszHostname ) ) { dwError = LwAllocateStringPrintf(&pszAddress, "%d.%d.%d.%d", pRecord->pData[0], pRecord->pData[1], pRecord->pData[2], pRecord->pData[3]); BAIL_ON_LWNET_ERROR(dwError); break; } pListMember = pListMember->pNext; } if (IsNullOrEmptyString(pszAddress)) { struct hostent * host; LWNET_LOG_VERBOSE("Getting address for '%s'", pszHostname); host = gethostbyname(pszHostname); if (host && host->h_name) { // ISSUE-2008/07/01-dalmeida -- Need to check that address type is IPv4 dwError = LWNetAllocateString(inet_ntoa(*(struct in_addr*)(host->h_addr_list[0])), &pszAddress); BAIL_ON_LWNET_ERROR(dwError); } } if (IsNullOrEmptyString(pszAddress)) { LWNET_LOG_WARNING("Unable to get IP address for '%s'", pszHostname); dwError = ERROR_NOT_FOUND; BAIL_ON_LWNET_ERROR(dwError); } error: if (dwError) { LWNET_SAFE_FREE_STRING(pszAddress); } *ppszAddress = pszAddress; return dwError; }
static DWORD LWNetSrvPingCLdapProcess( IN PLWNET_CLDAP_CONNECTION_CONTEXT pContext, IN DWORD dwDsFlags, IN LWNET_UNIX_MS_TIME_T StopTime, OUT PLWNET_DC_INFO* ppDcInfo, OUT PBOOLEAN pbFailedFindWritable ) { DWORD dwError = 0; DWORD dwResultType = 0; LDAPMessage* pMessage = NULL; PBYTE pNetlogonAttributeValue = NULL; DWORD dwNetlogonAttributeSize = 0; PLWNET_DC_INFO pDcInfo = NULL; BOOLEAN bFailedFindWritable = FALSE; struct timeval timeout = {0}; LDAP *ld = NULL; ld = LwLdapGetSession(pContext->hDirectory); dwResultType = ldap_result( ld, pContext->msgid, 0, &timeout, &pMessage); if (dwResultType == 0) { // timed out goto error; } else if (dwResultType == -1) { // -1 = problem dwError = LDAP_NO_SUCH_OBJECT; LWNET_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search"); } else { // returns result type if (dwResultType != LDAP_RES_SEARCH_ENTRY) { dwError = LDAP_NO_SUCH_OBJECT; LWNET_LOG_DEBUG("Caught incorrect result type on ldap search: %d", dwError); } } dwError = LwMapLdapErrorToLwError(dwError); BAIL_ON_LWNET_ERROR(dwError); dwError = LwLdapGetBytes( pContext->hDirectory, pMessage, NETLOGON_LDAP_ATTRIBUTE_NAME, &pNetlogonAttributeValue, &dwNetlogonAttributeSize); BAIL_ON_LWNET_ERROR(dwError); dwError = LWNetBuildDCInfo(pNetlogonAttributeValue, dwNetlogonAttributeSize, &pDcInfo); BAIL_ON_LWNET_ERROR(dwError); dwError = LWNetAllocateString(pContext->pServerInfo->pszAddress, &pDcInfo->pszDomainControllerAddress); BAIL_ON_LWNET_ERROR(dwError); pDcInfo->dwPingTime = (DWORD)(StopTime - pContext->StartTime); if (StopTime < pContext->StartTime) { LWNET_LOG_ERROR("Stop time is earlier than start time"); } if (!LWNetSrvIsMatchingDcInfo(pDcInfo, dwDsFlags)) { dwError = LW_ERROR_NO_SUCH_OBJECT; if (LWNetSrvIsMatchingDcInfo(pDcInfo, dwDsFlags & ~DS_WRITABLE_REQUIRED)) { // We found something, but it failed only because it did // not satisfy writability. bFailedFindWritable = TRUE; } } error: if (pMessage) { ldap_msgfree(pMessage); } LWNET_SAFE_FREE_MEMORY(pNetlogonAttributeValue); if (dwError) { LWNET_SAFE_FREE_DC_INFO(pDcInfo); LWNetSrvPingCLdapEnd(pContext); } *ppDcInfo = pDcInfo; *pbFailedFindWritable = bFailedFindWritable; return dwError; }
DWORD LWNetDnsQueryWithBuffer( IN PCSTR pszQuestion, IN BOOLEAN bReInit, IN BOOLEAN bUseTcp, OUT PVOID pBuffer, IN DWORD dwBufferSize, OUT PDWORD pdwResponseSize ) { DWORD dwError = 0; PDNS_RESPONSE_HEADER pHeader = (PDNS_RESPONSE_HEADER)pBuffer; int responseSize = 0; BOOLEAN bInLock = FALSE; #if HAVE_DECL_RES_NINIT union { struct __res_state res; #ifdef __LWI_AIX__ // struct __res_state was enlarged from 720 in AIX 5.2 to 824 in AIX // 5.3. This means calling res_ninit on AIX 5.3 on a structure compiled // on AIX 5.2 will result in a buffer overflow. Furthermore, even on // AIX 5.3, res_ninit seems to expect 1596 bytes in the structure (1491 // on AIX 5.2). As a workaround, this padding will ensure enough space // is allocated on the stack. char buffer[2048]; #endif } resLocal = { {0} }; res_state res = &resLocal.res; #else struct __res_state *res = &_res; #endif LWNET_LOCK_RESOLVER_API(bInLock); #if HAVE_DECL_RES_NINIT if (res_ninit(res) != 0) #else if (res_init() != 0) #endif { dwError = ERROR_NOT_FOUND; BAIL_ON_LWNET_ERROR(dwError); } if (dwBufferSize < CT_MIN(sizeof(DNS_RESPONSE_HEADER), MAX_DNS_UDP_BUFFER)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_LWNET_ERROR(dwError); } // TODO: Add lock on calling resolver due to global options, which may or // may not be safe depending on the system. if (bUseTcp) { res->options |= RES_USEVC; } else { res->options &= ~(RES_USEVC); } /* Assertion: pResolverContext != NULL && pResolverContext->bLocked == TRUE */ #if HAVE_DECL_RES_NINIT responseSize = res_nquery(res, pszQuestion, ns_c_in, ns_t_srv, (PBYTE) pBuffer, dwBufferSize); #else responseSize = res_query(pszQuestion, ns_c_in, ns_t_srv, (PBYTE) pBuffer, dwBufferSize); #endif if (responseSize < 0) { LWNET_LOG_VERBOSE("DNS lookup for '%s' failed with errno %d, h_errno = %d", pszQuestion, errno, h_errno); dwError = DNS_ERROR_BAD_PACKET; BAIL_ON_LWNET_ERROR(dwError); } if (responseSize < CT_FIELD_OFFSET(DNS_RESPONSE_HEADER, data)) { dwError = DNS_ERROR_BAD_PACKET; BAIL_ON_LWNET_ERROR(dwError); } if (responseSize > dwBufferSize) { dwError = DNS_ERROR_BAD_PACKET; BAIL_ON_LWNET_ERROR(dwError); } LWNetDnsFixHeaderForEndianness(pHeader); if (!LWNetDnsIsValidResponse(pHeader)) { dwError = DNS_ERROR_BAD_PACKET; BAIL_ON_LWNET_ERROR(dwError); } error: #if HAVE_DECL_RES_NINIT res_nclose(res); #else /* Indicate that we are done with the resolver, except on HPUX which does not implement the res_close function. */ #ifndef __LWI_HP_UX__ res_close(); #endif #endif LWNET_UNLOCK_RESOLVER_API(bInLock); if (dwError) { responseSize = 0; } *pdwResponseSize = responseSize; return dwError; }