Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Apr 2013 16:38:46 -0400 (EDT)
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        freebsd-hackers@freebsd.org
Subject:   review of patches for the gssd that handle getpwXX_r ERANGE return
Message-ID:  <1513398963.1192605.1367095126723.JavaMail.root@erie.cs.uoguelph.ca>
In-Reply-To: <1589161980.1192602.1367095122855.JavaMail.root@erie.cs.uoguelph.ca>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
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

[-- Attachment #2 --]
--- 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;

[-- Attachment #3 --]
--- 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);
 }

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1513398963.1192605.1367095126723.JavaMail.root>