Subject: Re: Hesiod uid maps
To: Michael Graff <explorer@flame.org>
From: Greg Hudson <ghudson@MIT.EDU>
List: tech-userlevel
Date: 03/07/1999 15:47:21
> Do you really want a function that is marked as "internal to..." to
> have a weak alias? I may not fully understand the purpose of this,
> but I thoght it was to allow us to provide a function but allow it
> to be overridden at link time.
Hm. The intention was that if the application has its own
hesiod__uidresolve function which does something completely different,
getpwuid() shouldn't break. Thus the namespace.h addition. Having
the weak alias there shouldn't be necessary, I suppose.
I could also just name it _hesiod_uidresolve() and ignore namespace.h.
That might be better. (The Athena distribution will name it
hesiod__uidresolve(), however, since a non-system library can't safely
use symbols beginning with an underscore.)
*** /mit/netbsd/src/lib/libc/net/hesiod.c Tue Mar 2 17:48:41 1999
--- hesiod.c Sun Mar 7 15:45:40 1999
***************
*** 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
--- 83,99 ----
__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 ****
--- 266,284 ----
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 ****
--- 314,323 ----
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;
}
--- 379,412 ----
}
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 Sun Mar 7 15:45:53 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) {