summaryrefslogtreecommitdiffstats
path: root/kerberos5
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2013-05-02 12:52:49 +0000
committerrmacklem <rmacklem@FreeBSD.org>2013-05-02 12:52:49 +0000
commitc33ddc827e746f7cf351f75073f5361eb044ae5f (patch)
treeb8b2c936f2dbca6c827d1190cc2e84ac67aaf73d /kerberos5
parentfc5e40a818b97d0b3d2d21a0bb64a3574d656764 (diff)
downloadFreeBSD-src-c33ddc827e746f7cf351f75073f5361eb044ae5f.zip
FreeBSD-src-c33ddc827e746f7cf351f75073f5361eb044ae5f.tar.gz
Fix the getpwnam_r() call in the pname_to_uid() kerberos library function 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 (lokedhs@gmail.com) Tested by: Elias Martenson (earlier version) MFC after: 2 weeks
Diffstat (limited to 'kerberos5')
-rw-r--r--kerberos5/lib/libgssapi_krb5/pname_to_uid.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/kerberos5/lib/libgssapi_krb5/pname_to_uid.c b/kerberos5/lib/libgssapi_krb5/pname_to_uid.c
index 52220f6..043ec22 100644
--- a/kerberos5/lib/libgssapi_krb5/pname_to_uid.c
+++ b/kerberos5/lib/libgssapi_krb5/pname_to_uid.c
@@ -26,6 +26,7 @@
*/
/* $FreeBSD$ */
+#include <errno.h>
#include <pwd.h>
#include "krb5/gsskrb5_locl.h"
@@ -37,8 +38,12 @@ _gsskrb5_pname_to_uid(OM_uint32 *minor_status, const gss_name_t pname,
krb5_context context;
krb5_const_principal name = (krb5_const_principal) pname;
krb5_error_code kret;
- char lname[MAXLOGNAME + 1], buf[128];
+ char lname[MAXLOGNAME + 1], buf[1024], *bufp;
struct passwd pwd, *pw;
+ size_t buflen;
+ int error;
+ OM_uint32 ret;
+ static size_t buflen_hint = 1024;
GSSAPI_KRB5_INIT (&context);
@@ -49,11 +54,30 @@ _gsskrb5_pname_to_uid(OM_uint32 *minor_status, const gss_name_t pname,
}
*minor_status = 0;
- getpwnam_r(lname, &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 = getpwnam_r(lname, &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) {
*uidp = pw->pw_uid;
- return (GSS_S_COMPLETE);
+ ret = GSS_S_COMPLETE;
} else {
- return (GSS_S_FAILURE);
+ ret = GSS_S_FAILURE;
}
+ if (bufp != NULL && buflen > sizeof(buf))
+ free(bufp);
+ return (ret);
}
OpenPOWER on IntegriCloud