Hi,
I have attached two patches, which can also be found at:
http://people.freebsd.org/~rmacklem/getpw.patch1 and getpw.patch2
They are almost identical and handle the ERANGE error return from
getpw[nam|uid]_r() when buf[128] isn't large enough.
Is anyone interested in reviewing these? (This has been discussed
some time ago, but the patch was never reviewed. Actually I reviewed
a patch similar to this, but the submitter subsequently requested that
I not use their patch, so I wrote similar ones.)
Thanks in advance for any review, rick
--- usr.sbin/gssd/gssd.c.sav 2013-04-26 20:38:45.000000000 -0400
+++ usr.sbin/gssd/gssd.c 2013-04-26 20:38:53.000000000 -0400
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD: head/usr.sbin/gssd/g
#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;
--- kerberos5/lib/libgssapi_krb5/pname_to_uid.c.sav 2013-04-26 20:37:45.000000000 -0400
+++ kerberos5/lib/libgssapi_krb5/pname_to_uid.c 2013-04-27 16:25:14.000000000 -0400
@@ -26,6 +26,7 @@
*/
/* $FreeBSD: head/kerberos5/lib/libgssapi_krb5/pname_to_uid.c 181344 2008-08-06 14:02:05Z dfr $ */
+#include <errno.h>
#include <pwd.h>
#include "krb5/gsskrb5_locl.h"
@@ -37,8 +38,12 @@ _gsskrb5_pname_to_uid(OM_uint32 *minor_s
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_s
}
*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);
}
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[email protected]"