summaryrefslogtreecommitdiffstats
path: root/usr.sbin/gssd
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2013-05-02 12:43:56 +0000
committerrmacklem <rmacklem@FreeBSD.org>2013-05-02 12:43:56 +0000
commitfc5e40a818b97d0b3d2d21a0bb64a3574d656764 (patch)
tree99128a35654f214145980883b8431f9d301cd229 /usr.sbin/gssd
parent607cfd414a6ddff1ee7ce419236a98e4b80fb2b5 (diff)
downloadFreeBSD-src-fc5e40a818b97d0b3d2d21a0bb64a3574d656764.zip
FreeBSD-src-fc5e40a818b97d0b3d2d21a0bb64a3574d656764.tar.gz
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 (lokedhs@gmail.com) Tested by: Elias Martenson (earlier version) MFC after: 2 weeks
Diffstat (limited to 'usr.sbin/gssd')
-rw-r--r--usr.sbin/gssd/gssd.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/usr.sbin/gssd/gssd.c b/usr.sbin/gssd/gssd.c
index 9777943..a50e097 100644
--- a/usr.sbin/gssd/gssd.c
+++ b/usr.sbin/gssd/gssd.c
@@ -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_args *argp, pname_to_uid_res *result, struc
{
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_args *argp, pname_to_uid_res *result, struc
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_args *argp, pname_to_uid_res *result, struc
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;
OpenPOWER on IntegriCloud