util-int.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. /* $OpenLDAP$ */
  2. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  3. *
  4. * Copyright 1998-2022 The OpenLDAP Foundation.
  5. * Portions Copyright 1998 A. Hartgers.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted only as authorized by the OpenLDAP
  10. * Public License.
  11. *
  12. * A copy of this license is available in the file LICENSE in the
  13. * top-level directory of the distribution or, alternatively, at
  14. * <http://www.OpenLDAP.org/license.html>.
  15. */
  16. /* ACKNOWLEDGEMENTS:
  17. * This work was initially developed by Bart Hartgers for inclusion in
  18. * OpenLDAP Software.
  19. */
  20. /*
  21. * util-int.c Various functions to replace missing threadsafe ones.
  22. * Without the real *_r funcs, things will
  23. * work, but might not be threadsafe.
  24. */
  25. #include "portable.h"
  26. #include <ac/stdlib.h>
  27. #include <ac/errno.h>
  28. #include <ac/socket.h>
  29. #include <ac/string.h>
  30. #include <ac/time.h>
  31. #include <ac/unistd.h>
  32. #include "ldap-int.h"
  33. #ifndef h_errno
  34. /* newer systems declare this in <netdb.h> for you, older ones don't.
  35. * harmless to declare it again (unless defined by a macro).
  36. */
  37. extern int h_errno;
  38. #endif
  39. #ifdef HAVE_HSTRERROR
  40. # define HSTRERROR(e) hstrerror(e)
  41. #else
  42. # define HSTRERROR(e) hp_strerror(e)
  43. #endif
  44. #ifndef LDAP_R_COMPILE
  45. # undef HAVE_REENTRANT_FUNCTIONS
  46. # undef HAVE_CTIME_R
  47. # undef HAVE_GETHOSTBYNAME_R
  48. # undef HAVE_GETHOSTBYADDR_R
  49. #else
  50. # include <ldap_pvt_thread.h>
  51. ldap_pvt_thread_mutex_t ldap_int_resolv_mutex;
  52. ldap_pvt_thread_mutex_t ldap_int_hostname_mutex;
  53. static ldap_pvt_thread_mutex_t ldap_int_gettime_mutex;
  54. # if (defined( HAVE_CTIME_R ) || defined( HAVE_REENTRANT_FUNCTIONS)) \
  55. && defined( CTIME_R_NARGS )
  56. # define USE_CTIME_R
  57. # else
  58. static ldap_pvt_thread_mutex_t ldap_int_ctime_mutex;
  59. # endif
  60. /* USE_GMTIME_R and USE_LOCALTIME_R defined in ldap_pvt.h */
  61. #if !defined( USE_GMTIME_R ) || !defined( USE_LOCALTIME_R )
  62. /* we use the same mutex for gmtime(3) and localtime(3)
  63. * because implementations may use the same buffer
  64. * for both functions */
  65. static ldap_pvt_thread_mutex_t ldap_int_gmtime_mutex;
  66. #endif
  67. # if defined(HAVE_GETHOSTBYNAME_R) && \
  68. (GETHOSTBYNAME_R_NARGS < 5) || (6 < GETHOSTBYNAME_R_NARGS)
  69. /* Don't know how to handle this version, pretend it's not there */
  70. # undef HAVE_GETHOSTBYNAME_R
  71. # endif
  72. # if defined(HAVE_GETHOSTBYADDR_R) && \
  73. (GETHOSTBYADDR_R_NARGS < 7) || (8 < GETHOSTBYADDR_R_NARGS)
  74. /* Don't know how to handle this version, pretend it's not there */
  75. # undef HAVE_GETHOSTBYADDR_R
  76. # endif
  77. #endif /* LDAP_R_COMPILE */
  78. char *ldap_pvt_ctime( const time_t *tp, char *buf )
  79. {
  80. #ifdef USE_CTIME_R
  81. # if (CTIME_R_NARGS > 3) || (CTIME_R_NARGS < 2)
  82. # error "CTIME_R_NARGS should be 2 or 3"
  83. # elif CTIME_R_NARGS > 2 && defined(CTIME_R_RETURNS_INT)
  84. return( ctime_r(tp,buf,26) < 0 ? 0 : buf );
  85. # elif CTIME_R_NARGS > 2
  86. return ctime_r(tp,buf,26);
  87. # else
  88. return ctime_r(tp,buf);
  89. # endif
  90. #else
  91. LDAP_MUTEX_LOCK( &ldap_int_ctime_mutex );
  92. AC_MEMCPY( buf, ctime(tp), 26 );
  93. LDAP_MUTEX_UNLOCK( &ldap_int_ctime_mutex );
  94. return buf;
  95. #endif
  96. }
  97. #if !defined( USE_GMTIME_R ) || !defined( USE_LOCALTIME_R )
  98. int
  99. ldap_pvt_gmtime_lock( void )
  100. {
  101. # ifndef LDAP_R_COMPILE
  102. return 0;
  103. # else /* LDAP_R_COMPILE */
  104. return ldap_pvt_thread_mutex_lock( &ldap_int_gmtime_mutex );
  105. # endif /* LDAP_R_COMPILE */
  106. }
  107. int
  108. ldap_pvt_gmtime_unlock( void )
  109. {
  110. # ifndef LDAP_R_COMPILE
  111. return 0;
  112. # else /* LDAP_R_COMPILE */
  113. return ldap_pvt_thread_mutex_unlock( &ldap_int_gmtime_mutex );
  114. # endif /* LDAP_R_COMPILE */
  115. }
  116. #endif /* !USE_GMTIME_R || !USE_LOCALTIME_R */
  117. #ifndef USE_GMTIME_R
  118. struct tm *
  119. ldap_pvt_gmtime( const time_t *timep, struct tm *result )
  120. {
  121. struct tm *tm_ptr;
  122. LDAP_MUTEX_LOCK( &ldap_int_gmtime_mutex );
  123. tm_ptr = gmtime( timep );
  124. if ( tm_ptr == NULL ) {
  125. result = NULL;
  126. } else {
  127. *result = *tm_ptr;
  128. }
  129. LDAP_MUTEX_UNLOCK( &ldap_int_gmtime_mutex );
  130. return result;
  131. }
  132. #endif /* !USE_GMTIME_R */
  133. #ifndef USE_LOCALTIME_R
  134. struct tm *
  135. ldap_pvt_localtime( const time_t *timep, struct tm *result )
  136. {
  137. struct tm *tm_ptr;
  138. LDAP_MUTEX_LOCK( &ldap_int_gmtime_mutex );
  139. tm_ptr = localtime( timep );
  140. if ( tm_ptr == NULL ) {
  141. result = NULL;
  142. } else {
  143. *result = *tm_ptr;
  144. }
  145. LDAP_MUTEX_UNLOCK( &ldap_int_gmtime_mutex );
  146. return result;
  147. }
  148. #endif /* !USE_LOCALTIME_R */
  149. static int _ldap_pvt_gt_subs;
  150. #ifdef _WIN32
  151. /* Windows SYSTEMTIME only has 10 millisecond resolution, so we
  152. * also need to use a high resolution timer to get nanoseconds.
  153. * This is pretty clunky.
  154. */
  155. static LARGE_INTEGER _ldap_pvt_gt_freq;
  156. static LARGE_INTEGER _ldap_pvt_gt_prev;
  157. static int _ldap_pvt_gt_offset;
  158. #define SEC_TO_UNIX_EPOCH 11644473600LL
  159. #define TICKS_PER_SECOND 10000000
  160. #define BILLION 1000000000L
  161. static int
  162. ldap_pvt_gettimensec(int *sec)
  163. {
  164. LARGE_INTEGER count;
  165. QueryPerformanceCounter( &count );
  166. /* It shouldn't ever go backwards, but multiple CPUs might
  167. * be able to hit in the same tick.
  168. */
  169. LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
  170. /* We assume Windows has at least a vague idea of
  171. * when a second begins. So we align our nanosecond count
  172. * with the Windows millisecond count using this offset.
  173. * We retain the submillisecond portion of our own count.
  174. *
  175. * Note - this also assumes that the relationship between
  176. * the PerformanceCounter and SystemTime stays constant;
  177. * that assumption breaks if the SystemTime is adjusted by
  178. * an external action.
  179. */
  180. if ( !_ldap_pvt_gt_freq.QuadPart ) {
  181. LARGE_INTEGER c2;
  182. ULARGE_INTEGER ut;
  183. FILETIME ft0, ft1;
  184. long long t;
  185. int nsec;
  186. /* Initialize our offset */
  187. QueryPerformanceFrequency( &_ldap_pvt_gt_freq );
  188. /* Wait for a tick of the system time: 10-15ms */
  189. GetSystemTimeAsFileTime( &ft0 );
  190. do {
  191. GetSystemTimeAsFileTime( &ft1 );
  192. } while ( ft1.dwLowDateTime == ft0.dwLowDateTime );
  193. ut.LowPart = ft1.dwLowDateTime;
  194. ut.HighPart = ft1.dwHighDateTime;
  195. QueryPerformanceCounter( &c2 );
  196. /* get second and fraction portion of counter */
  197. t = c2.QuadPart % (_ldap_pvt_gt_freq.QuadPart*10);
  198. /* convert to nanoseconds */
  199. t *= BILLION;
  200. nsec = t / _ldap_pvt_gt_freq.QuadPart;
  201. ut.QuadPart /= 10;
  202. ut.QuadPart %= (10 * BILLION);
  203. _ldap_pvt_gt_offset = nsec - ut.QuadPart;
  204. count = c2;
  205. }
  206. if ( count.QuadPart <= _ldap_pvt_gt_prev.QuadPart ) {
  207. _ldap_pvt_gt_subs++;
  208. } else {
  209. _ldap_pvt_gt_subs = 0;
  210. _ldap_pvt_gt_prev = count;
  211. }
  212. LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );
  213. /* convert to nanoseconds */
  214. count.QuadPart %= _ldap_pvt_gt_freq.QuadPart*10;
  215. count.QuadPart *= BILLION;
  216. count.QuadPart /= _ldap_pvt_gt_freq.QuadPart;
  217. count.QuadPart -= _ldap_pvt_gt_offset;
  218. /* We've extracted the 1s and nanoseconds.
  219. * The 1sec digit is used to detect wraparound in nanosecnds.
  220. */
  221. if (count.QuadPart < 0)
  222. count.QuadPart += (10 * BILLION);
  223. else if (count.QuadPart >= (10 * BILLION))
  224. count.QuadPart -= (10 * BILLION);
  225. *sec = count.QuadPart / BILLION;
  226. return count.QuadPart % BILLION;
  227. }
  228. /* emulate POSIX clock_gettime */
  229. int
  230. ldap_pvt_clock_gettime( int clk_id, struct timespec *tv )
  231. {
  232. FILETIME ft;
  233. ULARGE_INTEGER ut;
  234. int sec, sec0;
  235. GetSystemTimeAsFileTime( &ft );
  236. ut.LowPart = ft.dwLowDateTime;
  237. ut.HighPart = ft.dwHighDateTime;
  238. /* convert to sec */
  239. ut.QuadPart /= TICKS_PER_SECOND;
  240. tv->tv_nsec = ldap_pvt_gettimensec(&sec);
  241. tv->tv_sec = ut.QuadPart - SEC_TO_UNIX_EPOCH;
  242. /* check for carry from microseconds */
  243. sec0 = tv->tv_sec % 10;
  244. if (sec0 < sec || (sec0 == 9 && !sec))
  245. tv->tv_sec++;
  246. return 0;
  247. }
  248. /* emulate POSIX gettimeofday */
  249. int
  250. ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
  251. {
  252. struct timespec ts;
  253. ldap_pvt_clock_gettime( 0, &ts );
  254. tv->tv_sec = ts.tv_sec;
  255. tv->tv_usec = ts.tv_nsec / 1000;
  256. return 0;
  257. }
  258. /* return a broken out time, with nanoseconds
  259. */
  260. void
  261. ldap_pvt_gettime( struct lutil_tm *tm )
  262. {
  263. SYSTEMTIME st;
  264. int sec, sec0;
  265. static const char daysPerMonth[] = {
  266. 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  267. GetSystemTime( &st );
  268. tm->tm_nsec = ldap_pvt_gettimensec(&sec);
  269. tm->tm_usub = _ldap_pvt_gt_subs;
  270. /* any difference larger than nanoseconds is
  271. * already reflected in st
  272. */
  273. tm->tm_sec = st.wSecond;
  274. tm->tm_min = st.wMinute;
  275. tm->tm_hour = st.wHour;
  276. tm->tm_mday = st.wDay;
  277. tm->tm_mon = st.wMonth - 1;
  278. tm->tm_year = st.wYear - 1900;
  279. /* check for carry from nanoseconds */
  280. sec0 = tm->tm_sec % 10;
  281. if (sec0 < sec || (sec0 == 9 && !sec)) {
  282. tm->tm_sec++;
  283. /* FIXME: we don't handle leap seconds */
  284. if (tm->tm_sec > 59) {
  285. tm->tm_sec = 0;
  286. tm->tm_min++;
  287. if (tm->tm_min > 59) {
  288. tm->tm_min = 0;
  289. tm->tm_hour++;
  290. if (tm->tm_hour > 23) {
  291. int days = daysPerMonth[tm->tm_mon];
  292. tm->tm_hour = 0;
  293. tm->tm_mday++;
  294. /* if it's February of a leap year,
  295. * add 1 day to this month
  296. */
  297. if (tm->tm_mon == 1 &&
  298. ((!(st.wYear % 4) && (st.wYear % 100)) ||
  299. !(st.wYear % 400)))
  300. days++;
  301. if (tm->tm_mday > days) {
  302. tm->tm_mday = 1;
  303. tm->tm_mon++;
  304. if (tm->tm_mon > 11) {
  305. tm->tm_mon = 0;
  306. tm->tm_year++;
  307. }
  308. }
  309. }
  310. }
  311. }
  312. }
  313. }
  314. #else
  315. #ifdef HAVE_CLOCK_GETTIME
  316. static struct timespec _ldap_pvt_gt_prevTv;
  317. #else
  318. static struct timeval _ldap_pvt_gt_prevTv;
  319. #endif
  320. void
  321. ldap_pvt_gettime( struct lutil_tm *ltm )
  322. {
  323. struct tm tm;
  324. time_t t;
  325. #ifdef HAVE_CLOCK_GETTIME
  326. #define FRAC tv_nsec
  327. #define NSECS(x) x
  328. struct timespec tv;
  329. clock_gettime( CLOCK_REALTIME, &tv );
  330. #else
  331. #define FRAC tv_usec
  332. #define NSECS(x) x * 1000
  333. struct timeval tv;
  334. gettimeofday( &tv, NULL );
  335. #endif
  336. t = tv.tv_sec;
  337. LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
  338. if ( tv.tv_sec < _ldap_pvt_gt_prevTv.tv_sec
  339. || ( tv.tv_sec == _ldap_pvt_gt_prevTv.tv_sec
  340. && tv.FRAC <= _ldap_pvt_gt_prevTv.FRAC )) {
  341. _ldap_pvt_gt_subs++;
  342. } else {
  343. _ldap_pvt_gt_subs = 0;
  344. _ldap_pvt_gt_prevTv = tv;
  345. }
  346. LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );
  347. ltm->tm_usub = _ldap_pvt_gt_subs;
  348. ldap_pvt_gmtime( &t, &tm );
  349. ltm->tm_sec = tm.tm_sec;
  350. ltm->tm_min = tm.tm_min;
  351. ltm->tm_hour = tm.tm_hour;
  352. ltm->tm_mday = tm.tm_mday;
  353. ltm->tm_mon = tm.tm_mon;
  354. ltm->tm_year = tm.tm_year;
  355. ltm->tm_nsec = NSECS(tv.FRAC);
  356. }
  357. #endif
  358. size_t
  359. ldap_pvt_csnstr(char *buf, size_t len, unsigned int replica, unsigned int mod)
  360. {
  361. struct lutil_tm tm;
  362. int n;
  363. ldap_pvt_gettime( &tm );
  364. n = snprintf( buf, len,
  365. "%4d%02d%02d%02d%02d%02d.%06dZ#%06x#%03x#%06x",
  366. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
  367. tm.tm_min, tm.tm_sec, tm.tm_nsec / 1000, tm.tm_usub, replica, mod );
  368. if( n < 0 ) return 0;
  369. return ( (size_t) n < len ) ? n : 0;
  370. }
  371. #define BUFSTART (1024-32)
  372. #define BUFMAX (32*1024-32)
  373. #if defined(LDAP_R_COMPILE)
  374. static char *safe_realloc( char **buf, int len );
  375. #if !(defined(HAVE_GETHOSTBYNAME_R) && defined(HAVE_GETHOSTBYADDR_R))
  376. static int copy_hostent( struct hostent *res,
  377. char **buf, struct hostent * src );
  378. #endif
  379. #endif
  380. int ldap_pvt_gethostbyname_a(
  381. const char *name,
  382. struct hostent *resbuf,
  383. char **buf,
  384. struct hostent **result,
  385. int *herrno_ptr )
  386. {
  387. #if defined( HAVE_GETHOSTBYNAME_R )
  388. # define NEED_SAFE_REALLOC 1
  389. int r=-1;
  390. int buflen=BUFSTART;
  391. *buf = NULL;
  392. for(;buflen<BUFMAX;) {
  393. if (safe_realloc( buf, buflen )==NULL)
  394. return r;
  395. #if (GETHOSTBYNAME_R_NARGS < 6)
  396. *result=gethostbyname_r( name, resbuf, *buf, buflen, herrno_ptr );
  397. r = (*result == NULL) ? -1 : 0;
  398. #else
  399. while((r = gethostbyname_r( name, resbuf, *buf, buflen, result, herrno_ptr )) == ERANGE) {
  400. /* Increase the buffer */
  401. buflen*=2;
  402. if (safe_realloc(buf, buflen) == NULL)
  403. return -1;
  404. }
  405. #endif
  406. Debug2( LDAP_DEBUG_TRACE, "ldap_pvt_gethostbyname_a: host=%s, r=%d\n",
  407. name, r );
  408. #ifdef NETDB_INTERNAL
  409. if ((r<0) &&
  410. (*herrno_ptr==NETDB_INTERNAL) &&
  411. (errno==ERANGE))
  412. {
  413. buflen*=2;
  414. continue;
  415. }
  416. #endif
  417. return r;
  418. }
  419. return -1;
  420. #elif defined( LDAP_R_COMPILE )
  421. # define NEED_COPY_HOSTENT
  422. struct hostent *he;
  423. int retval;
  424. *buf = NULL;
  425. LDAP_MUTEX_LOCK( &ldap_int_resolv_mutex );
  426. he = gethostbyname( name );
  427. if (he==NULL) {
  428. *herrno_ptr = h_errno;
  429. retval = -1;
  430. } else if (copy_hostent( resbuf, buf, he )<0) {
  431. *herrno_ptr = -1;
  432. retval = -1;
  433. } else {
  434. *result = resbuf;
  435. retval = 0;
  436. }
  437. LDAP_MUTEX_UNLOCK( &ldap_int_resolv_mutex );
  438. return retval;
  439. #else
  440. *buf = NULL;
  441. *result = gethostbyname( name );
  442. if (*result!=NULL) {
  443. return 0;
  444. }
  445. *herrno_ptr = h_errno;
  446. return -1;
  447. #endif
  448. }
  449. #if !defined( HAVE_GETNAMEINFO ) && !defined( HAVE_HSTRERROR )
  450. static const char *
  451. hp_strerror( int err )
  452. {
  453. switch (err) {
  454. case HOST_NOT_FOUND: return _("Host not found (authoritative)");
  455. case TRY_AGAIN: return _("Host not found (server fail?)");
  456. case NO_RECOVERY: return _("Non-recoverable failure");
  457. case NO_DATA: return _("No data of requested type");
  458. #ifdef NETDB_INTERNAL
  459. case NETDB_INTERNAL: return STRERROR( errno );
  460. #endif
  461. }
  462. return _("Unknown resolver error");
  463. }
  464. #endif
  465. int ldap_pvt_get_hname(
  466. const struct sockaddr *sa,
  467. int len,
  468. char *name,
  469. int namelen,
  470. char **err )
  471. {
  472. int rc;
  473. #if defined( HAVE_GETNAMEINFO )
  474. LDAP_MUTEX_LOCK( &ldap_int_resolv_mutex );
  475. rc = getnameinfo( sa, len, name, namelen, NULL, 0, 0 );
  476. LDAP_MUTEX_UNLOCK( &ldap_int_resolv_mutex );
  477. if ( rc ) *err = (char *)AC_GAI_STRERROR( rc );
  478. return rc;
  479. #else /* !HAVE_GETNAMEINFO */
  480. char *addr;
  481. int alen;
  482. struct hostent *hp = NULL;
  483. #ifdef HAVE_GETHOSTBYADDR_R
  484. struct hostent hb;
  485. int buflen=BUFSTART, h_errno;
  486. char *buf=NULL;
  487. #endif
  488. #ifdef LDAP_PF_INET6
  489. if (sa->sa_family == AF_INET6) {
  490. struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
  491. addr = (char *)&sin->sin6_addr;
  492. alen = sizeof(sin->sin6_addr);
  493. } else
  494. #endif
  495. if (sa->sa_family == AF_INET) {
  496. struct sockaddr_in *sin = (struct sockaddr_in *)sa;
  497. addr = (char *)&sin->sin_addr;
  498. alen = sizeof(sin->sin_addr);
  499. } else {
  500. rc = NO_RECOVERY;
  501. *err = (char *)HSTRERROR( rc );
  502. return rc;
  503. }
  504. #if defined( HAVE_GETHOSTBYADDR_R )
  505. for(;buflen<BUFMAX;) {
  506. if (safe_realloc( &buf, buflen )==NULL) {
  507. *err = (char *)STRERROR( ENOMEM );
  508. return ENOMEM;
  509. }
  510. #if (GETHOSTBYADDR_R_NARGS < 8)
  511. hp=gethostbyaddr_r( addr, alen, sa->sa_family,
  512. &hb, buf, buflen, &h_errno );
  513. rc = (hp == NULL) ? -1 : 0;
  514. #else
  515. rc = gethostbyaddr_r( addr, alen, sa->sa_family,
  516. &hb, buf, buflen,
  517. &hp, &h_errno );
  518. #endif
  519. #ifdef NETDB_INTERNAL
  520. if ((rc<0) &&
  521. (h_errno==NETDB_INTERNAL) &&
  522. (errno==ERANGE))
  523. {
  524. buflen*=2;
  525. continue;
  526. }
  527. #endif
  528. break;
  529. }
  530. if (hp) {
  531. strncpy( name, hp->h_name, namelen );
  532. } else {
  533. *err = (char *)HSTRERROR( h_errno );
  534. }
  535. LDAP_FREE(buf);
  536. #else /* HAVE_GETHOSTBYADDR_R */
  537. LDAP_MUTEX_LOCK( &ldap_int_resolv_mutex );
  538. hp = gethostbyaddr( addr, alen, sa->sa_family );
  539. if (hp) {
  540. strncpy( name, hp->h_name, namelen );
  541. rc = 0;
  542. } else {
  543. rc = h_errno;
  544. *err = (char *)HSTRERROR( h_errno );
  545. }
  546. LDAP_MUTEX_UNLOCK( &ldap_int_resolv_mutex );
  547. #endif /* !HAVE_GETHOSTBYADDR_R */
  548. return rc;
  549. #endif /* !HAVE_GETNAMEINFO */
  550. }
  551. int ldap_pvt_gethostbyaddr_a(
  552. const char *addr,
  553. int len,
  554. int type,
  555. struct hostent *resbuf,
  556. char **buf,
  557. struct hostent **result,
  558. int *herrno_ptr )
  559. {
  560. #if defined( HAVE_GETHOSTBYADDR_R )
  561. # undef NEED_SAFE_REALLOC
  562. # define NEED_SAFE_REALLOC
  563. int r=-1;
  564. int buflen=BUFSTART;
  565. *buf = NULL;
  566. for(;buflen<BUFMAX;) {
  567. if (safe_realloc( buf, buflen )==NULL)
  568. return r;
  569. #if (GETHOSTBYADDR_R_NARGS < 8)
  570. *result=gethostbyaddr_r( addr, len, type,
  571. resbuf, *buf, buflen, herrno_ptr );
  572. r = (*result == NULL) ? -1 : 0;
  573. #else
  574. r = gethostbyaddr_r( addr, len, type,
  575. resbuf, *buf, buflen,
  576. result, herrno_ptr );
  577. #endif
  578. #ifdef NETDB_INTERNAL
  579. if ((r<0) &&
  580. (*herrno_ptr==NETDB_INTERNAL) &&
  581. (errno==ERANGE))
  582. {
  583. buflen*=2;
  584. continue;
  585. }
  586. #endif
  587. return r;
  588. }
  589. return -1;
  590. #elif defined( LDAP_R_COMPILE )
  591. # undef NEED_COPY_HOSTENT
  592. # define NEED_COPY_HOSTENT
  593. struct hostent *he;
  594. int retval;
  595. *buf = NULL;
  596. LDAP_MUTEX_LOCK( &ldap_int_resolv_mutex );
  597. he = gethostbyaddr( addr, len, type );
  598. if (he==NULL) {
  599. *herrno_ptr = h_errno;
  600. retval = -1;
  601. } else if (copy_hostent( resbuf, buf, he )<0) {
  602. *herrno_ptr = -1;
  603. retval = -1;
  604. } else {
  605. *result = resbuf;
  606. retval = 0;
  607. }
  608. LDAP_MUTEX_UNLOCK( &ldap_int_resolv_mutex );
  609. return retval;
  610. #else /* gethostbyaddr() */
  611. *buf = NULL;
  612. *result = gethostbyaddr( addr, len, type );
  613. if (*result!=NULL) {
  614. return 0;
  615. }
  616. return -1;
  617. #endif
  618. }
  619. /*
  620. * ldap_int_utils_init() should be called before any other function.
  621. */
  622. void ldap_int_utils_init( void )
  623. {
  624. static int done=0;
  625. if (done)
  626. return;
  627. done=1;
  628. #ifdef LDAP_R_COMPILE
  629. #if !defined( USE_CTIME_R ) && !defined( HAVE_REENTRANT_FUNCTIONS )
  630. ldap_pvt_thread_mutex_init( &ldap_int_ctime_mutex );
  631. #endif
  632. #if !defined( USE_GMTIME_R ) && !defined( USE_LOCALTIME_R )
  633. ldap_pvt_thread_mutex_init( &ldap_int_gmtime_mutex );
  634. #endif
  635. ldap_pvt_thread_mutex_init( &ldap_int_resolv_mutex );
  636. ldap_pvt_thread_mutex_init( &ldap_int_hostname_mutex );
  637. ldap_pvt_thread_mutex_init( &ldap_int_gettime_mutex );
  638. #endif
  639. /* call other module init functions here... */
  640. }
  641. #if defined( NEED_COPY_HOSTENT )
  642. # undef NEED_SAFE_REALLOC
  643. #define NEED_SAFE_REALLOC
  644. static char *cpy_aliases(
  645. char ***tgtio,
  646. char *buf,
  647. char **src )
  648. {
  649. int len;
  650. char **tgt=*tgtio;
  651. for( ; (*src) ; src++ ) {
  652. len = strlen( *src ) + 1;
  653. AC_MEMCPY( buf, *src, len );
  654. *tgt++=buf;
  655. buf+=len;
  656. }
  657. *tgtio=tgt;
  658. return buf;
  659. }
  660. static char *cpy_addresses(
  661. char ***tgtio,
  662. char *buf,
  663. char **src,
  664. int len )
  665. {
  666. char **tgt=*tgtio;
  667. for( ; (*src) ; src++ ) {
  668. AC_MEMCPY( buf, *src, len );
  669. *tgt++=buf;
  670. buf+=len;
  671. }
  672. *tgtio=tgt;
  673. return buf;
  674. }
  675. static int copy_hostent(
  676. struct hostent *res,
  677. char **buf,
  678. struct hostent * src )
  679. {
  680. char **p;
  681. char **tp;
  682. char *tbuf;
  683. int name_len;
  684. int n_alias=0;
  685. int total_alias_len=0;
  686. int n_addr=0;
  687. int total_addr_len=0;
  688. int total_len;
  689. /* calculate the size needed for the buffer */
  690. name_len = strlen( src->h_name ) + 1;
  691. if( src->h_aliases != NULL ) {
  692. for( p = src->h_aliases; (*p) != NULL; p++ ) {
  693. total_alias_len += strlen( *p ) + 1;
  694. n_alias++;
  695. }
  696. }
  697. if( src->h_addr_list != NULL ) {
  698. for( p = src->h_addr_list; (*p) != NULL; p++ ) {
  699. n_addr++;
  700. }
  701. total_addr_len = n_addr * src->h_length;
  702. }
  703. total_len = (n_alias + n_addr + 2) * sizeof( char * ) +
  704. total_addr_len + total_alias_len + name_len;
  705. if (safe_realloc( buf, total_len )) {
  706. tp = (char **) *buf;
  707. tbuf = *buf + (n_alias + n_addr + 2) * sizeof( char * );
  708. AC_MEMCPY( res, src, sizeof( struct hostent ) );
  709. /* first the name... */
  710. AC_MEMCPY( tbuf, src->h_name, name_len );
  711. res->h_name = tbuf; tbuf+=name_len;
  712. /* now the aliases */
  713. res->h_aliases = tp;
  714. if ( src->h_aliases != NULL ) {
  715. tbuf = cpy_aliases( &tp, tbuf, src->h_aliases );
  716. }
  717. *tp++=NULL;
  718. /* finally the addresses */
  719. res->h_addr_list = tp;
  720. if ( src->h_addr_list != NULL ) {
  721. tbuf = cpy_addresses( &tp, tbuf, src->h_addr_list, src->h_length );
  722. }
  723. *tp++=NULL;
  724. return 0;
  725. }
  726. return -1;
  727. }
  728. #endif
  729. #if defined( NEED_SAFE_REALLOC )
  730. static char *safe_realloc( char **buf, int len )
  731. {
  732. char *tmpbuf;
  733. tmpbuf = LDAP_REALLOC( *buf, len );
  734. if (tmpbuf) {
  735. *buf=tmpbuf;
  736. }
  737. return tmpbuf;
  738. }
  739. #endif
  740. char * ldap_pvt_get_fqdn( char *name )
  741. {
  742. #ifdef HAVE_GETADDRINFO
  743. struct addrinfo hints, *res;
  744. #else
  745. char *ha_buf;
  746. struct hostent *hp, he_buf;
  747. int local_h_errno;
  748. #endif
  749. int rc;
  750. char *fqdn, hostbuf[MAXHOSTNAMELEN+1];
  751. if( name == NULL ) {
  752. if( gethostname( hostbuf, MAXHOSTNAMELEN ) == 0 ) {
  753. hostbuf[MAXHOSTNAMELEN] = '\0';
  754. name = hostbuf;
  755. } else {
  756. name = "localhost";
  757. }
  758. }
  759. #ifdef HAVE_GETADDRINFO
  760. memset( &hints, 0, sizeof( hints ));
  761. hints.ai_family = AF_UNSPEC;
  762. hints.ai_flags = AI_CANONNAME;
  763. LDAP_MUTEX_LOCK( &ldap_int_resolv_mutex );
  764. rc = getaddrinfo( name, NULL, &hints, &res );
  765. LDAP_MUTEX_UNLOCK( &ldap_int_resolv_mutex );
  766. if ( rc == 0 && res->ai_canonname ) {
  767. fqdn = LDAP_STRDUP( res->ai_canonname );
  768. } else {
  769. fqdn = LDAP_STRDUP( name );
  770. }
  771. if ( rc == 0 )
  772. freeaddrinfo( res );
  773. #else
  774. rc = ldap_pvt_gethostbyname_a( name,
  775. &he_buf, &ha_buf, &hp, &local_h_errno );
  776. if( rc < 0 || hp == NULL || hp->h_name == NULL ) {
  777. fqdn = LDAP_STRDUP( name );
  778. } else {
  779. fqdn = LDAP_STRDUP( hp->h_name );
  780. }
  781. LDAP_FREE( ha_buf );
  782. #endif
  783. return fqdn;
  784. }
  785. #if ( defined( HAVE_GETADDRINFO ) || defined( HAVE_GETNAMEINFO ) ) \
  786. && !defined( HAVE_GAI_STRERROR )
  787. char *ldap_pvt_gai_strerror (int code) {
  788. static struct {
  789. int code;
  790. const char *msg;
  791. } values[] = {
  792. #ifdef EAI_ADDRFAMILY
  793. { EAI_ADDRFAMILY, N_("Address family for hostname not supported") },
  794. #endif
  795. { EAI_AGAIN, N_("Temporary failure in name resolution") },
  796. { EAI_BADFLAGS, N_("Bad value for ai_flags") },
  797. { EAI_FAIL, N_("Non-recoverable failure in name resolution") },
  798. { EAI_FAMILY, N_("ai_family not supported") },
  799. { EAI_MEMORY, N_("Memory allocation failure") },
  800. #ifdef EAI_NODATA
  801. { EAI_NODATA, N_("No address associated with hostname") },
  802. #endif
  803. { EAI_NONAME, N_("Name or service not known") },
  804. { EAI_SERVICE, N_("Servname not supported for ai_socktype") },
  805. { EAI_SOCKTYPE, N_("ai_socktype not supported") },
  806. #ifdef EAI_SYSTEM
  807. { EAI_SYSTEM, N_("System error") },
  808. #endif
  809. { 0, NULL }
  810. };
  811. int i;
  812. for ( i = 0; values[i].msg != NULL; i++ ) {
  813. if ( values[i].code == code ) {
  814. return (char *) _(values[i].msg);
  815. }
  816. }
  817. return _("Unknown error");
  818. }
  819. #endif
  820. /* format a socket address as a string */
  821. #ifdef HAVE_TCPD
  822. # include <tcpd.h>
  823. # define SOCKADDR_STRING_UNKNOWN STRING_UNKNOWN
  824. #else /* ! TCP Wrappers */
  825. # define SOCKADDR_STRING_UNKNOWN "unknown"
  826. #endif /* ! TCP Wrappers */
  827. void
  828. ldap_pvt_sockaddrstr( Sockaddr *sa, struct berval *addrbuf )
  829. {
  830. char *addr;
  831. switch( sa->sa_addr.sa_family ) {
  832. #ifdef LDAP_PF_LOCAL
  833. case AF_LOCAL:
  834. addrbuf->bv_len = snprintf( addrbuf->bv_val, addrbuf->bv_len,
  835. "PATH=%s", sa->sa_un_addr.sun_path );
  836. break;
  837. #endif
  838. #ifdef LDAP_PF_INET6
  839. case AF_INET6:
  840. strcpy(addrbuf->bv_val, "IP=");
  841. if ( IN6_IS_ADDR_V4MAPPED(&sa->sa_in6_addr.sin6_addr) ) {
  842. #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
  843. addr = (char *)inet_ntop( AF_INET,
  844. ((struct in_addr *)&sa->sa_in6_addr.sin6_addr.s6_addr[12]),
  845. addrbuf->bv_val+3, addrbuf->bv_len-3 );
  846. #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
  847. addr = inet_ntoa( *((struct in_addr *)
  848. &sa->sa_in6_addr.sin6_addr.s6_addr[12]) );
  849. #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
  850. if ( !addr ) addr = SOCKADDR_STRING_UNKNOWN;
  851. if ( addr != addrbuf->bv_val+3 ) {
  852. addrbuf->bv_len = sprintf( addrbuf->bv_val+3, "%s:%d", addr,
  853. (unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + 3;
  854. } else {
  855. int len = strlen( addr );
  856. addrbuf->bv_len = sprintf( addr+len, ":%d",
  857. (unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + len + 3;
  858. }
  859. } else {
  860. addr = (char *)inet_ntop( AF_INET6,
  861. &sa->sa_in6_addr.sin6_addr,
  862. addrbuf->bv_val+4, addrbuf->bv_len-4 );
  863. if ( !addr ) addr = SOCKADDR_STRING_UNKNOWN;
  864. if ( addr != addrbuf->bv_val+4 ) {
  865. addrbuf->bv_len = sprintf( addrbuf->bv_val+3, "[%s]:%d", addr,
  866. (unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + 3;
  867. } else {
  868. int len = strlen( addr );
  869. addrbuf->bv_val[3] = '[';
  870. addrbuf->bv_len = sprintf( addr+len, "]:%d",
  871. (unsigned) ntohs( sa->sa_in6_addr.sin6_port ) ) + len + 4;
  872. }
  873. }
  874. break;
  875. #endif /* LDAP_PF_INET6 */
  876. case AF_INET:
  877. strcpy(addrbuf->bv_val, "IP=");
  878. #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP )
  879. addr = (char *)inet_ntop( AF_INET, &sa->sa_in_addr.sin_addr,
  880. addrbuf->bv_val+3, addrbuf->bv_len-3 );
  881. #else /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
  882. addr = inet_ntoa( sa->sa_in_addr.sin_addr );
  883. #endif /* ! HAVE_GETADDRINFO || ! HAVE_INET_NTOP */
  884. if ( !addr ) addr = SOCKADDR_STRING_UNKNOWN;
  885. if ( addr != addrbuf->bv_val+3 ) {
  886. addrbuf->bv_len = sprintf( addrbuf->bv_val+3, "%s:%d", addr,
  887. (unsigned) ntohs( sa->sa_in_addr.sin_port ) ) + 3;
  888. } else {
  889. int len = strlen( addr );
  890. addrbuf->bv_len = sprintf( addr+len, ":%d",
  891. (unsigned) ntohs( sa->sa_in_addr.sin_port ) ) + len + 3;
  892. }
  893. break;
  894. default:
  895. addrbuf->bv_val[0] = '\0';
  896. }
  897. }