tech-userlevel: Hesiod uid maps

Subject: Hesiod uid maps
To: None <tech-userlevel@netbsd.org>
From: Greg Hudson <ghudson@MIT.EDU>
List: tech-userlevel
Date: 03/06/1999 17:46:48
So, we never finished addressing the Hesiod getpwuid() problem (that
is, that Ultrix uses the "passwd" map and Athena Hesiod uses the "uid"
map). I came up with an idea today for fixing the problem without
having to parse hesiod.conf in two places. It adds a uid map search
just like the class search, and adds an internal function to hesiod.c
to do the resolution for uid lookups.
I do not have a good setup for testing NetBSD libc changes. The
changes to hesiod.c are just a reindentation of changes to the Athena
hesiod code (with modified comments) which I did test, so I have good
confidence that these changes should work.
The default I chose was "uidmaps=uid". This means people using Hesiod
against Ultrix servers will need to add "uidmaps=passwd" (or
"uidmaps=passwd,uid" or whatnot) to their hesiod.conf files before
this code will help them. That line, as well as a "classes=" line,
will be harmless on an Ultrix box, so you can still use the same
hesiod.conf on Ultrix and NetBSD machines.
We could make the default "uidmaps=uid,passwd", but that means a
failed uid lookup using the default search paths will take four
packets. I think that's excessive. However, I feel less strongly
about the default in this case than I did in the classes case.
*** /mit/netbsd/src/lib/libc/net/hesiod.c	Tue Mar 2 17:48:41 1999
--- hesiod.c	Sat Mar 6 17:40:14 1999
***************
*** 75,80 ****
--- 75,81 ----
 __weak_alias(hesiod_end,_hesiod_end);
 __weak_alias(hesiod_to_bind,_hesiod_to_bind);
 __weak_alias(hesiod_resolve,_hesiod_resolve);
+ __weak_alias(hesiod__uidresolve,_hesiod__uidresolve);
 __weak_alias(hesiod_free_list,_hesiod_free_list);
 __weak_alias(hes_init,_hes_init);
 __weak_alias(hes_to_bind,_hes_to_bind);
***************
*** 83,92 ****
 __weak_alias(hes_free,_hes_free);
 #endif
 
 struct hesiod_p {
! 	char	*lhs;			/* normally ".ns" */
! 	char	*rhs;			/* AKA the default hesiod domain */
! 	int	 classes[2];		/* The class search order. */
 };
 
 #define	MAX_HESRESP	1024
--- 84,100 ----
 __weak_alias(hes_free,_hes_free);
 #endif
 
+ /* Athena uses the "uid" hesiod type for uid lookups. Ultrix uses the
+ * "passwd" type. Some constants for the compatibility code.
+ */
+ #define UIDMAP_UID "uid"
+ #define UIDMAP_PASSWD "passwd"
+ 
 struct hesiod_p {
! 	char		*lhs;		/* normally ".ns" */
! 	char		*rhs;		/* AKA the default hesiod domain */
! 	int	 	classes[2];	/* The class search order */
! 	const char	*uidmaps[2];	/* The uid map search order */
 };
 
 #define	MAX_HESRESP	1024
***************
*** 259,264 ****
--- 267,285 ----
 	return retvec;
 }
 
+ /* Internal function for getpwent.c. */
+ char **hesiod__uidresolve(void *context, const char *uidstr)
+ {
+ 	struct hesiod_p *ctx = (struct hesiod_p *) context;
+ 	char **retvec;
+ 
+ 	retvec = hesiod_resolve(context, uidstr, ctx->uidmaps[0]);
+ 	if (retvec == NULL && errno == ENOENT && ctx->uidmaps[1])
+ 		retvec = hesiod_resolve(context, uidstr, ctx->uidmaps[1]);
+ 
+ 	return retvec;
+ }
+ 
 /*ARGSUSED*/
 void 
 hesiod_free_list(context, list)
***************
*** 294,299 ****
--- 315,324 ----
 	ctx->classes[0] = C_IN;
 	ctx->classes[1] = C_HS;
 
+ 		/* Set default uid maps. */
+ 	ctx->uidmaps[0] = UIDMAP_UID;
+ 	ctx->uidmaps[1] = NULL;
+ 
 		/* Try to open the configuration file. */
 	fp = fopen(filename, "r");
 	if (!fp) {
***************
*** 355,367 ****
 				}
 				while (n < 2)
 					ctx->classes[n++] = 0;
 			}
 		}
 	}
 	fclose(fp);
 
 	if (!ctx->rhs || ctx->classes[0] == 0 ||
! 	 ctx->classes[0] == ctx->classes[1]) {
 		errno = ENOEXEC;
 		return -1;
 	}
--- 380,413 ----
 				}
 				while (n < 2)
 					ctx->classes[n++] = 0;
+ 			} else if (strcasecmp(key, "uidmaps") == 0) {
+ 				n = 0;
+ 				while (*data && n < 2) {
+ 					p = data;
+ 					while (*p && *p != ',')
+ 						p++;
+ 					if (*p)
+ 						*p++ = 0;
+ 					if (strcasecmp(data, "uid") == 0)
+ 						ctx->uidmaps[n++] = UIDMAP_UID;
+ 					else if (strcasecmp(data,
+ 							 "passwd") == 0)
+ 						ctx->uidmaps[n++] =
+ 						 UIDMAP_PASSWD;
+ 					data = p;
+ 				}
+ 				while (n < 2)
+ 					ctx->uidmaps[n++] = NULL;
 			}
 		}
 	}
 	fclose(fp);
 
+ 		/* Make sure that the rhs is set and that the class search
+ 		 * order and the uidmap search order both make sense. */
 	if (!ctx->rhs || ctx->classes[0] == 0 ||
! 	 ctx->classes[0] == ctx->classes[1] || ctx->uidmaps[0] == 0 ||
! 	 ctx->uidmaps[0] == ctx->uidmaps[1]) {
 		errno = ENOEXEC;
 		return -1;
 	}
*** /mit/netbsd/src/lib/libc/gen/getpwent.c	Fri Jan 29 16:40:12 1999
--- getpwent.c	Sat Mar 6 17:35:46 1999
***************
*** 83,88 ****
--- 83,89 ----
 __weak_alias(setpwent,_setpwent);
 #endif
 
+ extern char **hesiod__uidresolve __P((void *, const char *));
 
 /*
 * The lookup techniques and data extraction code here must be kept
***************
*** 450,456 ****
 	uid_t		 uid;
 	int		 search;
 
- 	char		 *map;
 	char		**hp;
 	void		 *context;
 	int		 r;
--- 451,456 ----
***************
*** 460,476 ****
 	case _PW_KEYBYNUM:
 		snprintf(line, sizeof(line) - 1, "passwd-%u", _pw_hesnum);
 		_pw_hesnum++;
- 		map = "passwd";
 		break;
 	case _PW_KEYBYNAME:
 		name = va_arg(ap, const char *);
 		strncpy(line, name, sizeof(line));
- 		map = "passwd";
 		break;
 	case _PW_KEYBYUID:
 		uid = va_arg(ap, uid_t);
 		snprintf(line, sizeof(line), "%u", (unsigned int)uid);
- 		map = "uid";		/* XXX this is `passwd' on ultrix */
 		break;
 	default:
 		abort();
--- 460,473 ----
***************
*** 481,487 ****
 	if (hesiod_init(&context) == -1)
 		return (r);
 
! 	hp = hesiod_resolve(context, line, map);
 	if (hp == NULL) {
 		if (errno == ENOENT) {
 			if (search == _PW_KEYBYNUM) {
--- 478,487 ----
 	if (hesiod_init(&context) == -1)
 		return (r);
 
! 	if (search == _PW_KEYBYUID)
! 		hp = hesiod__uidresolve(context, line);
! 	else
! 		hp = hesiod_resolve(context, line, "passwd");
 	if (hp == NULL) {
 		if (errno == ENOENT) {
 			if (search == _PW_KEYBYNUM) {
*** /mit/netbsd/src/lib/libc/include/namespace.h	Tue Mar 2 17:48:39 1999
--- namespace.h	Sat Mar 6 17:34:30 1999
***************
*** 221,226 ****
--- 221,227 ----
 #define hesiod_free_list	_hesiod_free_list
 #define hesiod_init		_hesiod_init
 #define hesiod_resolve		_hesiod_resolve
+ #define hesiod__uidresolve	_hesiod__uidresolve
 #define hesiod_to_bind		_hesiod_to_bind
 #define inet_aton		_inet_aton
 #define inet_lnaof		_inet_lnaof

AltStyle によって変換されたページ (->オリジナル) /