diff options
author | hjl <hjl> | 1999-10-18 23:21:12 +0000 |
---|---|---|
committer | hjl <hjl> | 1999-10-18 23:21:12 +0000 |
commit | 8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9 (patch) | |
tree | 0904ef8554ed680fe3244fa618685e1fb7ea148b /support/nfs/clients.c | |
download | nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.gz nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.xz nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.zip |
Initial revision
Diffstat (limited to 'support/nfs/clients.c')
-rw-r--r-- | support/nfs/clients.c | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/support/nfs/clients.c b/support/nfs/clients.c new file mode 100644 index 0000000..b1970e0 --- /dev/null +++ b/support/nfs/clients.c @@ -0,0 +1,324 @@ +/* + * support/nfs/nfsclient.c + * + * Parse the nfsclients file. + * + * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> + */ + +#include "config.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <syslog.h> +#include <ctype.h> +#include "xmalloc.h" +#include "nfslib.h" +#include "exportfs.h" +#include "xio.h" + +static XFILE *cfp = NULL; +static int *squash_uids = NULL, + *squash_gids = NULL; +static int squash_uidlen = 0, + squash_gidlen = 0; +static char *hosts = NULL; + +static int parsesquash(char *list, int **idp, int *lenp); +static int parsenum(char **cpp); +static int parsekey(struct nfskey *keyp, char *str); +static int hexdigit(char c); +static int gettag(char *tag, int len); +static int getattr(char *attr, int alen, char *value, int vlen); +static void syntaxerr(char *msg); + +#ifndef isblank +#define isblank(c) ((c) == ' ' || (c) == '\t') +#endif + +void +setnfsclntent(char *fname) +{ + if (cfp) + xfclose(cfp); + if (!fname) + fname = _PATH_NFSCLIENTS; + if ((cfp = xfopen(fname)) == NULL) + xlog(L_ERROR, "can't open %s for reading", fname); +} + +struct nfsclntent * +getnfsclntent(void) +{ + static struct nfsclntent cle; + static char *hostptr = NULL; + char attr[32], val[512], *sp; + int ok; + + if (!cfp) + endnfsclntent(); + +again: + if (hosts) { + if (hostptr) + goto nexthost; + xfree(hosts); + hosts = NULL; + } + + if ((ok = gettag(cle.c_tag, sizeof(cle.c_tag))) < 0) + syntaxerr("expected tag"); + if (ok <= 0) + return NULL; + + cle.c_hostname[0] = '\0'; + cle.c_fhkey.k_type = CLE_KEY_NONE; + cle.c_mapping = CLE_MAP_IDENT; + cle.c_anonuid = -2; + cle.c_anongid = -2; + + if (squash_uids) + xfree(squash_uids); + if (squash_gids) + xfree(squash_gids); + squash_uids = squash_gids = NULL; + squash_uidlen = squash_gidlen = 0; + + while (ok) { + if ((ok = getattr(attr, sizeof(attr), val, sizeof(val))) < 0) + return NULL; + if (!ok) + break; + if (attr[0] == 'h' && !strcmp(attr, "hosts")) { + int l0 = hosts? strlen(hosts) : 0; + + hosts = (char *) xrealloc(hosts, l0+strlen(val)+2); + if (l0) + hosts[l0++] = ':'; + strcpy(hosts+l0, val); + } else + if (attr[0] == 'f' && !strcmp(attr, "fhmac")) { + if (!parsekey(&cle.c_fhkey, val)) + return NULL; + } else + if (attr[0] == 'm' && !strcmp(attr, "mapping")) { + if (!strcmp(val, "identity")) + cle.c_mapping = CLE_MAP_IDENT; + else if (!strcmp(val, "file")) + cle.c_mapping = CLE_MAP_FILE; + else if (!strcmp(val, "daemon")) + cle.c_mapping = CLE_MAP_UGIDD; + else { + syntaxerr("invalid mapping type"); + return NULL; + } + } else + if (attr[0] == 's' && !strcmp(attr, "squash_uids")) { + if (!parsesquash(val, &squash_uids, &squash_uidlen)) + return NULL; + } else + if (attr[0] == 's' && !strcmp(attr, "squash_gids")) { + if (!parsesquash(val, &squash_gids, &squash_gidlen)) + return NULL; + } else + if (attr[0] == 'a' && !strcmp(attr, "anonuid")) + cle.c_anonuid = atoi(val); + else + if (attr[0] == 'a' && !strcmp(attr, "anongid")) + cle.c_anongid = atoi(val); + else + syntaxerr("unknown attribute"); + } + + cle.c_squashuids = squash_uids; + cle.c_squashgids = squash_gids; + + /* This is the anon entry */ + if (!hosts) { + if (strcmp(cle.c_tag, "anonymous")) { + xlog(L_ERROR, "nfsclients entry %s allows anonymous " + "access. Ignored.", cle.c_tag); + goto again; + } + return &cle; + } + hostptr = hosts; + +nexthost: + if (*hostptr == ':' && strcmp(cle.c_tag, "anonymous")) { + xlog(L_ERROR, "nfsclients entry %s allows anonymous " + "access. Ignored.", cle.c_tag); + while (*hostptr == ':') + hostptr++; + } + + /* Ignore trailing colons */ + if (!*hostptr) { + hostptr = NULL; + goto again; + } + + sp = hostptr; + hostptr = strchr(hostptr, ':'); + if (hostptr) + *hostptr++ = '\0'; + strncpy(cle.c_hostname, sp, sizeof(cle.c_hostname) - 1); + cle.c_hostname [sizeof(cle.c_hostname) - 1] = '\0'; + return &cle; +} + +void +endnfsclntent(void) +{ + if (cfp) + xfclose(cfp); + if (squash_uids) + xfree(squash_uids); + if (squash_gids) + xfree(squash_gids); + if (hosts) + xfree(hosts); + cfp = NULL; + squash_uids = NULL; + squash_gids = NULL; + hosts = NULL; +} + +static int +parsekey(struct nfskey *keyp, char *str) +{ + char *sp; + int i, l, x0, x1; + + + if ((sp = strchr(str, ':')) != NULL) + *sp++ = '\0'; + if (!strcmp(str, "null")) + keyp->k_type = CLE_KEY_NULL; + else if (!strcmp(str, "md5")) + keyp->k_type = CLE_KEY_MD5; + else if (!strcmp(str, "sha")) + keyp->k_type = CLE_KEY_SHA; + else { + syntaxerr("unknown key type"); + return 0; + } + if (keyp->k_type == CLE_KEY_NULL) { + keyp->k_len = 0; + if (sp) + syntaxerr("unexpected key data for null key"); + return sp? 0 : 1; + } else if (sp) { + if ((l = strlen(sp)) & 1) { + syntaxerr("odd key length"); + return 0; + } + + l >>= 1; + for (i = 0; i < l && i < sizeof(keyp->k_key); i++, sp += 2) { + if ((x0 = hexdigit(sp[0])) == 0xff || + (x1 = hexdigit(sp[1])) == 0xff) { + syntaxerr("bad key digit"); + return 0; + } + keyp->k_key[i] = (x0 << 4) | x1; + } + keyp->k_len = i; + return 1; + } + return 0; +} + +static int +hexdigit(char c) +{ + if ((c = tolower(c)) >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0xff; +} + +static int +parsesquash(char *list, int **idp, int *lenp) +{ + char *cp = list; + int id0, id1; + int len = *lenp; + int *id = *idp; + + do { + id0 = parsenum(&cp); + if (*cp == '-') { + cp++; + id1 = parsenum(&cp); + } else { + id1 = id0; + } + if (id0 == -1 || id1 == -1) { + syntaxerr("uid/gid -1 not permitted"); + return 0; + } + if ((len % 8) == 0) + id = (int *) xrealloc(id, (len + 9) * sizeof(*id)); + id[len++] = id0; + id[len++] = id1; + if (!*cp) + break; + if (*cp != ',') { + syntaxerr("bad uid/gid list"); + return 0; + } + cp++; + } while(1); + + id[len] = -1; + *lenp = len; + *idp = id; + return 1; +} + +static int +parsenum(char **cpp) +{ + char *cp = *cpp, c; + int num = 0; + + if (**cpp == '-') + (*cpp)++; + while (isdigit(**cpp)) + (*cpp)++; + c = **cpp; **cpp = '\0'; num = atoi(cp); **cpp = c; + return num; +} + +static int +gettag(char *tag, int len) +{ + xskip(cfp, " \t\n"); + return xgettok(cfp, ':', tag, len); +} + +static int +getattr(char *attr, int alen, char *value, int vlen) +{ + int ok; + + xskip(cfp, " \t"); + if ((ok = xgettok(cfp, '=', attr, alen)) < 0) + xlog(L_ERROR, "error parsing attribute"); + if (ok <= 0) + return ok; + xskip(cfp, " \t="); + + return xgettok(cfp, 0, value, vlen); +} + +static void +syntaxerr(char *msg) +{ + xlog(L_ERROR, "syntax error in nfsclients file (line %d): %s", + cfp->x_line, msg); +} + |