Author: rmacklem
Date: Thu May  2 12:43:56 2013
New Revision: 250176
URL: http://svnweb.freebsd.org/changeset/base/250176

Log:
  Fix the getpwuid_r() call in the gssd daemon so that it handles
  the ERANGE error return case. Without this fix, authentication
  of users for certain system setups could fail unexpectedly.
  
  Reported by:  Elias Martenson (loke...@gmail.com)
  Tested by:    Elias Martenson (earlier version)
  MFC after:    2 weeks

Modified:
  head/usr.sbin/gssd/gssd.c

Modified: head/usr.sbin/gssd/gssd.c
==============================================================================
--- head/usr.sbin/gssd/gssd.c   Thu May  2 12:35:15 2013        (r250175)
+++ head/usr.sbin/gssd/gssd.c   Thu May  2 12:43:56 2013        (r250176)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <ctype.h>
 #include <dirent.h>
 #include <err.h>
+#include <errno.h>
 #ifndef WITHOUT_KERBEROS
 #include <krb5.h>
 #endif
@@ -557,8 +558,11 @@ gssd_pname_to_uid_1_svc(pname_to_uid_arg
 {
        gss_name_t name = gssd_find_resource(argp->pname);
        uid_t uid;
-       char buf[128];
+       char buf[1024], *bufp;
        struct passwd pwd, *pw;
+       size_t buflen;
+       int error;
+       static size_t buflen_hint = 1024;
 
        memset(result, 0, sizeof(*result));
        if (name) {
@@ -567,7 +571,24 @@ gssd_pname_to_uid_1_svc(pname_to_uid_arg
                            name, argp->mech, &uid);
                if (result->major_status == GSS_S_COMPLETE) {
                        result->uid = uid;
-                       getpwuid_r(uid, &pwd, buf, sizeof(buf), &pw);
+                       buflen = buflen_hint;
+                       for (;;) {
+                               pw = NULL;
+                               bufp = buf;
+                               if (buflen > sizeof(buf))
+                                       bufp = malloc(buflen);
+                               if (bufp == NULL)
+                                       break;
+                               error = getpwuid_r(uid, &pwd, bufp, buflen,
+                                   &pw);
+                               if (error != ERANGE)
+                                       break;
+                               if (buflen > sizeof(buf))
+                                       free(bufp);
+                               buflen += 1024;
+                               if (buflen > buflen_hint)
+                                       buflen_hint = buflen;
+                       }
                        if (pw) {
                                int len = NGRPS;
                                int groups[NGRPS];
@@ -584,6 +605,8 @@ gssd_pname_to_uid_1_svc(pname_to_uid_arg
                                result->gidlist.gidlist_len = 0;
                                result->gidlist.gidlist_val = NULL;
                        }
+                       if (bufp != NULL && buflen > sizeof(buf))
+                               free(bufp);
                }
        } else {
                result->major_status = GSS_S_BAD_NAME;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to