2 * support/nfs/nfsclient.c
4 * Parse the nfsclients file.
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
21 static char *cfname = NULL;
22 static XFILE *cfp = NULL;
23 static int *squash_uids = NULL,
25 static int squash_uidlen = 0,
27 static char *hosts = NULL;
29 static int parsesquash(char *list, int **idp, int *lenp);
30 static int parsenum(char **cpp);
31 static int parsekey(struct nfskey *keyp, char *str);
32 static int hexdigit(char c);
33 static int gettag(char *tag, int len);
34 static int getattr(char *attr, int alen, char *value, int vlen);
35 static void syntaxerr(char *msg);
38 #define isblank(c) ((c) == ' ' || (c) == '\t')
42 setnfsclntent(char *fname)
47 fname = _PATH_NFSCLIENTS;
48 if ((cfp = xfopen(fname)) == NULL)
49 xlog(L_ERROR, "can't open %s for reading", fname);
50 cfname = strdup(fname);
56 static struct nfsclntent cle;
57 static char *hostptr = NULL;
58 char attr[32], val[512], *sp;
72 if ((ok = gettag(cle.c_tag, sizeof(cle.c_tag))) < 0)
73 syntaxerr("expected tag");
77 cle.c_hostname[0] = '\0';
78 cle.c_fhkey.k_type = CLE_KEY_NONE;
79 cle.c_mapping = CLE_MAP_IDENT;
87 squash_uids = squash_gids = NULL;
88 squash_uidlen = squash_gidlen = 0;
91 if ((ok = getattr(attr, sizeof(attr), val, sizeof(val))) < 0)
95 if (attr[0] == 'h' && !strcmp(attr, "hosts")) {
96 int l0 = hosts? strlen(hosts) : 0;
98 hosts = (char *) xrealloc(hosts, l0+strlen(val)+2);
101 strcpy(hosts+l0, val);
103 if (attr[0] == 'f' && !strcmp(attr, "fhmac")) {
104 if (!parsekey(&cle.c_fhkey, val))
107 if (attr[0] == 'm' && !strcmp(attr, "mapping")) {
108 if (!strcmp(val, "identity"))
109 cle.c_mapping = CLE_MAP_IDENT;
110 else if (!strcmp(val, "file"))
111 cle.c_mapping = CLE_MAP_FILE;
112 else if (!strcmp(val, "daemon"))
113 cle.c_mapping = CLE_MAP_UGIDD;
115 syntaxerr("invalid mapping type");
119 if (attr[0] == 's' && !strcmp(attr, "squash_uids")) {
120 if (!parsesquash(val, &squash_uids, &squash_uidlen))
123 if (attr[0] == 's' && !strcmp(attr, "squash_gids")) {
124 if (!parsesquash(val, &squash_gids, &squash_gidlen))
127 if (attr[0] == 'a' && !strcmp(attr, "anonuid"))
128 cle.c_anonuid = atoi(val);
130 if (attr[0] == 'a' && !strcmp(attr, "anongid"))
131 cle.c_anongid = atoi(val);
133 syntaxerr("unknown attribute");
136 cle.c_squashuids = squash_uids;
137 cle.c_squashgids = squash_gids;
139 /* This is the anon entry */
141 if (strcmp(cle.c_tag, "anonymous")) {
143 "%s:%d: entry %s allows anonymous access. Ignored.",
144 cfname, xfp->x_line, cle.c_tag);
152 if (*hostptr == ':' && strcmp(cle.c_tag, "anonymous")) {
154 "%s:%d: entry %s allows anonymous access. Ignored.",
155 cfname, cfp->x_line, cle.c_tag);
156 while (*hostptr == ':')
160 /* Ignore trailing colons */
167 hostptr = strchr(hostptr, ':');
170 strncpy(cle.c_hostname, sp, sizeof(cle.c_hostname) - 1);
171 cle.c_hostname [sizeof(cle.c_hostname) - 1] = '\0';
196 parsekey(struct nfskey *keyp, char *str)
202 if ((sp = strchr(str, ':')) != NULL)
204 if (!strcmp(str, "null"))
205 keyp->k_type = CLE_KEY_NULL;
206 else if (!strcmp(str, "md5"))
207 keyp->k_type = CLE_KEY_MD5;
208 else if (!strcmp(str, "sha"))
209 keyp->k_type = CLE_KEY_SHA;
211 syntaxerr("unknown key type");
214 if (keyp->k_type == CLE_KEY_NULL) {
217 syntaxerr("unexpected key data for null key");
220 if ((l = strlen(sp)) & 1) {
221 syntaxerr("odd key length");
226 for (i = 0; i < l && i < sizeof(keyp->k_key); i++, sp += 2) {
227 if ((x0 = hexdigit(sp[0])) == 0xff ||
228 (x1 = hexdigit(sp[1])) == 0xff) {
229 syntaxerr("bad key digit");
232 keyp->k_key[i] = (x0 << 4) | x1;
243 if ((c = tolower(c)) >= '0' && c <= '9')
245 if (c >= 'a' && c <= 'f')
251 parsesquash(char *list, int **idp, int *lenp)
266 if (id0 == -1 || id1 == -1) {
267 syntaxerr("uid/gid -1 not permitted");
271 id = (int *) xrealloc(id, (len + 9) * sizeof(*id));
277 syntaxerr("bad uid/gid list");
297 while (isdigit(**cpp))
299 c = **cpp; **cpp = '\0'; num = atoi(cp); **cpp = c;
304 gettag(char *tag, int len)
307 return xgettok(cfp, ':', tag, len);
311 getattr(char *attr, int alen, char *value, int vlen)
316 if ((ok = xgettok(cfp, '=', attr, alen)) < 0)
317 syntaxerr("missing attribute");
322 return xgettok(cfp, 0, value, vlen);
328 xlog(L_ERROR, "%s:%d: syntax error: %s",
329 cfname, cfp->x_line, msg);