From: Gary Lockyer Date: Thu, 1 Jun 2017 01:26:38 +0000 (+1200) Subject: strerror_r: provide XSI-compliant strerror_r X-Git-Tag: ldb-1.1.31~87 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=378ae342c4e2e6b5bafbe54067d35344746be41b;p=thirdparty%2Fsamba.git strerror_r: provide XSI-compliant strerror_r Provide a XSI-compliant strerror_r on GNU based systems. The default GNU strerror_r is not XSI-compliant, this patch wraps the GNU-specific call in an XSI-compliant wrapper. This reverts 18ed32ce0821d11c0c06d82c07ba1c27b0c2b886 which tried to make Heimdal use roken, rather than libreplace for strerror_r. Signed-off-by: Gary Lockyer Signed-off-by: Andrew Bartlett Reviewed-by: Jeremy Allison --- diff --git a/lib/replace/replace.c b/lib/replace/replace.c index b5d7f117857..9351b6c94e3 100644 --- a/lib/replace/replace.c +++ b/lib/replace/replace.c @@ -820,6 +820,24 @@ int rep_strerror_r(int errnum, char *buf, size_t buflen) strncpy(buf, s, buflen); return 0; } +#elif (!defined(STRERROR_R_XSI_NOT_GNU)) +#undef strerror_r +int rep_strerror_r(int errnum, char *buf, size_t buflen) +{ + char *s = strerror_r(errnum, buf, buflen); + if (s == NULL) { + /* Shouldn't happen, should always get a string */ + return EINVAL; + } + if (s != buf) { + strlcpy(buf, s, buflen); + if (strlen(s) > buflen - 1) { + return ERANGE; + } + } + return 0; + +} #endif #ifndef HAVE_CLOCK_GETTIME diff --git a/lib/replace/replace.h b/lib/replace/replace.h index 1dbeacfff66..a41e9f89d20 100644 --- a/lib/replace/replace.h +++ b/lib/replace/replace.h @@ -628,7 +628,7 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) char *rep_get_current_dir_name(void); #endif -#ifndef HAVE_STRERROR_R +#if (!defined(HAVE_STRERROR_R) || !defined(STRERROR_R_XSI_NOT_GNU)) #define strerror_r rep_strerror_r int rep_strerror_r(int errnum, char *buf, size_t buflen); #endif diff --git a/lib/replace/wscript b/lib/replace/wscript index eeb1b3ebcf0..33f49eb5aa8 100644 --- a/lib/replace/wscript +++ b/lib/replace/wscript @@ -627,6 +627,13 @@ removeea setea conf.RECURSE('system') conf.SAMBA_CONFIG_H() + if conf.CHECK_FUNCS('strerror_r'): + # Check if strerror_r is XSI-Compatable, the default GNU implementation + # is not + conf.CHECK_CODE('int strerror_r(int errnum, char *buf, size_t buflen);', + 'STRERROR_R_XSI_NOT_GNU', + headers='string.h', addmain=False, link=False, + msg="Checking for XSI (rather than GNU) prototype for strerror_r") REPLACEMENT_FUNCTIONS = { diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 68028f0fce4..1eb39dabf78 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -1543,12 +1543,17 @@ static int setup_primary_userPassword_hash( hash = crypt((char *)io->n.cleartext_utf8->data, cmd); #endif if (hash == NULL) { + char buf[1024]; + int err = strerror_r(errno, buf, sizeof(buf)); + if (err != 0) { + strlcpy(buf, "Unknown error", sizeof(buf)-1); + } ldb_asprintf_errstring( ldb, "setup_primary_userPassword: generation of a %s " "password hash failed: (%s)", scheme, - strerror(errno)); + buf); TALLOC_FREE(frame); return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/heimdal/lib/roken/strerror_r.c b/source4/heimdal/lib/roken/strerror_r.c deleted file mode 100644 index 85271ecaf5c..00000000000 --- a/source4/heimdal/lib/roken/strerror_r.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#if (!defined(HAVE_STRERROR_R) && !defined(strerror_r)) || (!defined(STRERROR_R_PROTO_COMPATIBLE) && defined(HAVE_STRERROR_R)) - -#include -#include -#include -#include "roken.h" - -#ifdef _MSC_VER - -int ROKEN_LIB_FUNCTION -rk_strerror_r(int eno, char * strerrbuf, size_t buflen) -{ - errno_t err; - - err = strerror_s(strerrbuf, buflen, eno); - if (err != 0) { - int code; - code = sprintf_s(strerrbuf, buflen, "Error % occurred.", eno); - err = ((code != 0)? errno : 0); - } - - return err; -} - -#else /* _MSC_VER */ - -int ROKEN_LIB_FUNCTION -rk_strerror_r(int eno, char *strerrbuf, size_t buflen) -{ - /* Assume is the linux broken strerror_r (returns the a buffer (char *) if the input buffer wasn't use */ -#ifdef HAVE_STRERROR_R - const char *str; - str = strerror_r(eno, strerrbuf, buflen); - if (str != strerrbuf) - if (strlcpy(strerrbuf, str, buflen) >= buflen) - return ERANGE; - return 0; -#else - int ret; - ret = strlcpy(strerrbuf, strerror(eno), buflen); - if (ret > buflen) - return ERANGE; - return 0; -#endif -} - -#endif /* !_MSC_VER */ - -#endif diff --git a/source4/heimdal_build/config.h b/source4/heimdal_build/config.h index 2d113ae543f..a7669227960 100644 --- a/source4/heimdal_build/config.h +++ b/source4/heimdal_build/config.h @@ -49,4 +49,7 @@ /* heimdal now wants some atomic ops - ask for the non-atomic ones for Samba */ #define HEIM_BASE_NON_ATOMIC 1 +/* lib/replace provides an XSI Compatable strerror_r so use that */ +#define STRERROR_R_PROTO_COMPATIBLE + #endif diff --git a/source4/heimdal_build/wscript_build b/source4/heimdal_build/wscript_build index c733b8f5583..2072be42e7d 100644 --- a/source4/heimdal_build/wscript_build +++ b/source4/heimdal_build/wscript_build @@ -408,7 +408,6 @@ if not bld.CONFIG_SET('USING_SYSTEM_ROKEN'): lib/roken/resolve.c lib/roken/socket.c lib/roken/roken_gethostby.c - lib/roken/strerror_r.c ''' HEIMDAL_LIBRARY('roken', diff --git a/source4/heimdal_build/wscript_configure b/source4/heimdal_build/wscript_configure index 67ac34b45b2..354d44fbf36 100644 --- a/source4/heimdal_build/wscript_configure +++ b/source4/heimdal_build/wscript_configure @@ -28,13 +28,6 @@ conf.CHECK_FUNCS('''atexit cgetent getprogname setprogname gethostname strptime strsep strsep_copy strtok_r strupr swab umask uname unsetenv closefrom err warn errx warnx flock writev''') -if conf.CHECK_FUNCS('strerror_r'): - # Check if strerror_r is BSD compatible (default GNU implementation is not what Heimdal expects) - conf.CHECK_CODE('int strerror_r(int errnum, char *buf, size_t buflen);', - 'STRERROR_R_PROTO_COMPATIBLE', - headers='string.h', addmain=False, link=False, - msg="Checking for XSI (rather than GNU) prototype for strerror_r") - conf.CHECK_FUNCS_IN('hstrerror', 'resolv socket nsl', checklibc=True) conf.CHECK_FUNCS_IN('''getnameinfo sendmsg socket getipnodebyname gethostent gethostent_r sethostent endhostent getipnodebyaddr freehostent gethostbyname