static DWORD AD_SetConfig_RequireMembershipOf( PLSA_AD_CONFIG pConfig, PCSTR pszName, PCSTR pszValue ) { DWORD dwError = 0; PCSTR pszIter = pszValue; PSTR pszMember = NULL; pszIter = pszValue; while (pszIter != NULL && *pszIter != '\0') { PSTR pszEnd; while (*pszIter == ' ') { ++pszIter; } dwError = LwStrDupOrNull( pszIter, &pszMember); BAIL_ON_LSA_ERROR(dwError); pszEnd = pszMember + strlen(pszMember); while (pszEnd > pszMember && pszEnd[-1] == ' ') { --pszEnd; } *pszEnd = '\0'; dwError = LwDLinkedListAppend( &pConfig->pUnresolvedMemberList, pszMember); BAIL_ON_LSA_ERROR(dwError); pszMember = NULL; pszIter += strlen(pszIter) + 1; } cleanup: LW_SAFE_FREE_STRING(pszMember); return dwError; error: goto cleanup; }
static DWORD DNSGetInfoUsingIoctl( PLW_DLINKED_LIST* ppInterfaceList ) { DWORD dwError = 0; SOCKET fd = -1; DWORD dwBufLen = 0; DWORD dwLastBufLen = 0; PBYTE pBuffer = NULL; PBYTE pIter = NULL; struct ifconf ifc = {0}; PLW_DLINKED_LIST pInterfaceList = NULL; PLW_INTERFACE_INFO pInterfaceInfo = NULL; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } dwBufLen = 64 * sizeof(struct ifreq); dwError = DNSAllocateMemory( dwBufLen, (PVOID*)&pBuffer); BAIL_ON_LWDNS_ERROR(dwError); do { DWORD dwNewSize = 0; ifc.ifc_len = dwBufLen; ifc.ifc_buf = (caddr_t)pBuffer; // On some systems, the ioctl returns success // even if the buffer is insufficient. So, we // retry until the buffer length consolidates if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) { if ((errno != EINVAL) || (dwLastBufLen)) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } } else { if (dwLastBufLen == ifc.ifc_len) { break; } dwLastBufLen = ifc.ifc_len; } dwNewSize = dwLastBufLen + 32 * sizeof(struct ifreq); dwError = DNSReallocMemory( pBuffer, (PVOID*)&pBuffer, dwNewSize); BAIL_ON_LWDNS_ERROR(dwError); dwBufLen = dwNewSize; } while (TRUE); for (pIter = pBuffer; pIter < pBuffer + dwBufLen;) { CHAR szItfName[IFNAMSIZ+1]; PSTR pszIpAddress = NULL; DWORD dwFlags = 0; struct ifreq* pInterfaceRecord = NULL; struct ifreq interfaceRecordCopy; struct sockaddr * pSA = NULL; DWORD dwLen = 0; #ifdef LW_SKIP_ALIASED_INTERFACES PSTR pszIndex = NULL; #endif pInterfaceRecord = (struct ifreq*)pIter; #ifdef AF_LINK if (pInterfaceRecord->ifr_addr.sa_family == AF_LINK) { #if defined(__LWI_AIX__) dwLen = DNS_MAX(sizeof(struct sockaddr_dl), ((struct sockaddr_dl*)&pInterfaceRecord->ifr_addr)->sdl_len); #else /* Solaris etc. */ dwLen = sizeof(struct sockaddr_dl); #endif } else { #endif switch (pInterfaceRecord->ifr_addr.sa_family) { #ifdef HAVE_SOCKADDR_SA_LEN dwLen = DNS_MAX(sizeof(struct sockaddr), pInterfaceRecord->ifr_addr.sa_len); #else #ifdef AF_INET6 case AF_INET6: #ifdef __LWI_HP_UX__ dwLen = sizeof(short) + sizeof(short) + sizeof(uint32_t) + (sizeof(uint8_t) * 16); #else dwLen = sizeof(struct sockaddr_in6); #endif break; #endif case AF_INET: default: dwLen = sizeof(struct sockaddr); break; } #endif /* HAVE_SOCKADDR_SA_LEN */ #ifdef AF_LINK } #endif pIter += sizeof(pInterfaceRecord->ifr_name) + dwLen; #ifdef LW_SKIP_ALIASED_INTERFACES // On Solaris, the name for an aliased interface contains // a colon. if ((pszIndex = strchr(pInterfaceRecord->ifr_name, ':'))) { *pszIndex = '\0'; } #endif memset(szItfName, 0, sizeof(szItfName)); memcpy(szItfName, pInterfaceRecord->ifr_name, IFNAMSIZ); LWDNS_LOG_VERBOSE("Considering network interface [%s]", szItfName); pSA = (struct sockaddr*)&pInterfaceRecord->ifr_addr; if (pSA->sa_family != AF_INET) { LWDNS_LOG_VERBOSE("Skipping network interface [%s] [family:%d] because it is not AF_INET family", szItfName, pSA->sa_family); continue; } interfaceRecordCopy = *pInterfaceRecord; if (ioctl(fd, SIOCGIFFLAGS, &interfaceRecordCopy) < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } dwFlags = interfaceRecordCopy.ifr_flags; if (dwFlags & IFF_LOOPBACK) { LWDNS_LOG_VERBOSE("Skipping loopback network interface [%s]", szItfName); continue; } if (!(dwFlags & IFF_UP)) { LWDNS_LOG_VERBOSE("Skipping in-active network interface [%s]", szItfName); continue; } #ifdef LW_SKIP_ALIASED_INTERFACES if (DNSInterfaceIsInList(szItfName, pInterfaceList)) { LWDNS_LOG_VERBOSE("Skipping aliased network interface [%s]", IsNullOrEmptyString(szItfName) ? "" : szItfName); continue; } #endif dwError = DNSAllocateMemory( sizeof(LW_INTERFACE_INFO), (PVOID*)&pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateMemory( IF_NAMESIZE, (PVOID*)&pInterfaceInfo->pszName); BAIL_ON_LWDNS_ERROR(dwError); strncpy(pInterfaceInfo->pszName, pInterfaceRecord->ifr_name, IF_NAMESIZE-1); pInterfaceInfo->dwFlags = dwFlags; if (ioctl(fd, SIOCGIFADDR, &interfaceRecordCopy, sizeof(struct ifreq)) < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } // From the above logic, we consider only // AF_INET addresses at this point. memcpy(&pInterfaceInfo->ipAddr, &pInterfaceRecord->ifr_addr, sizeof(struct sockaddr_in)); dwError = LwDLinkedListAppend( &pInterfaceList, pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); pszIpAddress = inet_ntoa(((struct sockaddr_in*)&pInterfaceInfo->ipAddr)->sin_addr); LWDNS_LOG_VERBOSE("Added network interface [Name:%s; Address:%s] to list", (IsNullOrEmptyString(pInterfaceInfo->pszName) ? "" : pInterfaceInfo->pszName), (IsNullOrEmptyString(pszIpAddress) ? "" : pszIpAddress)); pInterfaceInfo = NULL; } *ppInterfaceList = pInterfaceList; cleanup: if (fd >= 0) { close(fd); } if (pBuffer) { DNSFreeMemory(pBuffer); } return dwError; error: if (pInterfaceInfo) { DNSFreeNetworkInterface(pInterfaceInfo); } if (pInterfaceList) { DNSFreeInterfaceLinkedList(pInterfaceList); } goto cleanup; }
static DWORD DNSGetInfoUsingGetIfAddrs( PLW_DLINKED_LIST* ppInterfaceList ) { DWORD dwError = 0; PLW_DLINKED_LIST pInterfaceList = NULL; struct ifaddrs* pInterfaces = NULL; struct ifaddrs* pIter = NULL; PLW_INTERFACE_INFO pInterfaceInfo = NULL; if (getifaddrs(&pInterfaces) < 0) { dwError = errno; BAIL_ON_LWDNS_ERROR(dwError); } for (pIter = pInterfaces; pIter; pIter = pIter->ifa_next) { if (IsNullOrEmptyString(pIter->ifa_name)) { LWDNS_LOG_VERBOSE("Skipping network interface with no name"); continue; } LWDNS_LOG_VERBOSE("Considering network interface [%s]", pIter->ifa_name); if (pIter->ifa_addr->sa_family != AF_INET) { if (pIter->ifa_addr->sa_family != AF_INET6) { LWDNS_LOG_VERBOSE("Skipping network interface [%s] because it is not AF_INET/AF_INET6 family", pIter->ifa_name); continue; } } if (!(pIter->ifa_flags & IFF_UP)) { LWDNS_LOG_VERBOSE("Skipping in-active network interface [%s]", pIter->ifa_name); continue; } if (pIter->ifa_flags & IFF_LOOPBACK) { LWDNS_LOG_VERBOSE("Skipping loopback network interface [%s]", pIter->ifa_name); continue; } #ifdef LW_SKIP_ALIASED_INTERFACES if (DNSInterfaceIsInList(pIter->ifa_name, pInterfaceList)) { LWDNS_LOG_VERBOSE("Skipping aliased network interface [%s]", pIter->ifa_name); continue; } #endif dwError = DNSAllocateMemory( sizeof(LW_INTERFACE_INFO), (PVOID*)&pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); dwError = DNSAllocateString( pIter->ifa_name, &pInterfaceInfo->pszName); BAIL_ON_LWDNS_ERROR(dwError); if (pIter->ifa_addr) { if (pIter->ifa_addr->sa_family == AF_INET) { memcpy(&pInterfaceInfo->ipAddr, pIter->ifa_addr, sizeof(*pIter->ifa_addr)); } #ifndef HAVE_HPUX_OS else if (pIter->ifa_addr->sa_family == AF_INET6) { pInterfaceInfo->bIPV6Enabled = TRUE; memcpy(&pInterfaceInfo->ipv6Addr, pIter->ifa_addr, sizeof(struct sockaddr_in6)); } #endif } pInterfaceInfo->dwFlags = pIter->ifa_flags; dwError = LwDLinkedListAppend( &pInterfaceList, pInterfaceInfo); BAIL_ON_LWDNS_ERROR(dwError); LWDNS_LOG_VERBOSE("Added network interface [Name:%s] to list", pInterfaceInfo->pszName); pInterfaceInfo = NULL; } *ppInterfaceList = pInterfaceList; cleanup: if (pInterfaces) { freeifaddrs(pInterfaces); } return dwError; error: if (pInterfaceList) { DNSFreeInterfaceLinkedList(pInterfaceList); } if (pInterfaceInfo) { DNSFreeNetworkInterface(pInterfaceInfo); } *ppInterfaceList = NULL; goto cleanup; }