~ubuntu-branches/debian/experimental/nfs-utils/experimental

« back to all changes in this revision

Viewing changes to support/nfs/clients.c

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2006-07-08 14:26:40 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060708142640-r171kjj2a13gy2kz
Tags: 1:1.0.9-1
* Updated co-mantainer mail address.
* New upstream release.
  - Added 'mount.nfs' utility which can be used as a mount helper
    to mount nfs filesystems. It does not yet support 'user' mounts.
  - Makefile/autoconf tidyups
  - No compiles with no warnings
  - deleted debian/* at request of debian maintainer
  - deleted assorted other unused files
  - mountd can be run multi-threaded for configurations with many hundreds
    of clients (mountd -t 20).  Default is single-threaded
  - Support for selection NFS version to be exported, and protocol to
    use.  This requires kernel patches that should be in linux 2.6.19.
  - Use 65534 rather than -2 for default anon.  This makes no difference in many
    cases, but is important in some.
  - New utility 'rpcdebug' for controlled kernel 'debug' options for nfs and nfsd.
  - nfsstat reports NFSv4 operation statistics that should be available in
    linux 2.6.18.
  - assorted other fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * support/nfs/nfsclient.c
3
 
 *
4
 
 * Parse the nfsclients file.
5
 
 *
6
 
 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7
 
 */
8
 
 
9
 
#include "config.h"
10
 
 
11
 
#include <string.h>
12
 
#include <stdlib.h>
13
 
#include <stdio.h>
14
 
#include <syslog.h>
15
 
#include <ctype.h>
16
 
#include "xmalloc.h"
17
 
#include "nfslib.h"
18
 
#include "exportfs.h"
19
 
#include "xio.h"
20
 
 
21
 
static char     *cfname = NULL;
22
 
static XFILE    *cfp = NULL;
23
 
static int      *squash_uids = NULL,
24
 
                *squash_gids = NULL;
25
 
static int      squash_uidlen = 0,
26
 
                squash_gidlen = 0;
27
 
static char     *hosts = NULL;
28
 
 
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);
36
 
 
37
 
#ifndef isblank
38
 
#define isblank(c)      ((c) == ' ' || (c) == '\t')
39
 
#endif
40
 
 
41
 
void
42
 
setnfsclntent(char *fname)
43
 
{
44
 
        if (cfp)
45
 
                xfclose(cfp);
46
 
        if (!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);
51
 
}
52
 
 
53
 
struct nfsclntent *
54
 
getnfsclntent(void)
55
 
{
56
 
        static struct nfsclntent cle;
57
 
        static char     *hostptr = NULL;
58
 
        char            attr[32], val[512], *sp;
59
 
        int             ok;
60
 
 
61
 
        if (!cfp)
62
 
                endnfsclntent();
63
 
 
64
 
again:
65
 
        if (hosts) {
66
 
                if (hostptr)
67
 
                        goto nexthost;
68
 
                xfree(hosts);
69
 
                hosts = NULL;
70
 
        }
71
 
 
72
 
        if ((ok = gettag(cle.c_tag, sizeof(cle.c_tag))) < 0)
73
 
                syntaxerr("expected tag");
74
 
        if (ok <= 0)
75
 
                return NULL;
76
 
 
77
 
        cle.c_hostname[0] = '\0';
78
 
        cle.c_fhkey.k_type = CLE_KEY_NONE;
79
 
        cle.c_mapping = CLE_MAP_IDENT;
80
 
        cle.c_anonuid = 65534;
81
 
        cle.c_anongid = 65534;
82
 
 
83
 
        if (squash_uids)
84
 
                xfree(squash_uids);
85
 
        if (squash_gids)
86
 
                xfree(squash_gids);
87
 
        squash_uids = squash_gids = NULL;
88
 
        squash_uidlen = squash_gidlen = 0;
89
 
 
90
 
        while (ok) {
91
 
                if ((ok = getattr(attr, sizeof(attr), val, sizeof(val))) < 0)
92
 
                        return NULL;
93
 
                if (!ok)
94
 
                        break;
95
 
                if (attr[0] == 'h' && !strcmp(attr, "hosts")) {
96
 
                        int     l0 = hosts? strlen(hosts) : 0;
97
 
 
98
 
                        hosts = (char *) xrealloc(hosts, l0+strlen(val)+2);
99
 
                        if (l0)
100
 
                                hosts[l0++] = ':';
101
 
                        strcpy(hosts+l0, val);
102
 
                } else
103
 
                if (attr[0] == 'f' && !strcmp(attr, "fhmac")) {
104
 
                        if (!parsekey(&cle.c_fhkey, val))
105
 
                                return NULL;
106
 
                } else
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;
114
 
                        else {
115
 
                                syntaxerr("invalid mapping type");
116
 
                                return NULL;
117
 
                        }
118
 
                } else
119
 
                if (attr[0] == 's' && !strcmp(attr, "squash_uids")) {
120
 
                        if (!parsesquash(val, &squash_uids, &squash_uidlen))
121
 
                                return NULL;
122
 
                } else
123
 
                if (attr[0] == 's' && !strcmp(attr, "squash_gids")) {
124
 
                        if (!parsesquash(val, &squash_gids, &squash_gidlen))
125
 
                                return NULL;
126
 
                } else
127
 
                if (attr[0] == 'a' && !strcmp(attr, "anonuid"))
128
 
                        cle.c_anonuid = atoi(val);
129
 
                else
130
 
                if (attr[0] == 'a' && !strcmp(attr, "anongid"))
131
 
                        cle.c_anongid = atoi(val);
132
 
                else
133
 
                        syntaxerr("unknown attribute");
134
 
        }
135
 
 
136
 
        cle.c_squashuids = squash_uids;
137
 
        cle.c_squashgids = squash_gids;
138
 
 
139
 
        /* This is the anon entry */
140
 
        if (!hosts) {
141
 
                if (strcmp(cle.c_tag, "anonymous")) {
142
 
                        xlog(L_ERROR,
143
 
                             "%s:%d: entry %s allows anonymous access.  Ignored.",
144
 
                             cfname, xfp->x_line, cle.c_tag);
145
 
                        goto again;
146
 
                }
147
 
                return &cle;
148
 
        }
149
 
        hostptr = hosts;
150
 
 
151
 
nexthost:
152
 
        if (*hostptr == ':' && strcmp(cle.c_tag, "anonymous")) {
153
 
                xlog(L_ERROR,
154
 
                     "%s:%d: entry %s allows anonymous access.  Ignored.",
155
 
                     cfname, cfp->x_line, cle.c_tag);
156
 
                while (*hostptr == ':')
157
 
                        hostptr++;
158
 
        }
159
 
 
160
 
        /* Ignore trailing colons */
161
 
        if (!*hostptr) {
162
 
                hostptr = NULL;
163
 
                goto again;
164
 
        }
165
 
 
166
 
        sp = hostptr;
167
 
        hostptr = strchr(hostptr, ':');
168
 
        if (hostptr)
169
 
                *hostptr++ = '\0';
170
 
        strncpy(cle.c_hostname, sp, sizeof(cle.c_hostname) - 1);
171
 
        cle.c_hostname [sizeof(cle.c_hostname) - 1] = '\0';
172
 
        return &cle;
173
 
}
174
 
 
175
 
void
176
 
endnfsclntent(void)
177
 
{
178
 
        if (cfname)
179
 
                free(cfname);
180
 
        if (cfp)
181
 
                xfclose(cfp);
182
 
        if (squash_uids)
183
 
                xfree(squash_uids);
184
 
        if (squash_gids)
185
 
                xfree(squash_gids);
186
 
        if (hosts)
187
 
                xfree(hosts);
188
 
        cfname = NULL;
189
 
        cfp = NULL;
190
 
        squash_uids = NULL;
191
 
        squash_gids = NULL;
192
 
        hosts = NULL;
193
 
}
194
 
 
195
 
static int
196
 
parsekey(struct nfskey *keyp, char *str)
197
 
{
198
 
        char    *sp;
199
 
        int     i, l, x0, x1;
200
 
 
201
 
 
202
 
        if ((sp = strchr(str, ':')) != NULL)
203
 
                *sp++ = '\0';
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;
210
 
        else {
211
 
                syntaxerr("unknown key type");
212
 
                return 0;
213
 
        }
214
 
        if (keyp->k_type == CLE_KEY_NULL) {
215
 
                keyp->k_len = 0;
216
 
                if (sp)
217
 
                        syntaxerr("unexpected key data for null key");
218
 
                return sp? 0 : 1;
219
 
        } else if (sp) {
220
 
                if ((l = strlen(sp)) & 1) {
221
 
                        syntaxerr("odd key length");
222
 
                        return 0;
223
 
                }
224
 
 
225
 
                l >>= 1;
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");
230
 
                                return 0;
231
 
                        }
232
 
                        keyp->k_key[i] = (x0 << 4) | x1;
233
 
                }
234
 
                keyp->k_len = i;
235
 
                return 1;
236
 
        }
237
 
        return 0;
238
 
}
239
 
 
240
 
static int
241
 
hexdigit(char c)
242
 
{
243
 
        if ((c = tolower(c)) >= '0' && c <= '9')
244
 
                return c - '0';
245
 
        if (c >= 'a' && c <= 'f')
246
 
                return c - 'a' + 10;
247
 
        return 0xff;
248
 
}
249
 
 
250
 
static int
251
 
parsesquash(char *list, int **idp, int *lenp)
252
 
{
253
 
        char    *cp = list;
254
 
        int     id0, id1;
255
 
        int     len = *lenp;
256
 
        int     *id = *idp;
257
 
 
258
 
        do {
259
 
                id0 = parsenum(&cp);
260
 
                if (*cp == '-') {
261
 
                        cp++;
262
 
                        id1 = parsenum(&cp);
263
 
                } else {
264
 
                        id1 = id0;
265
 
                }
266
 
                if (id0 == -1 || id1 == -1) {
267
 
                        syntaxerr("uid/gid -1 not permitted");
268
 
                        return 0;
269
 
                }
270
 
                if ((len % 8) == 0)
271
 
                        id = (int *) xrealloc(id, (len + 9) * sizeof(*id));
272
 
                id[len++] = id0;
273
 
                id[len++] = id1;
274
 
                if (!*cp)
275
 
                        break;
276
 
                if (*cp != ',') {
277
 
                        syntaxerr("bad uid/gid list");
278
 
                        return 0;
279
 
                }
280
 
                cp++;
281
 
        } while(1);
282
 
 
283
 
        id[len] = -1;
284
 
        *lenp = len;
285
 
        *idp = id;
286
 
        return 1;
287
 
}
288
 
 
289
 
static int
290
 
parsenum(char **cpp)
291
 
{
292
 
        char    *cp = *cpp, c;
293
 
        int     num = 0;
294
 
 
295
 
        if (**cpp == '-')
296
 
                (*cpp)++;
297
 
        while (isdigit(**cpp))
298
 
                (*cpp)++;
299
 
        c = **cpp; **cpp = '\0'; num = atoi(cp); **cpp = c;
300
 
        return num;
301
 
}
302
 
 
303
 
static int
304
 
gettag(char *tag, int len)
305
 
{
306
 
        xskip(cfp, " \t\n");
307
 
        return xgettok(cfp, ':', tag, len);
308
 
}
309
 
 
310
 
static int
311
 
getattr(char *attr, int alen, char *value, int vlen)
312
 
{
313
 
        int     ok;
314
 
 
315
 
        xskip(cfp, " \t");
316
 
        if ((ok = xgettok(cfp, '=', attr, alen)) < 0)
317
 
                syntaxerr("missing attribute");
318
 
        if (ok <= 0)
319
 
                return ok;
320
 
        xskip(cfp, " \t=");
321
 
 
322
 
        return xgettok(cfp, 0, value, vlen);
323
 
}
324
 
 
325
 
static void
326
 
syntaxerr(char *msg)
327
 
{
328
 
        xlog(L_ERROR, "%s:%d: syntax error: %s",
329
 
                        cfname, cfp->x_line, msg);
330
 
}
331