X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fnfs%2Frmtab.c;h=ca789a32c6a8599b07f0c74c0aa531a0b58a661d;hp=a28abf343898791b415336d36ef67c4977063d5f;hb=291b329ad1f5a65270097f4ec3a8dd465df42669;hpb=9e398e49be79af62fca8efb21849d8a2714dc92a diff --git a/support/nfs/rmtab.c b/support/nfs/rmtab.c index a28abf3..ca789a3 100644 --- a/support/nfs/rmtab.c +++ b/support/nfs/rmtab.c @@ -19,6 +19,18 @@ #include #include "nfslib.h" +/* + * Colons in incoming IPv6 presentation addresses have to + * replaced with another character, since rmtab already + * uses colons to delineate fields. + * + * Use a printable character, but one that would never be + * found in a presentation address or domain name + */ +#define IPV6_COLON ';' + +#define LINELEN (2048) + static FILE *rmfp = NULL; int @@ -56,7 +68,8 @@ struct rmtabent * fgetrmtabent(FILE *fp, int log, long *pos) { static struct rmtabent re; - char buf[2048], *count, *host, *path; + char *count, *host, *path, *c; + static char buf[LINELEN]; errno = 0; if (!fp) @@ -84,10 +97,16 @@ fgetrmtabent(FILE *fp, int log, long *pos) else re.r_count = 1; } while (0); + strncpy(re.r_client, host, sizeof (re.r_client) - 1); re.r_client[sizeof (re.r_client) - 1] = '\0'; + for (c = re.r_client; *c != '\0'; c++) + if (*c == IPV6_COLON) + *c = ':'; + strncpy(re.r_path, path, sizeof (re.r_path) - 1); re.r_path[sizeof (re.r_path) - 1] = '\0'; + return &re; } @@ -100,10 +119,27 @@ putrmtabent(struct rmtabent *rep, long *pos) void fputrmtabent(FILE *fp, struct rmtabent *rep, long *pos) { + static char buf[LINELEN]; + char *c; + if (!fp || (pos && fseek (fp, *pos, SEEK_SET) != 0)) return; - fprintf(fp, "%s:%s:0x%.8x\n", rep->r_client, rep->r_path, - rep->r_count); + + /* + * To avoid confusing the token parser in fgetrmtabent(), + * convert colons in incoming IPv6 presentation addresses + * to semicolons. + */ + if (strlen(rep->r_client) > sizeof(buf)) { + xlog(L_ERROR, "client name too large"); + return; + } + strncpy(buf, rep->r_client, sizeof(buf)); + for (c = buf; *c != '\0'; c++) + if (*c == ':') + *c = IPV6_COLON; + + (void)fprintf(fp, "%s:%s:0x%.8x\n", buf, rep->r_path, rep->r_count); } void