From 1c36eeeaf08a93307fb218fc74577702728e3988 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Sat, 26 Mar 2005 02:00:47 +0000 Subject: [PATCH] This patch tightens up our determination of whether we can use getpw{nam,uid}_r, and using the set flags, creates macros providing a consistent API, and if possible thread safety. * configure.in: Don't check for getpwnam_r and getpwuid_r with AC_CHECK_FUNCS; use AC_CHECK_FUNC, and only set shell variables. Run stricter tests on return types and numbers of arguments, and only define the C macros if these parameters can actually be determined. * k5-platform.h (k5_getpwnam_r, k5_getpwuid_r): New macros. ticket: 2982 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17155 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/ChangeLog | 7 +++++ src/include/configure.in | 45 +++++++++++++++++++++---------- src/include/k5-platform.h | 57 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 14 deletions(-) diff --git a/src/include/ChangeLog b/src/include/ChangeLog index ec4149761..a5450b803 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,5 +1,12 @@ 2005-03-25 Ken Raeburn + * configure.in: Don't check for getpwnam_r and getpwuid_r with + AC_CHECK_FUNCS; use AC_CHECK_FUNC, and only set shell variables. + Run stricter tests on return types and numbers of arguments, and + only define the C macros if these parameters can actually be + determined. + * k5-platform.h (k5_getpwnam_r, k5_getpwuid_r): New macros. + * Makefile.in ($(srcdir)/krb5/autoconf.stmp): Nuke autom4te.cache directory. diff --git a/src/include/configure.in b/src/include/configure.in index 721865be2..5a24e1b92 100644 --- a/src/include/configure.in +++ b/src/include/configure.in @@ -9,7 +9,7 @@ AC_PROG_INSTALL AC_PROG_AWK AC_PROG_LEX AC_C_CONST -AC_CHECK_FUNCS(strdup setvbuf inet_ntoa inet_aton seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strftime strptime geteuid setenv unsetenv getenv gethostbyname2 getifaddrs getpwnam_r getpwuid_r gmtime_r localtime_r pthread_mutex_lock sched_yield dlopen) +AC_CHECK_FUNCS(strdup setvbuf inet_ntoa inet_aton seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strftime strptime geteuid setenv unsetenv getenv gethostbyname2 getifaddrs gmtime_r localtime_r pthread_mutex_lock sched_yield dlopen) AC_CHECK_FUNCS( mkstemp) AC_HEADER_STDARG AC_CHECK_HEADERS(unistd.h paths.h regex.h regexp.h regexpr.h fcntl.h memory.h ifaddrs.h sys/filio.h sched.h) @@ -50,6 +50,8 @@ fi ]) dnl +AC_CHECK_FUNC(getpwnam_r,ac_cv_func_getpwnam_r=yes,ac_cv_func_getpwnam_r=no) +AC_CHECK_FUNC(getpwuid_r,ac_cv_func_getpwuid_r=yes,ac_cv_func_getpwuid_r=no) if test "$ac_cv_func_getpwnam_r" = yes; then AC_MSG_CHECKING([return type of getpwnam_r]) AC_CACHE_VAL(krb5_cv_getpwnam_r_return_type, @@ -68,7 +70,7 @@ if test "$ac_cv_func_getpwnam_r" = yes; then if test $krb5_cv_getpwnam_r_return_type = int; then AC_DEFINE(GETPWNAM_R_RETURNS_INT, 1, [Define if getpwnam_r returns an int]) elif test $krb5_cv_getpwnam_r_return_type = unknown; then - AC_MSG_WARN([Cannot determine getpwnam_r return type, disabling]) + AC_MSG_WARN([Cannot determine getpwnam_r return type, disabling getpwnam_r]) ac_cv_func_getpwnam_r=no fi fi @@ -77,23 +79,38 @@ if test "$ac_cv_func_getpwnam_r" = yes; then AC_CACHE_VAL(krb5_cv_getpwnam_r_args, [AC_TRY_COMPILE([#include struct passwd pwx; char buf[1024];], - [getpwnam_r("", &pwx, buf, sizeof(buf));], - krb5_cv_getpwnam_r_args=4,krb5_cv_getpwnam_r_args=5)]) + [getpwnam_r("", &pwx, buf, sizeof(buf));], args4=yes, args4=no) + AC_TRY_COMPILE([#include + struct passwd pwx, *p; char buf[1024];], + [getpwnam_r("", &pwx, buf, sizeof(buf), &p);], args5=yes, args5=no) + case $args4/$args5 in + yes/no) krb5_cv_getpwnam_r_args=4 ;; + no/yes) krb5_cv_getpwnam_r_args=5 ;; + *) krb5_cv_getpwnam_r_args=unknown ;; + esac]) AC_MSG_RESULT($krb5_cv_getpwnam_r_args) - if test "$krb5_cv_getpwnam_r_args" = 4; then - AC_DEFINE(GETPWNAM_R_4_ARGS,1,[Define if getpwnam_r exists but takes only 4 arguments (e.g., POSIX draft 6 implementations like some Solaris releases).]) + if test "$krb5_cv_getpwnam_r_args" = unknown; then + AC_MSG_WARN([Cannot determine number of arguments to getpwnam_r, disabling its use.]) + ac_cv_func_getpwnam_r=no + else + AC_DEFINE(HAVE_GETPWNAM_R,1,[Define if getpwnam_r is available and useful.]) + if test "$krb5_cv_getpwnam_r_args" = 4; then + AC_DEFINE(GETPWNAM_R_4_ARGS,1,[Define if getpwnam_r exists but takes only 4 arguments (e.g., POSIX draft 6 implementations like some Solaris releases).]) + fi fi fi +if test "$ac_cv_func_getpwnam_r" = no && test "$ac_cv_func_getpwuid_r" = yes; then + # Actually, we could do this check, and the corresponding checks + # for return type and number of arguments, but I doubt we'll run + # into a system where we'd get to use getpwuid_r but not getpwnam_r. + AC_MSG_NOTICE([getpwnam_r not useful, so disabling getpwuid_r too]) + ac_cv_func_getpwuid_r=no +fi if test "$ac_cv_func_getpwuid_r" = yes; then - AC_MSG_CHECKING([number of arguments to getpwuid_r]) - AC_CACHE_VAL(krb5_cv_getpwuid_r_args, - [AC_TRY_COMPILE([#include - struct passwd pwx; char buf[1024];], - [getpwuid_r(0, &pwx, buf, sizeof(buf));], - krb5_cv_getpwuid_r_args=4,krb5_cv_getpwuid_r_args=5)]) - AC_MSG_RESULT($krb5_cv_getpwuid_r_args) - if test "$krb5_cv_getpwuid_r_args" = 4; then + AC_DEFINE(HAVE_GETPWUID_R,1,[Define if getpwuid_r is available and useful.]) + # Hack: Assume getpwuid_r is the shorter form if getpwnam_r is. + if test "$krb5_cv_getpwnam_r_args" = 4; then AC_DEFINE(GETPWUID_R_4_ARGS,1,[Define if getpwuid_r exists but takes only 4 arguments (e.g., POSIX draft 6 implementations like some Solaris releases).]) fi fi diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h index b178622d8..8a88cacf3 100644 --- a/src/include/k5-platform.h +++ b/src/include/k5-platform.h @@ -32,6 +32,7 @@ * + 64-bit types and load/store code * + SIZE_MAX * + shared library init/fini hooks + * + consistent getpwnam/getpwuid interfaces */ #ifndef K5_PLATFORM_H @@ -492,4 +493,60 @@ load_64_le (unsigned char *p) return ((UINT64_TYPE)load_32_le(p+4) << 32) | load_32_le(p); } + +/* Make the interfaces to getpwnam and getpwuid consistent. + Model the wrappers on the POSIX thread-safe versions, but + use the unsafe system versions if the safe ones don't exist + or we can't figure out their interfaces. */ + +/* int k5_getpwnam_r(const char *, blah blah) */ +#ifdef HAVE_GETPWNAM_R +# ifndef GETPWNAM_R_4_ARGS +/* POSIX */ +# define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ + getpwnam_r(NAME,REC,BUF,BUFSIZE,OUT) +# else +/* POSIX drafts? */ +# ifdef GETPWNAM_R_RETURNS_INT +# define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ + (getpwnam_r(NAME,REC,BUF,BUFSIZE) == 0 \ + ? (*(OUT) = REC, 0) \ + : (*(OUT) = NULL, -1)) +# else +# define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ + (*(OUT) = getpwnam_r(NAME,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0) +# endif +# endif +#else /* no getpwnam_r, or can't figure out #args or return type */ +/* Will get warnings about unused variables. */ +# define k5_getpwnam_r(NAME, REC, BUF, BUFSIZE, OUT) \ + (*(OUT) = getpwnam(NAME), *(OUT) == NULL ? -1 : 0) +#endif + +/* int k5_getpwuid_r(uid_t, blah blah) */ +#ifdef HAVE_GETPWUID_R +# ifndef GETPWUID_R_4_ARGS +/* POSIX */ +# define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ + getpwuid_r(UID,REC,BUF,BUFSIZE,OUT) +# else +/* POSIX drafts? Yes, I mean to test GETPWNAM... here. Less junk to + do at configure time. */ +# ifdef GETPWNAM_R_RETURNS_INT +# define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ + (getpwuid_r(UID,REC,BUF,BUFSIZE) == 0 \ + ? (*(OUT) = REC, 0) \ + : (*(OUT) = NULL, -1)) +# else +# define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ + (*(OUT) = getpwuid_r(UID,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0) +# endif +# endif +#else /* no getpwuid_r, or can't figure out #args or return type */ +/* Will get warnings about unused variables. */ +# define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \ + (*(OUT) = getpwuid(UID), *(OUT) == NULL ? -1 : 0) +#endif + + #endif /* K5_PLATFORM_H */ -- 2.26.2