diff --git a/configure.ac b/configure.ac index 94f950c76..e3bda0599 100644 --- a/configure.ac +++ b/configure.ac @@ -783,6 +783,7 @@ AC_CHECK_FUNCS(strdup \ strcasestr \ memrchr \ localtime_r \ + getprotobynumber_r \ gmtime_r \ strnlen \ strtok_r) diff --git a/lib/compat/CMakeLists.txt b/lib/compat/CMakeLists.txt index 4fa05d7e0..95fcb0e0d 100644 --- a/lib/compat/CMakeLists.txt +++ b/lib/compat/CMakeLists.txt @@ -10,7 +10,8 @@ set(COMPAT_HEADERS compat/openssl_support.h compat/pcre.h compat/getent.h - compat/getent-bb.h + compat/getent-sun.h + compat/getent-generic.h PARENT_SCOPE) set(COMPAT_SOURCES @@ -24,7 +25,8 @@ set(COMPAT_SOURCES compat/strnlen.c compat/time.c compat/openssl_support.c - compat/getent.c + compat/getent-sun.c + compat/getent-generic.c PARENT_SCOPE) add_test_subdirectory(tests) diff --git a/lib/compat/Makefile.am b/lib/compat/Makefile.am index e5c1f4e56..8d5010558 100644 --- a/lib/compat/Makefile.am +++ b/lib/compat/Makefile.am @@ -13,9 +13,10 @@ compatinclude_HEADERS = \ lib/compat/string.h \ lib/compat/time.h \ lib/compat/openssl_support.h \ - lib/compat/pcre.h \ - lib/compat/getent.h \ - lib/compat/getent-bb.h + lib/compat/pcre.h \ + lib/compat/getent.h \ + lib/compat/getent-sun.h \ + lib/compat/getent-generic.h compat_sources = \ lib/compat/getutent.c \ @@ -28,6 +29,7 @@ compat_sources = \ lib/compat/strnlen.c \ lib/compat/time.c \ lib/compat/openssl_support.c \ - lib/compat/getent.c + lib/compat/getent-sun.c \ + lib/compat/getent-generic.c include lib/compat/tests/Makefile.am diff --git a/lib/compat/getent-generic.c b/lib/compat/getent-generic.c new file mode 100644 index 000000000..f75d1cc0a --- /dev/null +++ b/lib/compat/getent-generic.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2017 Balabit + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#include "compat/getent-generic.h" + +#ifndef SYSLOG_NG_HAVE_GETPROTOBYNUMBER_R + +#include +#include + +G_LOCK_DEFINE_STATIC(getproto); + +/* this code does not support proto aliases, as we wouldn't be using + * them anyway. Should we ever want to support it, we would need to + * suballocate @buf and store all of the aliases in the same character + * array. + */ +static void +_extract_protoent_fields(struct protoent *dst, struct protoent *src, char *buf, size_t buflen) +{ + g_strlcpy(buf, src->p_name, buflen); + dst->p_name = buf; + dst->p_aliases = NULL; + dst->p_proto = src->p_proto; +} + +int +_compat_generic__getprotobynumber_r(int proto, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result) +{ + struct protoent *pe; + + G_LOCK(getproto); + pe = getprotobynumber(proto); + + if (pe) + { + _extract_protoent_fields(result_buf, pe, buf, buflen); + *result = result_buf; + errno = 0; + } + + G_UNLOCK(getproto); + return errno; +} + +int +_compat_generic__getprotobyname_r(const char *name, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result) +{ + struct protoent *pe; + + G_LOCK(getproto); + pe = getprotobyname(name); + + if (pe) + { + _extract_protoent_fields(result_buf, pe, buf, buflen); + *result = result_buf; + errno = 0; + } + + G_UNLOCK(getproto); + return errno; +} + +G_LOCK_DEFINE_STATIC(getserv); + +/* this code does not support service aliases or using the s_proto field, as + * we wouldn't be using them anyway. Should we ever want to support it, we + * would need to suballocate @buf and store all of the aliases in the same + * character array. + */ +static void +_extract_servent_fields(struct servent *dst, struct servent *src, char *buf, size_t buflen) +{ + g_strlcpy(buf, src->s_name, buflen); + dst->s_name = buf; + dst->s_aliases = NULL; + dst->s_port = src->s_port; + /* we don't support s_proto */ + dst->s_proto = NULL; +} + + +int +_compat_generic__getservbyport_r(int port, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result) +{ + struct servent *se; + + G_LOCK(getserv); + se = getservbyport(port, proto); + + if (se) + { + _extract_servent_fields(result_buf, se, buf, buflen); + *result = result_buf; + errno = 0; + } + + G_UNLOCK(getserv); + return errno; +} + +int +_compat_generic__getservbyname_r(const char *name, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result) +{ + struct servent *se; + + G_LOCK(getserv); + se = getservbyname(name, proto); + + if (se) + { + _extract_servent_fields(result_buf, se, buf, buflen); + *result = result_buf; + errno = 0; + } + + G_UNLOCK(getserv); + return errno; +} + +#endif diff --git a/lib/compat/getent-generic.h b/lib/compat/getent-generic.h new file mode 100644 index 000000000..cc95a2646 --- /dev/null +++ b/lib/compat/getent-generic.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Balabit + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * As an additional exemption you are allowed to compile & link against the + * OpenSSL libraries as published by the OpenSSL project. See the file + * COPYING for details. + * + */ + +#ifndef COMPAT_GETENT_GENERIC_H_INCLUDED +#define COMPAT_GETENT_GENERIC_H_INCLUDED + +#include "compat/compat.h" + +#ifndef SYSLOG_NG_HAVE_GETPROTOBYNUMBER_R + +#include +#include +#include +#include + +int _compat_generic__getprotobynumber_r(int proto, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result); + +int _compat_generic__getprotobyname_r(const char *name, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result); + +int _compat_generic__getservbyport_r(int port, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result); + +int _compat_generic__getservbyname_r(const char *name, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result); + +#endif + +#endif diff --git a/lib/compat/getent.c b/lib/compat/getent-sun.c similarity index 63% rename from lib/compat/getent.c rename to lib/compat/getent-sun.c index bb9b5b431..dce676f2f 100644 --- a/lib/compat/getent.c +++ b/lib/compat/getent-sun.c @@ -21,40 +21,45 @@ * */ -#if defined(sun) || defined(__sun) +#include "compat/getent-sun.h" -#include "compat/getent-bb.h" +#if defined(sun) || defined(__sun) #include -int bb__getprotobynumber_r(int proto, - struct protoent *result_buf, char *buf, - size_t buflen, struct protoent **result) +int +_compat_sun__getprotobynumber_r(int proto, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result) { *result = getprotobynumber_r(proto, result_buf, buf, buflen); return (*result ? NULL : errno); } -int bb__getprotobyname_r(const char *name, - struct protoent *result_buf, char *buf, - size_t buflen, struct protoent **result) +int +_compat_sun__getprotobyname_r(const char *name, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result) { *result = getprotobyname_r(name, result_buf, buf, buflen); return (*result ? NULL : errno); } -int bb__getservbyport_r(int port, const char *proto, - struct servent *result_buf, char *buf, - size_t buflen, struct servent **result) +int +_compat_sun__getservbyport_r(int port, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result) { *result = getservbyport_r(port, proto, result_buf, buf, buflen); return (*result ? NULL : errno); } -int bb__getservbyname_r(const char *name, const char *proto, - struct servent *result_buf, char *buf, - size_t buflen, struct servent **result) +int +_compat_sun__getservbyname_r(const char *name, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result) { *result = getservbyname_r(name, proto, result_buf, buf, buflen); return (*result ? NULL : errno); } + #endif diff --git a/lib/compat/getent-bb.h b/lib/compat/getent-sun.h similarity index 53% rename from lib/compat/getent-bb.h rename to lib/compat/getent-sun.h index 15aa2f5e5..fc1eccd2c 100644 --- a/lib/compat/getent-bb.h +++ b/lib/compat/getent-sun.h @@ -21,8 +21,10 @@ * */ -#ifndef GETENT_BB_H_INCLUDED -#define GETENT_BB_H_INCLUDED +#ifndef COMPAT_GETENT_SUN_H_INCLUDED +#define COMPAT_GETENT_SUN_H_INCLUDED + +#include "compat/compat.h" #if defined(sun) || defined(__sun) @@ -31,21 +33,21 @@ #include #include -int bb__getprotobynumber_r(int proto, - struct protoent *result_buf, char *buf, - size_t buflen, struct protoent **result); +int _compat_sun__getprotobynumber_r(int proto, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result); -int bb__getprotobyname_r(const char *name, - struct protoent *result_buf, char *buf, - size_t buflen, struct protoent **result); +int _compat_sun__getprotobyname_r(const char *name, + struct protoent *result_buf, char *buf, + size_t buflen, struct protoent **result); -int bb__getservbyport_r(int port, const char *proto, - struct servent *result_buf, char *buf, - size_t buflen, struct servent **result); +int _compat_sun__getservbyport_r(int port, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result); -int bb__getservbyname_r(const char *name, const char *proto, - struct servent *result_buf, char *buf, - size_t buflen, struct servent **result); +int _compat_sun__getservbyname_r(const char *name, const char *proto, + struct servent *result_buf, char *buf, + size_t buflen, struct servent **result); #endif diff --git a/lib/compat/getent.h b/lib/compat/getent.h index 09a9f73d6..01c3deb6d 100644 --- a/lib/compat/getent.h +++ b/lib/compat/getent.h @@ -21,22 +21,28 @@ * */ -#ifndef GETENT_COMPAT_H_INCLUDED -#define GETENT_COMPAT_H_INCLUDED +#ifndef COMPAT_GETENT_H_INCLUDED +#define COMPAT_GETENT_H_INCLUDED -#include -#include -#include -#include +#include "compat/compat.h" -#if defined(sun) || defined(__sun) +#ifndef SYSLOG_NG_HAVE_GETPROTOBYNUMBER_R -#define getprotobynumber_r bb__getprotobynumber_r -#define getprotobyname_r bb__getprotobyname_r -#define getservbyport_r bb__getservbyport_r -#define getservbyname_r bb__getservbyname_r +#define getprotobynumber_r _compat_generic__getprotobynumber_r +#define getprotobyname_r _compat_generic__getprotobyname_r +#define getservbyport_r _compat_generic__getservbyport_r +#define getservbyname_r _compat_generic__getservbyname_r -#include "getent-bb.h" +#include "getent-generic.h" -#endif // Solaris +#elif defined(sun) || defined(__sun) + +#define getprotobynumber_r _compat_sun__getprotobynumber_r +#define getprotobyname_r _compat_sun__getprotobyname_r +#define getservbyport_r _compat_sun__getservbyport_r +#define getservbyname_r _compat_sun__getservbyname_r + +#include "getent-sun.h" + +#endif #endif