From a652ff67c89888a61ce3da7cc55c45fb1f63cf7f Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 30 May 2019 16:52:58 -0400 Subject: [PATCH] Ticket 49361 - Use IPv6 friendly network functions Description: We use these functions that are not reliable with IPv6: - gethostbyname() - inet_ntoa() - inet_aton() - inet_addr() This patch replaces these calls using one of the following preferred functions: - inet_ntop() - inet_pton() Also fixed a few failures in the replication CI test regression_test.py as replication uses code touched by this patch. ASAN approved https://pagure.io/389-ds-base/issue/49361 Reviewed by: firstyear(Thanks!) --- Makefile.am | 2 - configure.ac | 2 +- .../suites/replication/regression_test.py | 53 ++++--- include/base/util.h | 3 - ldap/include/portable.h | 50 ------ ldap/servers/slapd/connection.c | 70 +++++---- ldap/servers/slapd/localhost.c | 61 ++++---- ldap/servers/slapd/tools/ldclt/repcheck.c | 30 +++- ldap/servers/slapd/tools/ldclt/repslave.c | 25 ++- lib/base/dns.cpp | 142 ------------------ lib/base/net.cpp | 66 -------- 11 files changed, 134 insertions(+), 370 deletions(-) delete mode 100644 lib/base/dns.cpp delete mode 100644 lib/base/net.cpp diff --git a/Makefile.am b/Makefile.am index de9e0c460..c23686ea3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1260,12 +1260,10 @@ libns_dshttpd_la_SOURCES = lib/libaccess/access_plhash.cpp \ lib/libadmin/template.c \ lib/libadmin/util.c \ lib/base/crit.cpp \ - lib/base/dns.cpp \ lib/base/dnsdmain.cpp \ lib/base/ereport.cpp \ lib/base/file.cpp \ lib/base/fsmutex.cpp \ - lib/base/net.cpp \ lib/base/nscperror.c \ lib/base/plist.cpp \ lib/base/pool.cpp \ diff --git a/configure.ac b/configure.ac index d329e84a9..0cc36fabe 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,7 @@ AC_FUNC_STAT AC_FUNC_STRERROR_R AC_FUNC_STRFTIME AC_FUNC_VPRINTF -AC_CHECK_FUNCS([endpwent ftruncate getcwd gethostbyname inet_ntoa localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset]) +AC_CHECK_FUNCS([endpwent ftruncate getcwd getaddrinfo inet_pton inet_ntop localtime_r memmove memset mkdir munmap putenv rmdir setrlimit socket strcasecmp strchr strcspn strdup strerror strncasecmp strpbrk strrchr strstr strtol tzset]) # These functions are *required* without option. AC_CHECK_FUNCS([clock_gettime], [], AC_MSG_ERROR([unable to locate required symbol clock_gettime])) diff --git a/dirsrvtests/tests/suites/replication/regression_test.py b/dirsrvtests/tests/suites/replication/regression_test.py index cf34a1a6a..830ef63ab 100644 --- a/dirsrvtests/tests/suites/replication/regression_test.py +++ b/dirsrvtests/tests/suites/replication/regression_test.py @@ -13,11 +13,9 @@ from lib389.idm.user import TEST_USER_PROPERTIES, UserAccounts from lib389.utils import * from lib389.topologies import topology_m2 as topo_m2, TopologyMain, topology_m3 as topo_m3, create_topology, _remove_ssca_db from lib389._constants import * -from . import get_repl_entries from lib389.idm.organizationalunit import OrganizationalUnits from lib389.agreement import Agreements from lib389.idm.user import UserAccount -from lib389 import Entry from lib389.idm.group import Groups, Group from lib389.replica import Replicas, ReplicationManager from lib389.changelog import Changelog5 @@ -40,6 +38,7 @@ else: logging.getLogger(__name__).setLevel(logging.INFO) log = logging.getLogger(__name__) + def find_start_location(file, no): log_pattern = re.compile("slapd_daemon - slapd started.") count = 0 @@ -59,7 +58,7 @@ def find_start_location(file, no): def pattern_errorlog(file, log_pattern, start_location=0): count = 0 - log.debug("_pattern_errorlog: start from the beginning" ) + log.debug("_pattern_errorlog: start from the beginning") file.seek(start_location) # Use a while true iteration because 'for line in file: hit a @@ -76,6 +75,7 @@ def pattern_errorlog(file, log_pattern, start_location=0): log.debug("_pattern_errorlog: complete (count=%d)" % count) return count + def _move_ruv(ldif_file): """ Move RUV entry in an ldif file to the top""" @@ -108,16 +108,13 @@ def topo_with_sigkill(request): subprocess.Popen(cmd, stdout=subprocess.PIPE) def fin(): + # Kill the hanging process at the end of test to prevent failures in the following tests if DEBUGGING: - # Kill the hanging process at the end of test to prevent failures in the following tests [_kill_ns_slapd(inst) for inst in topology] - #[inst.stop() for inst in topology] else: - # Kill the hanging process at the end of test to prevent failures in the following tests [_kill_ns_slapd(inst) for inst in topology] assert _remove_ssca_db(topology) [inst.delete() for inst in topology if inst.exists()] - request.addfinalizer(fin) return topology @@ -167,6 +164,7 @@ def test_double_delete(topo_m2, create_entry): repl.test_replication(m1, m2) repl.test_replication(m2, m1) + @pytest.mark.bz1506831 def test_repl_modrdn(topo_m2): """Test that replicated MODRDN does not break replication @@ -228,10 +226,10 @@ def test_repl_modrdn(topo_m2): topo_m2.pause_all_replicas() log.info("Apply modrdn to M1 - move test user from OU A -> C") - master1.rename_s(tuser_A.dn,'uid=testuser1',newsuperior=OU_C.dn,delold=1) + master1.rename_s(tuser_A.dn, 'uid=testuser1', newsuperior=OU_C.dn, delold=1) log.info("Apply modrdn on M2 - move test user from OU B -> C") - master2.rename_s(tuser_B.dn,'uid=testuser1',newsuperior=OU_C.dn,delold=1) + master2.rename_s(tuser_B.dn, 'uid=testuser1', newsuperior=OU_C.dn, delold=1) log.info("Start Replication") topo_m2.resume_all_replicas() @@ -252,7 +250,6 @@ def test_repl_modrdn(topo_m2): repl.test_replication(master2, master1) - def test_password_repl_error(topo_m2, create_entry): """Check that error about userpassword replication is properly logged @@ -329,7 +326,7 @@ def test_invalid_agmt(topo_m2): 'cn': 'whatever', 'nsDS5ReplicaRoot': DEFAULT_SUFFIX, 'nsDS5ReplicaBindDN': 'cn=replication manager,cn=config', - 'nsDS5ReplicaBindMethod': 'simple' , + 'nsDS5ReplicaBindMethod': 'simple', 'nsDS5ReplicaTransportInfo': 'LDAP', 'nsds5replicaTimeout': '5', 'description': "test agreement", @@ -344,6 +341,7 @@ def test_invalid_agmt(topo_m2): repl.test_replication(m1, m2) repl.test_replication(m2, m1) + def test_fetch_bindDnGroup(topo_m2): """Check the bindDNGroup is fetched on first replication session @@ -380,13 +378,13 @@ def test_fetch_bindDnGroup(topo_m2): M2 = topo_m2.ms['master2'] # Enable replication log level. Not really necessary - M1.modify_s('cn=config',[(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) - M2.modify_s('cn=config',[(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) + M1.modify_s('cn=config', [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) + M2.modify_s('cn=config', [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', b'8192')]) # Create a group and a user PEOPLE = "ou=People,%s" % SUFFIX PASSWD = 'password' - REPL_MGR_BOUND_DN='repl_mgr_bound_dn' + REPL_MGR_BOUND_DN = 'repl_mgr_bound_dn' uid = REPL_MGR_BOUND_DN.encode() users = UserAccounts(M1, PEOPLE, rdn=None) @@ -396,14 +394,12 @@ def test_fetch_bindDnGroup(topo_m2): groups_M1 = Groups(M1, DEFAULT_SUFFIX) group_properties = { - 'cn' : 'group1', - 'description' : 'testgroup'} + 'cn': 'group1', + 'description': 'testgroup'} group_M1 = groups_M1.create(properties=group_properties) group_M2 = Group(M2, group_M1.dn) assert(not group_M1.is_member(create_user.dn)) - - # Check that M1 and M2 are in sync repl = ReplicationManager(DEFAULT_SUFFIX) repl.wait_for_replication(M1, M2, timeout=20) @@ -414,13 +410,11 @@ def test_fetch_bindDnGroup(topo_m2): replica.apply_mods([(ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroupCheckInterval', '60'), (ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroup', group_M1.dn)]) - replicas = Replicas(M2) replica = replicas.list()[0] replica.apply_mods([(ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroupCheckInterval', '60'), (ldap.MOD_REPLACE, 'nsDS5ReplicaBindDnGroup', group_M1.dn)]) - # Then pause the replication agreement to prevent them trying to acquire # while the user is not member of the group topo_m2.pause_all_replicas() @@ -432,7 +426,6 @@ def test_fetch_bindDnGroup(topo_m2): agmt.replace('nsDS5ReplicaBindDN', create_user.dn.encode()) agmt.replace('nsds5ReplicaCredentials', PASSWD.encode()) - # Key step # The restart will fetch the group/members define in the replica # @@ -451,8 +444,8 @@ def test_fetch_bindDnGroup(topo_m2): topo_m2.resume_all_replicas() # trigger updates to be sure to have a replication session, giving some time - M1.modify_s(create_user.dn,[(ldap.MOD_ADD, 'description', b'value_1_1')]) - M2.modify_s(create_user.dn,[(ldap.MOD_ADD, 'description', b'value_2_2')]) + M1.modify_s(create_user.dn, [(ldap.MOD_ADD, 'description', b'value_1_1')]) + M2.modify_s(create_user.dn, [(ldap.MOD_ADD, 'description', b'value_2_2')]) time.sleep(10) # Check replication is working @@ -494,12 +487,13 @@ def test_fetch_bindDnGroup(topo_m2): count = pattern_errorlog(errorlog_M1, regex, start_location=restart_location_M1) assert(count <= 1) count = pattern_errorlog(errorlog_M2, regex, start_location=restart_location_M2) - assert(count <=1) + assert(count <= 1) if DEBUGGING: # Add debugging steps(if any)... pass + def test_cleanallruv_repl(topo_m3): """Test that cleanallruv could not break replication if anchor csn in ruv originated in deleted replica :id: 46faba9a-897e-45b8-98dc-aec7fa8cec9a @@ -546,7 +540,7 @@ def test_cleanallruv_repl(topo_m3): user_props = TEST_USER_PROPERTIES.copy() user_props.update({'uid': "testuser10"}) - user10 = users_m1.create(properties=user_props) + user10 = users_m1.create(properties=user_props) user_props.update({'uid': "testuser20"}) user20 = users_m2.create(properties=user_props) @@ -587,7 +581,7 @@ def test_cleanallruv_repl(topo_m3): # ClearRuv is launched but with Force M3.stop() M1.tasks.cleanAllRUV(suffix=SUFFIX, replicaid='3', - force=True,args={TASK_WAIT: False}) + force=True, args={TASK_WAIT: False}) # here M1 should clear 31 M2.start() @@ -595,11 +589,16 @@ def test_cleanallruv_repl(topo_m3): M1.agreement.resume(m1_m2[0].dn) time.sleep(10) - #Check the users after CleanRUV + # Check the users after CleanRUV expected_m1_users = [user31.dn, user11.dn, user21.dn, user32.dn, user33.dn, user12.dn] + expected_m1_users = [x.lower() for x in expected_m1_users] expected_m2_users = [user31.dn, user11.dn, user21.dn, user12.dn] + expected_m2_users = [x.lower() for x in expected_m2_users] + current_m1_users = [user.dn for user in users_m1.list()] + current_m1_users = [x.lower() for x in current_m1_users] current_m2_users = [user.dn for user in users_m2.list()] + current_m2_users = [x.lower() for x in current_m2_users] assert set(expected_m1_users).issubset(current_m1_users) assert set(expected_m2_users).issubset(current_m2_users) diff --git a/include/base/util.h b/include/base/util.h index 94506d5e0..8ad5ddfbb 100644 --- a/include/base/util.h +++ b/include/base/util.h @@ -36,8 +36,6 @@ NSPR_BEGIN_EXTERN_C -NSAPI_PUBLIC char *INTutil_hostname(void); - NSAPI_PUBLIC int INTutil_itoa(int i, char *a); NSAPI_PUBLIC @@ -75,7 +73,6 @@ NSAPI_PUBLIC int INTutil_strncasecmp(CASECMPARG_T char *one, CASECMPARG_T char * NSPR_END_EXTERN_C -#define util_hostname INTutil_hostname #define util_itoa INTutil_itoa #define util_vsprintf INTutil_vsprintf #define util_sprintf INTutil_sprintf diff --git a/ldap/include/portable.h b/ldap/include/portable.h index 63cc4d461..fddc9c80e 100644 --- a/ldap/include/portable.h +++ b/ldap/include/portable.h @@ -241,30 +241,9 @@ int strncasecmp(const char *, const char *, size_t); #endif /* SNI || LINUX1_2 */ #if defined(_WINDOWS) || defined(macintosh) -#define GETHOSTBYNAME(n, r, b, l, e) gethostbyname(n) #define CTIME(c, b, l) ctime(c) #define STRTOK(s1, s2, l) strtok(s1, s2) #else /* UNIX */ -#if defined(sgi) || defined(HPUX9) || defined(LINUX1_2) || defined(SCOOS) || \ - defined(UNIXWARE) || defined(SUNOS4) || defined(SNI) || defined(BSDI) || \ - defined(NCR) || defined(OSF1) || defined(NEC) || \ - (defined(HPUX10) && !defined(_REENTRANT)) || defined(HPUX11) || \ - defined(UnixWare) || defined(LINUX) || defined(__FreeBSD__) -#define GETHOSTBYNAME(n, r, b, l, e) gethostbyname(n) -#elif defined(AIX) -#define GETHOSTBYNAME_BUF_T struct hostent_data -#define GETHOSTBYNAME(n, r, b, l, e) \ - (memset(&b, 0, l), gethostbyname_r(n, r, &b) ? NULL : r) -#elif defined(HPUX10) -#define GETHOSTBYNAME_BUF_T struct hostent_data -#define GETHOSTBYNAME(n, r, b, l, e) nsldapi_compat_gethostbyname_r(n, r, (char *)&b, l, e) -#else -#include /* BUFSIZ */ -typedef char GETHOSTBYNAME_buf_t[BUFSIZ /* XXX might be too small */]; -#define GETHOSTBYNAME_BUF_T GETHOSTBYNAME_buf_t -#define GETHOSTBYNAME(n, r, b, l, e) gethostbyname_r(n, r, b, l, e) -#endif - /* * XXXmcs: GETHOSTBYADDR() is only defined for IRIX/SGI and Solaris for now. */ @@ -319,35 +298,6 @@ extern char *strdup(); #include /* for inet_addr() */ #endif /* SOLARIS */ -#ifdef SUNOS4 -#include /* for toupper() */ -int fprintf(FILE *, char *, ...); -int fseek(FILE *, long, int); -int fread(char *, int, int, FILE *); -int fclose(FILE *); -int fflush(FILE *); -int rewind(FILE *); -void *memmove(void *, const void *, size_t); -int strcasecmp(char *, char *); -int strncasecmp(char *, char *, int); -time_t time(time_t *); -void perror(char *); -int fputc(char, FILE *); -int fputs(char *, FILE *); -int LDAP_CALL re_exec(char *); -int socket(int, int, int); -void bzero(char *, int); -unsigned long inet_addr(char *); -char *inet_ntoa(struct in_addr); -int getdtablesize(); -int connect(int, struct sockaddr *, int); -#endif /* SUNOS4 */ - -/* #if defined(SUNOS4) || defined(SNI) */ -#if defined(SUNOS4) -int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); -#endif /* SUNOS4 || SNI */ - /* * SAFEMEMCPY is an overlap-safe copy from s to d of n bytes */ diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index 1dc53434c..4a611e7f4 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -244,6 +244,28 @@ connection_cleanup(Connection *conn) conn->c_ns_close_jobs = 0; } +static char * +get_ip_str(struct sockaddr *addr, char *str) +{ + switch(addr->sa_family) { + case AF_INET: + if (sizeof(str) < INET_ADDRSTRLEN) { + break; + } + inet_ntop(AF_INET, &(((struct sockaddr_in *)addr)->sin_addr), str, INET_ADDRSTRLEN); + break; + + case AF_INET6: + if (sizeof(str) < INET6_ADDRSTRLEN) { + break; + } + inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)addr)->sin6_addr), str, INET6_ADDRSTRLEN); + break; + } + + return str; +} + /* * Callers of connection_reset() must hold the conn->c_mutex lock. */ @@ -252,7 +274,8 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib { char *pTmp = is_SSL ? "SSL " : ""; char *str_ip = NULL, *str_destip; - char buf_ip[256], buf_destip[256]; + char buf_ip[INET6_ADDRSTRLEN + 1] = {0}; + char buf_destip[INET6_ADDRSTRLEN + 1] = {0}; char *str_unknown = "unknown"; int in_referral_mode = config_check_referral_mode(); @@ -288,10 +311,10 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib (from->ipv6.ip.pr_s6_addr32[1] != 0) || (from->ipv6.ip.pr_s6_addr32[2] != 0) || (from->ipv6.ip.pr_s6_addr32[3] != 0)) || - ((conn->c_prfd != NULL) && (PR_GetPeerName(conn->c_prfd, from) == 0))) { + ((conn->c_prfd != NULL) && (PR_GetPeerName(conn->c_prfd, from) == 0))) + { conn->cin_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr)); memcpy(conn->cin_addr, from, sizeof(PRNetAddr)); - if (PR_IsNetAddrType(conn->cin_addr, PR_IpAddrV4Mapped)) { PRNetAddr v4addr = {{0}}; v4addr.inet.family = PR_AF_INET; @@ -305,7 +328,7 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib } else { /* try syscall since "from" was not given and PR_GetPeerName failed */ /* a corner case */ - struct sockaddr_in addr = {0}; /* assuming IPv4 */ + struct sockaddr addr = {0}; #if (defined(hpux)) int addrlen; #else @@ -315,23 +338,15 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib addrlen = sizeof(addr); if ((conn->c_prfd == NULL) && - (getpeername(conn->c_sd, (struct sockaddr *)&addr, &addrlen) == 0)) { + (getpeername(conn->c_sd, (struct sockaddr *)&addr, &addrlen) == 0)) + { conn->cin_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr)); memset(conn->cin_addr, 0, sizeof(PRNetAddr)); PR_NetAddrFamily(conn->cin_addr) = AF_INET6; /* note: IPv4-mapped IPv6 addr does not work on Windows */ - PR_ConvertIPv4AddrToIPv6(addr.sin_addr.s_addr, &(conn->cin_addr->ipv6.ip)); - PRLDAP_SET_PORT(conn->cin_addr, addr.sin_port); - - /* copy string equivalent of address into a buffer to use for - * logging since each call to inet_ntoa() returns a pointer to a - * single thread-specific buffer (which prevents us from calling - * inet_ntoa() twice in one call to slapi_log_access()). - */ - str_ip = inet_ntoa(addr.sin_addr); - strncpy(buf_ip, str_ip, sizeof(buf_ip) - 1); - buf_ip[sizeof(buf_ip) - 1] = '\0'; - str_ip = buf_ip; + PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)&addr)->sin_addr.s_addr, &(conn->cin_addr->ipv6.ip)); + PRLDAP_SET_PORT(conn->cin_addr, ((struct sockaddr_in *)&addr)->sin_port); + str_ip = get_ip_str(&addr, buf_ip); } else { str_ip = str_unknown; } @@ -367,38 +382,27 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib } else { /* try syscall since c_prfd == NULL */ /* a corner case */ - struct sockaddr_in destaddr = {0}; /* assuming IPv4 */ + struct sockaddr destaddr = {0}; /* assuming IPv4 */ #if (defined(hpux)) int destaddrlen; #else socklen_t destaddrlen; #endif - destaddrlen = sizeof(destaddr); - if ((getsockname(conn->c_sd, (struct sockaddr *)&destaddr, &destaddrlen) == 0)) { + if ((getsockname(conn->c_sd, &destaddr, &destaddrlen) == 0)) { conn->cin_destaddr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr)); memset(conn->cin_destaddr, 0, sizeof(PRNetAddr)); PR_NetAddrFamily(conn->cin_destaddr) = AF_INET6; - PRLDAP_SET_PORT(conn->cin_destaddr, destaddr.sin_port); + PRLDAP_SET_PORT(conn->cin_destaddr, ((struct sockaddr_in *)&destaddr)->sin_port); /* note: IPv4-mapped IPv6 addr does not work on Windows */ - PR_ConvertIPv4AddrToIPv6(destaddr.sin_addr.s_addr, &(conn->cin_destaddr->ipv6.ip)); - - /* copy string equivalent of address into a buffer to use for - * logging since each call to inet_ntoa() returns a pointer to a - * single thread-specific buffer (which prevents us from calling - * inet_ntoa() twice in one call to slapi_log_access()). - */ - str_destip = inet_ntoa(destaddr.sin_addr); - strncpy(buf_destip, str_destip, sizeof(buf_destip) - 1); - buf_destip[sizeof(buf_destip) - 1] = '\0'; - str_destip = buf_destip; + PR_ConvertIPv4AddrToIPv6(((struct sockaddr_in *)&destaddr)->sin_addr.s_addr, &(conn->cin_destaddr->ipv6.ip)); + str_destip = get_ip_str(&destaddr, buf_destip); } else { str_destip = str_unknown; } } - if (!in_referral_mode) { /* create a sasl connection */ ids_sasl_server_new(conn); diff --git a/ldap/servers/slapd/localhost.c b/ldap/servers/slapd/localhost.c index f2aff28f4..993143cbd 100644 --- a/ldap/servers/slapd/localhost.c +++ b/ldap/servers/slapd/localhost.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -45,22 +46,14 @@ static char * find_localhost_DNS(void) { - /* This implementation could (and should) be entirely replaced by: - dns_ip2host ("127.0.0.1", 1); defined in ldapserver/lib/base/dns.c - */ char hostname[MAXHOSTNAMELEN + 1]; - struct hostent *hp; -#ifdef GETHOSTBYNAME_BUF_T - struct hostent hent; - GETHOSTBYNAME_BUF_T hbuf; - int err; -#endif - char **alias; FILE *f; char *cp; char *domain; char line[MAXHOSTNAMELEN + 8]; - + int gai_result; + struct addrinfo hints = {0}; + struct addrinfo *info = NULL, *p = NULL; if (gethostname(hostname, MAXHOSTNAMELEN)) { int oserr = errno; @@ -69,32 +62,34 @@ find_localhost_DNS(void) oserr, slapd_system_strerror(oserr)); return NULL; } - hp = GETHOSTBYNAME(hostname, &hent, hbuf, sizeof(hbuf), &err); - if (hp == NULL) { - int oserr = errno; - slapi_log_err(SLAPI_LOG_ERR, - "find_localhost_DNS - gethostbyname(\"%s\") failed, error %d (%s)\n", - hostname, oserr, slapd_system_strerror(oserr)); - return NULL; - } - if (hp->h_name == NULL) { + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if ((gai_result = getaddrinfo(hostname, NULL, &hints, &info)) != 0) { slapi_log_err(SLAPI_LOG_ERR, "find_localhost_DNS", - "gethostbyname(\"%s\")->h_name == NULL\n", hostname); + "getaddrinfo: %s\n", gai_strerror(gai_result)); return NULL; } - if (strchr(hp->h_name, '.') != NULL) { - slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "h_name == %s\n", hp->h_name); - return slapi_ch_strdup(hp->h_name); - } else if (hp->h_aliases != NULL) { - for (alias = hp->h_aliases; *alias != NULL; ++alias) { - if (strchr(*alias, '.') != NULL && - strncmp(*alias, hp->h_name, strlen(hp->h_name))) { - slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "h_alias == %s\n", *alias); - return slapi_ch_strdup(*alias); - } + + if (strchr(info->ai_canonname, '.') != NULL) { + char *return_name = slapi_ch_strdup(info->ai_canonname); + freeaddrinfo(info); + slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "initial ai_canonname == %s\n", return_name); + return return_name; + } + for(p = info; p != NULL; p = p->ai_next) { + if (strchr(p->ai_canonname, '.') != NULL && + strncmp(p->ai_canonname, info->ai_canonname, strlen(info->ai_canonname))) + { + char *return_name = slapi_ch_strdup(p->ai_canonname); + freeaddrinfo(info); + slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "next ai_canonname == %s\n", return_name); + return return_name; } } + + /* The following is copied from dns_guess_domain(), in ldapserver/lib/base/dnsdmain.c */ domain = NULL; @@ -134,9 +129,10 @@ find_localhost_DNS(void) } #endif if (domain == NULL) { + freeaddrinfo(info); return NULL; } - PL_strncpyz(hostname, hp->h_name, sizeof(hostname)); + PL_strncpyz(hostname, info->ai_canonname, sizeof(hostname)); if (domain[0] == '.') ++domain; if (domain[0]) { @@ -144,6 +140,7 @@ find_localhost_DNS(void) PL_strcatn(hostname, sizeof(hostname), domain); } slapi_log_err(SLAPI_LOG_CONFIG, "find_localhost_DNS", "hostname == %s\n", hostname); + freeaddrinfo(info); return slapi_ch_strdup(hostname); } diff --git a/ldap/servers/slapd/tools/ldclt/repcheck.c b/ldap/servers/slapd/tools/ldclt/repcheck.c index 4340055e5..05ea65a8b 100644 --- a/ldap/servers/slapd/tools/ldclt/repcheck.c +++ b/ldap/servers/slapd/tools/ldclt/repcheck.c @@ -19,6 +19,10 @@ #include "remote.h" #include "lber.h" #include "ldap.h" +#include +#include +#include + enum { @@ -90,13 +94,15 @@ send_op(char *s, int sfd) main(int argc, char **argv) { - int i, port = 16000; - int sockfd; + struct sockaddr_in srvsaddr; static char logline[512]; char **tmp; - struct hostent *serveraddr; - struct sockaddr_in srvsaddr; char *p; + struct addrinfo hints = {0}; + struct addrinfo *info = NULL; + int gai_result = 0; + int i, port = 16000; + int sockfd; while ((i = getopt(argc, argv, "p:")) != EOF) { switch (i) { @@ -105,15 +111,25 @@ main(int argc, char **argv) break; } } - serveraddr = gethostbyname(argv[optind]); - srvsaddr.sin_addr.s_addr = htonl(*((u_long *)(serveraddr->h_addr_list[0]))); + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if ((gai_result = getaddrinfo(argv[optind], NULL, &hints, &info)) != 0) { + slapi_log_err(SLAPI_LOG_ERR, "ldclt", + "getaddrinfo: %s\n", gai_strerror(gai_result)); + return NULL; + } + + srvsaddr.sin_addr.s_addr = htonl(*((u_long *)(info->ai_addr))); srvsaddr.sin_family = AF_INET; srvsaddr.sin_port = htons(port); + freeaddrinfo(info); maxop = npend = 0; pendops = (Optype *)malloc(sizeof(Optype) * 20); sigset(SIGPIPE, SIG_IGN); while (fgets(logline, sizeof(logline), stdin)) { - if (p = strchr(logline, '\n')) { + if ((p = strchr(logline, '\n'))) { *p = 0; } if (!connected) { diff --git a/ldap/servers/slapd/tools/ldclt/repslave.c b/ldap/servers/slapd/tools/ldclt/repslave.c index a04a73f5c..8df2a0ace 100644 --- a/ldap/servers/slapd/tools/ldclt/repslave.c +++ b/ldap/servers/slapd/tools/ldclt/repslave.c @@ -62,6 +62,9 @@ dd/mm/yy | Author | Comments #include "remote.h" #include "lber.h" #include "ldap.h" +#include +#include +#include /* * Enumeration for internal list @@ -221,7 +224,8 @@ main(int argc, char **argv) int sockfd, log = 0; static char logline[512]; char **tmp, *hn, *hp, *hf; - struct hostent *serveraddr; + struct addrinfo hints = {0}; + struct addrinfo *info = NULL; while ((i = getopt(argc, argv, "tdP:s:")) != EOF) { switch (i) { @@ -251,12 +255,17 @@ main(int argc, char **argv) /* * Get master address, just the first. */ - if ((serveraddr = gethostbyname(hn)) == NULL) { + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if (getaddrinfo(hn, NULL, &hints, &info) != 0) { printf("Unknown host %s\n", hn); break; } + srvlist = (Towho *)realloc(srvlist, (nsrv + 1) * sizeof(Towho)); - srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(serveraddr->h_addr_list[0]))); + srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(info->ai_addr))); srvlist[nsrv].addr.sin_family = AF_INET; srvlist[nsrv].addr.sin_port = htonl((hp == hf ? port : atoi(hp))); if ((srvlist[nsrv].filter = regcmp(hf, NULL)) == NULL) @@ -264,6 +273,7 @@ main(int argc, char **argv) srvlist[nsrv].fd = open_cnx((struct sockaddr *)&srvlist[nsrv].addr); srvlist[nsrv].hname = strdup(hn); nsrv++; + freeaddrinfo(info); break; } } @@ -273,18 +283,19 @@ main(int argc, char **argv) printf("\t-t\tprints input on stdout.\n\t-d\tdebug mode.\n"); exit(1); } - srvlist = (Towho *)malloc(sizeof(Towho)); - if ((serveraddr = gethostbyname(argv[optind])) == NULL) { - printf("Unknown host %s\n", argv[optind]); + if (getaddrinfo(argv[optind], NULL, &hints, &info) != 0) { + printf("Unknown host %s\n", hn); exit(1); } - srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(serveraddr->h_addr_list[0]))); + srvlist = (Towho *)malloc(sizeof(Towho)); + srvlist[nsrv].addr.sin_addr.s_addr = htonl(*((u_long *)(info->ai_addr))); srvlist[nsrv].addr.sin_family = AF_INET; srvlist[nsrv].addr.sin_port = htons(port); srvlist[nsrv].filter = NULL; srvlist[nsrv].fd = open_cnx((struct sockaddr *)&srvlist[nsrv].addr); srvlist[nsrv].hname = strdup(argv[optind]); nsrv++; + freeaddrinfo(info); } maxop = npend = 0; pendops = (Optype *)malloc(sizeof(Optype) * 20); diff --git a/lib/base/dns.cpp b/lib/base/dns.cpp deleted file mode 100644 index e704094db..000000000 --- a/lib/base/dns.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * dns.c: DNS resolution routines - * - * Rob McCool - */ -#define DNS_GUESSING - -#include "netsite.h" -#include "systems.h" - -/* Under NT, these are taken care of by net.h including winsock.h */ -#include /* inet_ntoa */ -#include /* struct hostent */ -#ifdef NEED_GHN_PROTO -extern "C" int gethostname (char *name, size_t namelen); -#endif -#include -#include - -/* ---------------------------- dns_find_fqdn ----------------------------- */ - - -/* defined in dnsdmain.c */ -extern "C" NSAPI_PUBLIC char *dns_guess_domain(char * hname); - -char *net_find_fqdn(PRHostEnt *p) -{ - int x; - - if((!p->h_name) || (!p->h_aliases)) - return NULL; - - if(!strchr(p->h_name, '.')) { - for(x = 0; p->h_aliases[x]; ++x) { - if((strchr(p->h_aliases[x], '.')) && - (!strncmp(p->h_aliases[x], p->h_name, strlen(p->h_name)))) - { - return STRDUP(p->h_aliases[x]); - } - } -#ifdef DNS_GUESSING - return dns_guess_domain(p->h_name); -#else - return NULL; -#endif /* DNS_GUESSING */ - } - else - return STRDUP(p->h_name); -} - - -/* ----------------------------- dns_ip2host ------------------------------ */ - - -char *dns_ip2host(char *ip, int verify) -{ - /* struct in_addr iaddr; */ - PRNetAddr iaddr; - char *hn; - static unsigned long laddr = 0; - static char myhostname[256]; - PRHostEnt hent; - char buf[PR_NETDB_BUF_SIZE]; - PRStatus err; - - - err = PR_InitializeNetAddr(PR_IpAddrNull, 0, &iaddr); - - /* richm: ipv6 cleanup - use inet_aton or other more appropriate function - instead of inet_addr */ - if((iaddr.inet.ip = inet_addr(ip)) == (in_addr_t)-1) - goto bong; - - /* - * See if it happens to be the localhost IP address, and try - * the local host name if so. - */ - if (laddr == 0) { - laddr = inet_addr("127.0.0.1"); - myhostname[0] = 0; - PR_GetSystemInfo(PR_SI_HOSTNAME, myhostname, sizeof(myhostname)); - } - - /* Have to match the localhost IP address and have a hostname */ - if ((iaddr.inet.ip == laddr) && (myhostname[0] != 0)) { - /* - * Now try for a fully-qualified domain name, starting with - * the local hostname. - */ - err = PR_GetHostByName(myhostname, - buf, - PR_NETDB_BUF_SIZE, - &hent); - - /* Don't verify if we get a fully-qualified name this way */ - verify = 0; - } - else { - err = PR_GetHostByAddr(&iaddr, - buf, - PR_NETDB_BUF_SIZE, - &hent); - } - - if ((err == PR_FAILURE) || !(hn = net_find_fqdn(&hent))) goto bong; - - - if(verify) { - char **haddr = 0; - err = PR_GetHostByName(hn, - buf, - PR_NETDB_BUF_SIZE, - &hent); - - if(err == PR_SUCCESS) { - for(haddr = hent.h_addr_list; *haddr; haddr++) { - if(((struct in_addr *)(*haddr))->s_addr == iaddr.inet.ip) - break; - } - } - - if((err == PR_FAILURE) || (!(*haddr))) - goto bong; - } - - return hn; - bong: - return NULL; -} diff --git a/lib/base/net.cpp b/lib/base/net.cpp deleted file mode 100644 index 7227d9584..000000000 --- a/lib/base/net.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -/* - * net.c: sockets abstraction and DNS related things - * - * Note: sockets created with net_socket are placed in non-blocking mode, - * however this API simulates that the calls are blocking. - * - * Rob McCool - */ - - -#include "netsite.h" -#include - -#include "util.h" -#include -#include /* inet_ntoa */ -#include /* hostent stuff */ -#ifdef NEED_GHN_PROTO -extern "C" int gethostname (char *name, size_t namelen); -#endif -#ifdef LINUX -#include /* ioctl */ -#endif - -#include "libadmin/libadmin.h" - -/* ---------------------------- util_hostname ----------------------------- */ - - -#include - -/* Defined in dns.cpp */ -char *net_find_fqdn(PRHostEnt *p); - -NSAPI_PUBLIC char *util_hostname(void) -{ - char str[MAXHOSTNAMELEN]; - PRHostEnt hent; - char buf[PR_NETDB_BUF_SIZE]; - PRStatus err; - - gethostname(str, MAXHOSTNAMELEN); - err = PR_GetHostByName( - str, - buf, - PR_NETDB_BUF_SIZE, - &hent); - - if (err == PR_FAILURE) - return NULL; - return net_find_fqdn(&hent); -} - -- 2.21.0