This patch tightens up our determination of whether we can use
authorKen Raeburn <raeburn@mit.edu>
Sat, 26 Mar 2005 02:00:47 +0000 (02:00 +0000)
committerKen Raeburn <raeburn@mit.edu>
Sat, 26 Mar 2005 02:00:47 +0000 (02:00 +0000)
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
src/include/configure.in
src/include/k5-platform.h

index ec4149761cce56cafe5d31462d1650d7f5707b1a..a5450b80352e2db31833c5e6c65ec0666f222b82 100644 (file)
@@ -1,5 +1,12 @@
 2005-03-25  Ken Raeburn  <raeburn@mit.edu>
 
+       * 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.
 
index 721865be24563b4977e8a419ccda816a311e0d7e..5a24e1b92ce0f6de323bdebae9618c7322f43806 100644 (file)
@@ -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 <pwd.h>
    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 <pwd.h>
+   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 <pwd.h>
-   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
index b178622d8702840f205742f0e0bb38aa7bc449bc..8a88cacf318834d9f416b7a3122203f1c39df14e 100644 (file)
@@ -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 */