[Bug 150350] libnss_hesiod doesn't honor classes=HS,IN in /etc/hesiod.conf
Jakub Jelinek
jakub@redhat.com
Wed Jun 8 21:18:00 GMT 2005
On Wed, Jun 08, 2005 at 10:42:12AM -0500, Karl E. Kelley wrote:
>
> Changelog entry for the patch sent to [Bug 150350] in Bugzilla:
I meant if you could post ChangeLog and the patch.
Anyway, here is the patch slightly cleaned up:
2005-06-08 Karl Kelley <kekelley@iastate.edu>
* hesiod/hesiod_p.h (struct hesiod_p): Add classes array.
* hesiod/hesiod.c (hesiod_init): Initialize classes. Fail if no
valid classes were given or if both are equal.
(hesiod_resolve): Use ctx->classes instead of hardcoded C_IN
and C_HS order.
(parse_config_file): Handle classes keyword.
* README.hesiod: Mention addition of the classes keyword.
--- libc/hesiod/hesiod_p.h.jj 2000-07-21 03:36:00.000000000 +0200
+++ libc/hesiod/hesiod_p.h 2005-06-08 22:12:10.000000000 +0200
@@ -41,6 +41,7 @@ struct hesiod_p {
void (*res_set)(struct hesiod_p *, struct __res_state *,
void (*)(void *));
struct __res_state * (*res_get)(struct hesiod_p *);
+ int classes[2]; /* The class search order. */
};
#define MAX_HESRESP 1024
--- libc/hesiod/hesiod.c.jj 2004-08-14 18:18:30.000000000 +0200
+++ libc/hesiod/hesiod.c 2005-06-08 22:48:01.000000000 +0200
@@ -83,6 +83,9 @@ hesiod_init(void **context) {
ctx->LHS = NULL;
ctx->RHS = NULL;
ctx->res = NULL;
+ /* Set default query classes. */
+ ctx->classes[0] = C_IN;
+ ctx->classes[1] = C_HS;
configname = __secure_getenv("HESIOD_CONFIG");
if (!configname)
@@ -123,7 +126,7 @@ hesiod_init(void **context) {
* If there is no default hesiod realm set, we return an
* error.
*/
- if (!ctx->RHS) {
+ if (!ctx->RHS || ctx->classes[0] == 0 || ctx->classes[0] == ctx->classes[1]) {
__set_errno(ENOEXEC);
goto cleanup;
}
@@ -234,15 +237,12 @@ hesiod_resolve(void *context, const char
return (NULL);
}
- if ((retvec = get_txt_records(ctx, C_IN, bindname))) {
- free(bindname);
- return (retvec);
- }
+ retvec = get_txt_records(ctx, ctx->classes[0], bindname);
+
+ if (retvec == NULL && (errno == ENOENT || errno == ECONNREFUSED) && ctx->classes[1])
+ retvec = get_txt_records(ctx, ctx->classes[1], bindname);
- if (errno != ENOENT && errno != ECONNREFUSED)
- return (NULL);
- retvec = get_txt_records(ctx, C_HS, bindname);
free(bindname);
return (retvec);
}
@@ -261,7 +261,6 @@ hesiod_free_list(void *context, char **l
*/
static int
parse_config_file(struct hesiod_p *ctx, const char *filename) {
- char *key, *data, *cp, **cpp;
char buf[MAXDNAME+7];
FILE *fp;
@@ -272,6 +271,9 @@ parse_config_file(struct hesiod_p *ctx,
free(ctx->RHS);
free(ctx->LHS);
ctx->RHS = ctx->LHS = 0;
+ /* Set default query classes. */
+ ctx->classes[0] = C_IN;
+ ctx->classes[1] = C_HS;
/*
* Now open and parse the file...
@@ -280,6 +282,8 @@ parse_config_file(struct hesiod_p *ctx,
return (-1);
while (fgets(buf, sizeof(buf), fp) != NULL) {
+ char *key, *data, *cp, **cpp;
+
cp = buf;
if (*cp == '#' || *cp == '\n' || *cp == '\r')
continue;
@@ -297,17 +301,30 @@ parse_config_file(struct hesiod_p *ctx,
cp++;
*cp++ = '\0';
- if (strcmp(key, "lhs") == 0)
+ cpp = NULL;
+ if (strcasecmp(key, "lhs") == 0)
cpp = &ctx->LHS;
- else if (strcmp(key, "rhs") == 0)
+ else if (strcasecmp(key, "rhs") == 0)
cpp = &ctx->RHS;
- else
- continue;
-
- *cpp = malloc(strlen(data) + 1);
- if (!*cpp)
- goto cleanup;
- strcpy(*cpp, data);
+ if (cpp) {
+ *cpp = strdup(data);
+ if (!*cpp)
+ goto cleanup;
+ } else if (strcasecmp(key, "classes") == 0) {
+ int n = 0;
+ while (*data && n < 2) {
+ cp = strchrnul(data, ',');
+ if (*cp)
+ *cp++ = 0;
+ if (strcasecmp(data, "IN") == 0)
+ ctx->classes[n++] = C_IN;
+ else if (strcasecmp(data, "HS") == 0)
+ ctx->classes[n++] = C_HS;
+ data = cp;
+ }
+ while (n < 2)
+ ctx->classes[n++] = 0;
+ }
}
fclose(fp);
return (0);
--- libc/hesiod/README.hesiod.jj 2000-07-21 03:32:45.000000000 +0200
+++ libc/hesiod/README.hesiod 2005-06-08 22:11:44.000000000 +0200
@@ -71,6 +71,14 @@ will want to create your own. It should
rhs=.your.domain
lhs=.ns
+ classes=in,hs
+
+The optional classes settings specifies which DNS classes Hesiod
+should do lookups in. Possible values are IN (the preferred class)
+and HS (the deprecated class, still used by some sites).
+You may specify both classes separated by a comma to try one class
+first and then the other if no entry is available in the first
+class. The default value of the classes variable is `IN,HS'.
The value of rhs can be overridden by the environment variable
`HES_DOMAIN'.
Jakub
More information about the Libc-alpha
mailing list