#50415 Ticket 49361 - Use IPv6 friendly network functions
Closed 3 years ago by spichugi. Opened 4 years ago by mreynolds.
mreynolds/389-ds-base ticket49361  into  master

file modified
-2
@@ -1260,12 +1260,10 @@ 

  	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 \

file modified
+1 -1
@@ -76,7 +76,7 @@ 

  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]))

@@ -13,11 +13,9 @@ 

  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 @@ 

      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 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 @@ 

      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 @@ 

          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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

              '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 @@ 

      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 @@ 

      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 @@ 

  

      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 @@ 

      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 @@ 

          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 @@ 

      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 @@ 

      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 @@ 

      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 @@ 

      # 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 @@ 

      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)

file modified
-3
@@ -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 @@ 

  

  NSPR_END_EXTERN_C

  

- #define util_hostname INTutil_hostname

  #define util_itoa INTutil_itoa

  #define util_vsprintf INTutil_vsprintf

  #define util_sprintf INTutil_sprintf

file modified
-50
@@ -241,30 +241,9 @@ 

  #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 <stdio.h> /* 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 @@ 

  #include <arpa/inet.h> /* for inet_addr() */

  #endif                 /* SOLARIS */

  

- #ifdef SUNOS4

- #include <pcfs/pc_dir.h> /* 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

   */

file modified
+37 -33
@@ -244,6 +244,28 @@ 

      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 @@ 

  {

      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 @@ 

                  (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 @@ 

      } 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 @@ 

          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 @@ 

      } 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);

file modified
+29 -32
@@ -17,6 +17,7 @@ 

  #include <string.h>

  #include <sys/param.h>

  #include <sys/socket.h>

+ #include <netdb.h>

  #include <netinet/in.h>

  #include <arpa/inet.h>

  #include <netdb.h>
@@ -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 @@ 

                        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 @@ 

      }

  #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 @@ 

          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);

  }

  

@@ -19,6 +19,10 @@ 

  #include "remote.h"

  #include "lber.h"

  #include "ldap.h"

+ #include <sys/types.h>

+ #include <sys/socket.h>

+ #include <netdb.h>

+ 

  

  enum

  {
@@ -90,13 +94,15 @@ 

  

  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 @@ 

              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) {

@@ -62,6 +62,9 @@ 

  #include "remote.h"

  #include "lber.h"

  #include "ldap.h"

+ #include <sys/types.h>

+ #include <sys/socket.h>

+ #include <netdb.h>

  

  /*

   * Enumeration for internal list
@@ -221,7 +224,8 @@ 

      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 @@ 

              /*

               * 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 @@ 

              srvlist[nsrv].fd = open_cnx((struct sockaddr *)&srvlist[nsrv].addr);

              srvlist[nsrv].hname = strdup(hn);

              nsrv++;

+             freeaddrinfo(info);

              break;

          }

      }
@@ -273,18 +283,19 @@ 

              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);

file removed
-142
@@ -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 <config.h>

- #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 <arpa/inet.h>  /* inet_ntoa */

- #include <netdb.h>  /* struct hostent */

- #ifdef NEED_GHN_PROTO

- extern "C" int gethostname (char *name, size_t namelen);

- #endif

- #include <stdio.h>

- #include <nspr.h>

- 

- /* ---------------------------- 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;

- }

file removed
-66
@@ -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 <config.h>

- #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 <nspr.h>

- 

- #include "util.h"

- #include <string.h>

- #include <arpa/inet.h>  /* inet_ntoa */

- #include <netdb.h>      /* hostent stuff */

- #ifdef NEED_GHN_PROTO

- extern "C" int gethostname (char *name, size_t namelen);

- #endif

- #ifdef LINUX

- #include <sys/ioctl.h> /* ioctl */

- #endif

- 

- #include "libadmin/libadmin.h"

- 

- /* ---------------------------- util_hostname ----------------------------- */

- 

- 

- #include <sys/param.h>

- 

- /* 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);

- }

- 

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

It could make more sense for inst.delete to better handle different states rather than overriding the state here?

Should we do a size check to make sure the buffers are large enough for this purpose?

Given that inet_addrstrlen is 16, and innet6_addrstrlen is 46, is 256 here too long? We could use INET6_ADDRSTRLEN instead of 256 here ...

I think that most of this looks like an awesome cleanup, great stuff!

It could make more sense for inst.delete to better handle different states rather than overriding the state here?

Weird after I rebased the PR I can not longer reprocue the problem, but I recall it was paths.py that was raising an error during the __get_attr_ call when the state was incorrectly ONLINE. But it seems to be working fine now. Anyway I undid this part of the PR, and applied the other changes.

rebased onto dee51e2523b95f225b95287948268e81931fec7c

4 years ago

I think this all seems good to me, and you fixed all my comments, so I think ack here :) if there are issues we'll probably shake them out in testing, code like this is always hard to judge :(

Thanks!

rebased onto a90dec7

4 years ago

code like this is always hard to judge :(

I know, all I can say is that I did test on IPV6 and IPv4 systems and everything seemed to work fine. Anyway thanks for ack, merging...

Pull-Request has been merged by mreynolds

4 years ago

389-ds-base is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in 389-ds-base's github repository.

This pull request has been cloned to Github as issue and is available here:
- https://github.com/389ds/389-ds-base/issues/3473

If you want to continue to work on the PR, please navigate to the github issue,
download the patch from the attachments and file a new pull request.

Thank you for understanding. We apologize for all inconvenience.

Pull-Request has been closed by spichugi

3 years ago