Blame


1 004aa293 2005-07-13 devnull /*
2 004aa293 2005-07-13 devnull * TO DO:
3 004aa293 2005-07-13 devnull * - gc of file systems (not going to do just yet?)
4 004aa293 2005-07-13 devnull * - statistics file
5 004aa293 2005-07-13 devnull * - configure on amsterdam
6 004aa293 2005-07-13 devnull */
7 004aa293 2005-07-13 devnull
8 004aa293 2005-07-13 devnull #include <u.h>
9 004aa293 2005-07-13 devnull #include <libc.h>
10 004aa293 2005-07-13 devnull #include <bio.h>
11 004aa293 2005-07-13 devnull #include <ip.h>
12 004aa293 2005-07-13 devnull #include <thread.h>
13 004aa293 2005-07-13 devnull #include <libsec.h>
14 004aa293 2005-07-13 devnull #include <sunrpc.h>
15 004aa293 2005-07-13 devnull #include <nfs3.h>
16 004aa293 2005-07-13 devnull #include <diskfs.h>
17 004aa293 2005-07-13 devnull #include <venti.h>
18 004aa293 2005-07-13 devnull #include "nfs3srv.h"
19 004aa293 2005-07-13 devnull
20 004aa293 2005-07-13 devnull #define trace if(!tracecalls){}else print
21 004aa293 2005-07-13 devnull
22 004aa293 2005-07-13 devnull typedef struct Ipokay Ipokay;
23 004aa293 2005-07-13 devnull typedef struct Config Config;
24 004aa293 2005-07-13 devnull typedef struct Ctree Ctree;
25 004aa293 2005-07-13 devnull typedef struct Cnode Cnode;
26 004aa293 2005-07-13 devnull
27 004aa293 2005-07-13 devnull struct Ipokay
28 004aa293 2005-07-13 devnull {
29 004aa293 2005-07-13 devnull int okay;
30 004aa293 2005-07-13 devnull uchar ip[IPaddrlen];
31 004aa293 2005-07-13 devnull uchar mask[IPaddrlen];
32 004aa293 2005-07-13 devnull };
33 004aa293 2005-07-13 devnull
34 004aa293 2005-07-13 devnull struct Config
35 004aa293 2005-07-13 devnull {
36 004aa293 2005-07-13 devnull Ipokay *ok;
37 004aa293 2005-07-13 devnull uint nok;
38 004aa293 2005-07-13 devnull ulong mtime;
39 004aa293 2005-07-13 devnull Ctree *ctree;
40 004aa293 2005-07-13 devnull };
41 004aa293 2005-07-13 devnull
42 004aa293 2005-07-13 devnull char *addr;
43 004aa293 2005-07-13 devnull int blocksize;
44 004aa293 2005-07-13 devnull int cachesize;
45 004aa293 2005-07-13 devnull Config config;
46 004aa293 2005-07-13 devnull char *configfile;
47 004aa293 2005-07-13 devnull int encryptedhandles = 1;
48 004aa293 2005-07-13 devnull Channel *nfschan;
49 004aa293 2005-07-13 devnull Channel *mountchan;
50 004aa293 2005-07-13 devnull Channel *timerchan;
51 004aa293 2005-07-13 devnull Nfs3Handle root;
52 004aa293 2005-07-13 devnull SunSrv *srv;
53 004aa293 2005-07-13 devnull int tracecalls;
54 004aa293 2005-07-13 devnull VtCache *vcache;
55 004aa293 2005-07-13 devnull VtConn *z;
56 004aa293 2005-07-13 devnull
57 004aa293 2005-07-13 devnull void cryptinit(void);
58 004aa293 2005-07-13 devnull void timerthread(void*);
59 004aa293 2005-07-13 devnull void timerproc(void*);
60 004aa293 2005-07-13 devnull
61 004aa293 2005-07-13 devnull extern void handleunparse(Fsys*, Nfs3Handle*, Nfs3Handle*, int);
62 004aa293 2005-07-13 devnull extern Nfs3Status handleparse(Nfs3Handle*, Fsys**, Nfs3Handle*, int);
63 004aa293 2005-07-13 devnull
64 004aa293 2005-07-13 devnull Nfs3Status logread(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);
65 004aa293 2005-07-13 devnull Nfs3Status refreshdiskread(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);
66 004aa293 2005-07-13 devnull Nfs3Status refreshconfigread(Cnode*, u32int, u64int, uchar**, u32int*, u1int*);
67 004aa293 2005-07-13 devnull
68 004aa293 2005-07-13 devnull int readconfigfile(Config *cp);
69 004aa293 2005-07-13 devnull void setrootfid(void);
70 004aa293 2005-07-13 devnull int ipokay(uchar *ip, ushort port);
71 004aa293 2005-07-13 devnull
72 2214d4b6 2005-12-30 devnull u64int unittoull(char*);
73 2214d4b6 2005-12-30 devnull
74 004aa293 2005-07-13 devnull void
75 004aa293 2005-07-13 devnull usage(void)
76 004aa293 2005-07-13 devnull {
77 d63790ee 2008-07-20 devnull fprint(2, "usage: vnfs [-LLRVir] [-a addr] [-b blocksize] [-c cachesize] configfile\n");
78 004aa293 2005-07-13 devnull threadexitsall("usage");
79 004aa293 2005-07-13 devnull }
80 004aa293 2005-07-13 devnull
81 004aa293 2005-07-13 devnull void
82 004aa293 2005-07-13 devnull threadmain(int argc, char **argv)
83 004aa293 2005-07-13 devnull {
84 004aa293 2005-07-13 devnull fmtinstall('B', sunrpcfmt);
85 004aa293 2005-07-13 devnull fmtinstall('C', suncallfmt);
86 004aa293 2005-07-13 devnull fmtinstall('F', vtfcallfmt);
87 004aa293 2005-07-13 devnull fmtinstall('H', encodefmt);
88 004aa293 2005-07-13 devnull fmtinstall('I', eipfmt);
89 004aa293 2005-07-13 devnull fmtinstall('V', vtscorefmt);
90 004aa293 2005-07-13 devnull sunfmtinstall(&nfs3prog);
91 004aa293 2005-07-13 devnull sunfmtinstall(&nfsmount3prog);
92 004aa293 2005-07-13 devnull
93 004aa293 2005-07-13 devnull addr = "udp!*!2049";
94 004aa293 2005-07-13 devnull blocksize = 8192;
95 004aa293 2005-07-13 devnull cachesize = 400;
96 004aa293 2005-07-13 devnull srv = sunsrv();
97 004aa293 2005-07-13 devnull srv->ipokay = ipokay;
98 004aa293 2005-07-13 devnull cryptinit();
99 004aa293 2005-07-13 devnull
100 004aa293 2005-07-13 devnull ARGBEGIN{
101 004aa293 2005-07-13 devnull default:
102 004aa293 2005-07-13 devnull usage();
103 004aa293 2005-07-13 devnull case 'E':
104 004aa293 2005-07-13 devnull encryptedhandles = 0;
105 004aa293 2005-07-13 devnull break;
106 004aa293 2005-07-13 devnull case 'L':
107 004aa293 2005-07-13 devnull if(srv->localonly == 0)
108 004aa293 2005-07-13 devnull srv->localonly = 1;
109 004aa293 2005-07-13 devnull else
110 004aa293 2005-07-13 devnull srv->localparanoia = 1;
111 004aa293 2005-07-13 devnull break;
112 004aa293 2005-07-13 devnull case 'R':
113 004aa293 2005-07-13 devnull srv->chatty++;
114 004aa293 2005-07-13 devnull break;
115 004aa293 2005-07-13 devnull case 'T':
116 004aa293 2005-07-13 devnull tracecalls = 1;
117 004aa293 2005-07-13 devnull break;
118 004aa293 2005-07-13 devnull case 'V':
119 80b4aedc 2006-05-04 devnull if(chattyventi++)
120 80b4aedc 2006-05-04 devnull vttracelevel++;
121 004aa293 2005-07-13 devnull break;
122 004aa293 2005-07-13 devnull case 'a':
123 004aa293 2005-07-13 devnull addr = EARGF(usage());
124 004aa293 2005-07-13 devnull break;
125 004aa293 2005-07-13 devnull case 'b':
126 2214d4b6 2005-12-30 devnull blocksize = unittoull(EARGF(usage()));
127 004aa293 2005-07-13 devnull break;
128 004aa293 2005-07-13 devnull case 'c':
129 2214d4b6 2005-12-30 devnull cachesize = unittoull(EARGF(usage()));
130 004aa293 2005-07-13 devnull break;
131 d63790ee 2008-07-20 devnull case 'i':
132 d63790ee 2008-07-20 devnull insecure = 1;
133 d63790ee 2008-07-20 devnull break;
134 004aa293 2005-07-13 devnull case 'r':
135 004aa293 2005-07-13 devnull srv->alwaysreject++;
136 004aa293 2005-07-13 devnull break;
137 004aa293 2005-07-13 devnull }ARGEND
138 004aa293 2005-07-13 devnull
139 004aa293 2005-07-13 devnull if(argc != 1)
140 004aa293 2005-07-13 devnull usage();
141 004aa293 2005-07-13 devnull
142 004aa293 2005-07-13 devnull if((z = vtdial(nil)) == nil)
143 004aa293 2005-07-13 devnull sysfatal("vtdial: %r");
144 004aa293 2005-07-13 devnull if(vtconnect(z) < 0)
145 004aa293 2005-07-13 devnull sysfatal("vtconnect: %r");
146 e781b7b6 2009-06-16 rsc if((vcache = vtcachealloc(z, blocksize*cachesize)) == nil)
147 004aa293 2005-07-13 devnull sysfatal("vtcache: %r");
148 004aa293 2005-07-13 devnull
149 004aa293 2005-07-13 devnull configfile = argv[0];
150 004aa293 2005-07-13 devnull if(readconfigfile(&config) < 0)
151 004aa293 2005-07-13 devnull sysfatal("readConfig: %r");
152 004aa293 2005-07-13 devnull setrootfid();
153 004aa293 2005-07-13 devnull
154 004aa293 2005-07-13 devnull nfschan = chancreate(sizeof(SunMsg*), 0);
155 004aa293 2005-07-13 devnull mountchan = chancreate(sizeof(SunMsg*), 0);
156 004aa293 2005-07-13 devnull timerchan = chancreate(sizeof(void*), 0);
157 fa325e9b 2020-01-10 cross
158 004aa293 2005-07-13 devnull if(sunsrvudp(srv, addr) < 0)
159 004aa293 2005-07-13 devnull sysfatal("starting server: %r");
160 004aa293 2005-07-13 devnull
161 004aa293 2005-07-13 devnull sunsrvthreadcreate(srv, nfs3proc, nfschan);
162 004aa293 2005-07-13 devnull sunsrvthreadcreate(srv, mount3proc, mountchan);
163 004aa293 2005-07-13 devnull sunsrvthreadcreate(srv, timerthread, nil);
164 004aa293 2005-07-13 devnull proccreate(timerproc, nil, 32768);
165 fa325e9b 2020-01-10 cross
166 004aa293 2005-07-13 devnull sunsrvprog(srv, &nfs3prog, nfschan);
167 004aa293 2005-07-13 devnull sunsrvprog(srv, &nfsmount3prog, mountchan);
168 004aa293 2005-07-13 devnull
169 004aa293 2005-07-13 devnull threadexits(nil);
170 004aa293 2005-07-13 devnull }
171 004aa293 2005-07-13 devnull
172 2214d4b6 2005-12-30 devnull #define TWID64 ((u64int)~(u64int)0)
173 2214d4b6 2005-12-30 devnull
174 2214d4b6 2005-12-30 devnull u64int
175 2214d4b6 2005-12-30 devnull unittoull(char *s)
176 2214d4b6 2005-12-30 devnull {
177 2214d4b6 2005-12-30 devnull char *es;
178 2214d4b6 2005-12-30 devnull u64int n;
179 2214d4b6 2005-12-30 devnull
180 2214d4b6 2005-12-30 devnull if(s == nil)
181 2214d4b6 2005-12-30 devnull return TWID64;
182 2214d4b6 2005-12-30 devnull n = strtoul(s, &es, 0);
183 2214d4b6 2005-12-30 devnull if(*es == 'k' || *es == 'K'){
184 2214d4b6 2005-12-30 devnull n *= 1024;
185 2214d4b6 2005-12-30 devnull es++;
186 2214d4b6 2005-12-30 devnull }else if(*es == 'm' || *es == 'M'){
187 2214d4b6 2005-12-30 devnull n *= 1024*1024;
188 2214d4b6 2005-12-30 devnull es++;
189 2214d4b6 2005-12-30 devnull }else if(*es == 'g' || *es == 'G'){
190 2214d4b6 2005-12-30 devnull n *= 1024*1024*1024;
191 2214d4b6 2005-12-30 devnull es++;
192 2214d4b6 2005-12-30 devnull }else if(*es == 't' || *es == 'T'){
193 2214d4b6 2005-12-30 devnull n *= 1024*1024;
194 2214d4b6 2005-12-30 devnull n *= 1024*1024;
195 2214d4b6 2005-12-30 devnull }
196 2214d4b6 2005-12-30 devnull if(*es != '\0')
197 2214d4b6 2005-12-30 devnull return TWID64;
198 2214d4b6 2005-12-30 devnull return n;
199 2214d4b6 2005-12-30 devnull }
200 2214d4b6 2005-12-30 devnull
201 004aa293 2005-07-13 devnull /*
202 004aa293 2005-07-13 devnull * Handles.
203 fa325e9b 2020-01-10 cross *
204 004aa293 2005-07-13 devnull * We store all the state about which file a client is accessing in
205 004aa293 2005-07-13 devnull * the handle, so that we don't have to maintain any per-client state
206 fa325e9b 2020-01-10 cross * ourselves. In order to avoid leaking handles or letting clients
207 004aa293 2005-07-13 devnull * create arbitrary handles, we sign and encrypt each handle with
208 004aa293 2005-07-13 devnull * AES using a key selected randomly when the server starts.
209 fa325e9b 2020-01-10 cross * Thus, handles cannot be used across sessions.
210 004aa293 2005-07-13 devnull *
211 004aa293 2005-07-13 devnull * The decrypted handles begin with the following header:
212 004aa293 2005-07-13 devnull *
213 004aa293 2005-07-13 devnull * sessid[8] random session id chosen at start time
214 6884e49f 2006-06-15 devnull * len[4] length of handle that follows
215 004aa293 2005-07-13 devnull *
216 004aa293 2005-07-13 devnull * If we're pressed for space in the rest of the handle, we could
217 6884e49f 2006-06-15 devnull * probably reduce the amount of sessid bytes. Note that the sessid
218 fa325e9b 2020-01-10 cross * bytes must be consistent during a run of vnfs, or else some
219 6884e49f 2006-06-15 devnull * clients (e.g., Linux 2.4) eventually notice that successive TLookups
220 6884e49f 2006-06-15 devnull * return different handles, and they return "Stale NFS file handle"
221 6884e49f 2006-06-15 devnull * errors to system calls in response (even though we never sent
222 6884e49f 2006-06-15 devnull * that error!).
223 004aa293 2005-07-13 devnull *
224 004aa293 2005-07-13 devnull * Security woes aside, the fact that we have to shove everything
225 004aa293 2005-07-13 devnull * into the handles is quite annoying. We have to encode, in 40 bytes:
226 004aa293 2005-07-13 devnull *
227 004aa293 2005-07-13 devnull * - position in the synthesized config tree
228 004aa293 2005-07-13 devnull * - enough of the path to do glob matching
229 004aa293 2005-07-13 devnull * - position in an archived file system image
230 004aa293 2005-07-13 devnull *
231 004aa293 2005-07-13 devnull * and the handles need to be stable across changes in the config file
232 004aa293 2005-07-13 devnull * (though not across server restarts since encryption screws
233 004aa293 2005-07-13 devnull * that up nicely).
234 fa325e9b 2020-01-10 cross *
235 fa325e9b 2020-01-10 cross * We encode each of the first two as a 10-byte hash that is
236 fa325e9b 2020-01-10 cross * the first half of a SHA1 hash.
237 004aa293 2005-07-13 devnull */
238 004aa293 2005-07-13 devnull
239 004aa293 2005-07-13 devnull enum
240 004aa293 2005-07-13 devnull {
241 004aa293 2005-07-13 devnull SessidSize = 8,
242 6884e49f 2006-06-15 devnull HeaderSize = SessidSize+4,
243 cbeb0b26 2006-04-01 devnull MaxHandleSize = Nfs3MaxHandleSize - HeaderSize
244 004aa293 2005-07-13 devnull };
245 004aa293 2005-07-13 devnull
246 004aa293 2005-07-13 devnull AESstate aesstate;
247 004aa293 2005-07-13 devnull uchar sessid[SessidSize];
248 004aa293 2005-07-13 devnull
249 004aa293 2005-07-13 devnull static void
250 004aa293 2005-07-13 devnull hencrypt(Nfs3Handle *h)
251 004aa293 2005-07-13 devnull {
252 004aa293 2005-07-13 devnull uchar *p;
253 004aa293 2005-07-13 devnull AESstate aes;
254 004aa293 2005-07-13 devnull
255 004aa293 2005-07-13 devnull /*
256 004aa293 2005-07-13 devnull * root handle has special encryption - a single 0 byte - so that it
257 004aa293 2005-07-13 devnull * never goes stale.
258 004aa293 2005-07-13 devnull */
259 004aa293 2005-07-13 devnull if(h->len == root.len && memcmp(h->h, root.h, root.len) == 0){
260 004aa293 2005-07-13 devnull h->h[0] = 0;
261 004aa293 2005-07-13 devnull h->len = 1;
262 004aa293 2005-07-13 devnull return;
263 004aa293 2005-07-13 devnull }
264 004aa293 2005-07-13 devnull
265 004aa293 2005-07-13 devnull if(!encryptedhandles)
266 004aa293 2005-07-13 devnull return;
267 004aa293 2005-07-13 devnull
268 004aa293 2005-07-13 devnull if(h->len > MaxHandleSize){
269 004aa293 2005-07-13 devnull /* oops */
270 004aa293 2005-07-13 devnull fprint(2, "handle too long: %.*lH\n", h->len, h->h);
271 004aa293 2005-07-13 devnull memset(h->h, 'X', Nfs3MaxHandleSize);
272 004aa293 2005-07-13 devnull h->len = Nfs3MaxHandleSize;
273 004aa293 2005-07-13 devnull return;
274 004aa293 2005-07-13 devnull }
275 004aa293 2005-07-13 devnull
276 004aa293 2005-07-13 devnull p = h->h;
277 004aa293 2005-07-13 devnull memmove(p+HeaderSize, p, h->len);
278 6884e49f 2006-06-15 devnull memmove(p, sessid, SessidSize);
279 6884e49f 2006-06-15 devnull *(u32int*)(p+SessidSize) = h->len;
280 004aa293 2005-07-13 devnull h->len += HeaderSize;
281 004aa293 2005-07-13 devnull
282 004aa293 2005-07-13 devnull if(encryptedhandles){
283 004aa293 2005-07-13 devnull while(h->len < MaxHandleSize)
284 6884e49f 2006-06-15 devnull h->h[h->len++] = 0;
285 004aa293 2005-07-13 devnull aes = aesstate;
286 004aa293 2005-07-13 devnull aesCBCencrypt(h->h, MaxHandleSize, &aes);
287 004aa293 2005-07-13 devnull }
288 004aa293 2005-07-13 devnull }
289 004aa293 2005-07-13 devnull
290 004aa293 2005-07-13 devnull static Nfs3Status
291 004aa293 2005-07-13 devnull hdecrypt(Nfs3Handle *h)
292 004aa293 2005-07-13 devnull {
293 004aa293 2005-07-13 devnull AESstate aes;
294 fa325e9b 2020-01-10 cross
295 004aa293 2005-07-13 devnull if(h->len == 1 && h->h[0] == 0){ /* single 0 byte is root */
296 004aa293 2005-07-13 devnull *h = root;
297 004aa293 2005-07-13 devnull return Nfs3Ok;
298 004aa293 2005-07-13 devnull }
299 004aa293 2005-07-13 devnull
300 004aa293 2005-07-13 devnull if(!encryptedhandles)
301 004aa293 2005-07-13 devnull return Nfs3Ok;
302 004aa293 2005-07-13 devnull
303 004aa293 2005-07-13 devnull if(h->len <= HeaderSize)
304 004aa293 2005-07-13 devnull return Nfs3ErrBadHandle;
305 004aa293 2005-07-13 devnull if(encryptedhandles){
306 004aa293 2005-07-13 devnull if(h->len != MaxHandleSize)
307 004aa293 2005-07-13 devnull return Nfs3ErrBadHandle;
308 004aa293 2005-07-13 devnull aes = aesstate;
309 004aa293 2005-07-13 devnull aesCBCdecrypt(h->h, h->len, &aes);
310 004aa293 2005-07-13 devnull }
311 6884e49f 2006-06-15 devnull if(memcmp(h->h, sessid, SessidSize) != 0)
312 004aa293 2005-07-13 devnull return Nfs3ErrStale; /* give benefit of doubt */
313 6884e49f 2006-06-15 devnull h->len = *(u32int*)(h->h+SessidSize);
314 6884e49f 2006-06-15 devnull if(h->len >= MaxHandleSize-HeaderSize)
315 6884e49f 2006-06-15 devnull return Nfs3ErrBadHandle;
316 004aa293 2005-07-13 devnull memmove(h->h, h->h+HeaderSize, h->len);
317 004aa293 2005-07-13 devnull return Nfs3Ok;
318 004aa293 2005-07-13 devnull }
319 004aa293 2005-07-13 devnull
320 004aa293 2005-07-13 devnull void
321 004aa293 2005-07-13 devnull cryptinit(void)
322 004aa293 2005-07-13 devnull {
323 004aa293 2005-07-13 devnull uchar key[32], ivec[AESbsize];
324 004aa293 2005-07-13 devnull int i;
325 0c9c620f 2010-03-10 rsc u32int u32;
326 fa325e9b 2020-01-10 cross
327 0c9c620f 2010-03-10 rsc u32 = truerand();
328 0c9c620f 2010-03-10 rsc memmove(sessid, &u32, 4);
329 0c9c620f 2010-03-10 rsc for(i=0; i<nelem(key); i+=4) {
330 0c9c620f 2010-03-10 rsc u32 = truerand();
331 0c9c620f 2010-03-10 rsc memmove(key+i, &u32, 4);
332 0c9c620f 2010-03-10 rsc }
333 004aa293 2005-07-13 devnull for(i=0; i<nelem(ivec); i++)
334 004aa293 2005-07-13 devnull ivec[i] = fastrand();
335 004aa293 2005-07-13 devnull setupAESstate(&aesstate, key, sizeof key, ivec);
336 004aa293 2005-07-13 devnull }
337 004aa293 2005-07-13 devnull
338 004aa293 2005-07-13 devnull /*
339 004aa293 2005-07-13 devnull * Config file.
340 004aa293 2005-07-13 devnull *
341 004aa293 2005-07-13 devnull * The main purpose of the configuration file is to define a tree
342 004aa293 2005-07-13 devnull * in which the archived file system images are mounted.
343 004aa293 2005-07-13 devnull * The tree is stored as Entry structures, defined below.
344 004aa293 2005-07-13 devnull *
345 004aa293 2005-07-13 devnull * The configuration file also allows one to define shell-like
346 004aa293 2005-07-13 devnull * glob expressions matching paths that are not to be displayed.
347 004aa293 2005-07-13 devnull * The matched files or directories are shown in directory listings
348 004aa293 2005-07-13 devnull * (could suppress these if we cared) but they cannot be opened,
349 004aa293 2005-07-13 devnull * read, or written, and getattr returns zeroed data.
350 004aa293 2005-07-13 devnull */
351 004aa293 2005-07-13 devnull enum
352 004aa293 2005-07-13 devnull {
353 004aa293 2005-07-13 devnull /* sizes used in handles; see nfs server below */
354 004aa293 2005-07-13 devnull CnodeHandleSize = 8,
355 cbeb0b26 2006-04-01 devnull FsysHandleOffset = CnodeHandleSize
356 004aa293 2005-07-13 devnull };
357 004aa293 2005-07-13 devnull
358 004aa293 2005-07-13 devnull /*
359 004aa293 2005-07-13 devnull * Config file tree.
360 004aa293 2005-07-13 devnull */
361 004aa293 2005-07-13 devnull struct Ctree
362 004aa293 2005-07-13 devnull {
363 004aa293 2005-07-13 devnull Cnode *root;
364 004aa293 2005-07-13 devnull Cnode *hash[1024];
365 004aa293 2005-07-13 devnull };
366 004aa293 2005-07-13 devnull
367 004aa293 2005-07-13 devnull struct Cnode
368 004aa293 2005-07-13 devnull {
369 004aa293 2005-07-13 devnull char *name; /* path element */
370 004aa293 2005-07-13 devnull Cnode *parent; /* in tree */
371 004aa293 2005-07-13 devnull Cnode *nextsib; /* in tree */
372 004aa293 2005-07-13 devnull Cnode *kidlist; /* in tree */
373 004aa293 2005-07-13 devnull Cnode *nexthash; /* in hash list */
374 fa325e9b 2020-01-10 cross
375 004aa293 2005-07-13 devnull Nfs3Status (*read)(Cnode*, u32int, u64int, uchar**, u32int*, u1int*); /* synthesized read fn */
376 004aa293 2005-07-13 devnull
377 004aa293 2005-07-13 devnull uchar handle[VtScoreSize]; /* sha1(path to here) */
378 004aa293 2005-07-13 devnull ulong mtime; /* mtime for this directory entry */
379 fa325e9b 2020-01-10 cross
380 004aa293 2005-07-13 devnull /* fsys overlay on this node */
381 004aa293 2005-07-13 devnull Fsys *fsys; /* cache of memory structure */
382 004aa293 2005-07-13 devnull Nfs3Handle fsyshandle;
383 004aa293 2005-07-13 devnull int isblackhole; /* walking down keeps you here */
384 004aa293 2005-07-13 devnull
385 004aa293 2005-07-13 devnull /*
386 004aa293 2005-07-13 devnull * mount point info.
387 004aa293 2005-07-13 devnull * if a mount point is inside another file system,
388 004aa293 2005-07-13 devnull * the fsys and fsyshandle above have the old fs info,
389 004aa293 2005-07-13 devnull * the mfsys and mfsyshandle below have the new one.
390 004aa293 2005-07-13 devnull * getattrs must use the old info for consistency.
391 004aa293 2005-07-13 devnull */
392 004aa293 2005-07-13 devnull int ismtpt; /* whether there is an fsys mounted here */
393 004aa293 2005-07-13 devnull uchar fsysscore[VtScoreSize]; /* score of fsys image on venti */
394 004aa293 2005-07-13 devnull char *fsysimage; /* raw disk image */
395 004aa293 2005-07-13 devnull Fsys *mfsys; /* mounted file system (nil until walked) */
396 004aa293 2005-07-13 devnull Nfs3Handle mfsyshandle; /* handle to root of mounted fsys */
397 fa325e9b 2020-01-10 cross
398 004aa293 2005-07-13 devnull int mark; /* gc */
399 004aa293 2005-07-13 devnull };
400 004aa293 2005-07-13 devnull
401 004aa293 2005-07-13 devnull static uint
402 004aa293 2005-07-13 devnull dumbhash(uchar *s)
403 004aa293 2005-07-13 devnull {
404 004aa293 2005-07-13 devnull return (s[0]<<2)|(s[1]>>6); /* first 10 bits */
405 004aa293 2005-07-13 devnull }
406 004aa293 2005-07-13 devnull
407 004aa293 2005-07-13 devnull static Cnode*
408 004aa293 2005-07-13 devnull mkcnode(Ctree *t, Cnode *parent, char *elem, uint elen, char *path, uint plen)
409 004aa293 2005-07-13 devnull {
410 004aa293 2005-07-13 devnull uint h;
411 004aa293 2005-07-13 devnull Cnode *n;
412 fa325e9b 2020-01-10 cross
413 004aa293 2005-07-13 devnull n = emalloc(sizeof *n + elen+1);
414 004aa293 2005-07-13 devnull n->name = (char*)(n+1);
415 004aa293 2005-07-13 devnull memmove(n->name, elem, elen);
416 004aa293 2005-07-13 devnull n->name[elen] = 0;
417 004aa293 2005-07-13 devnull n->parent = parent;
418 004aa293 2005-07-13 devnull if(parent){
419 004aa293 2005-07-13 devnull n->nextsib = parent->kidlist;
420 004aa293 2005-07-13 devnull parent->kidlist = n;
421 004aa293 2005-07-13 devnull }
422 004aa293 2005-07-13 devnull n->kidlist = nil;
423 004aa293 2005-07-13 devnull sha1((uchar*)path, plen, n->handle, nil);
424 004aa293 2005-07-13 devnull h = dumbhash(n->handle);
425 004aa293 2005-07-13 devnull n->nexthash = t->hash[h];
426 004aa293 2005-07-13 devnull t->hash[h] = n;
427 fa325e9b 2020-01-10 cross
428 004aa293 2005-07-13 devnull return n;
429 004aa293 2005-07-13 devnull }
430 004aa293 2005-07-13 devnull
431 004aa293 2005-07-13 devnull void
432 004aa293 2005-07-13 devnull markctree(Ctree *t)
433 004aa293 2005-07-13 devnull {
434 004aa293 2005-07-13 devnull int i;
435 004aa293 2005-07-13 devnull Cnode *n;
436 004aa293 2005-07-13 devnull
437 004aa293 2005-07-13 devnull for(i=0; i<nelem(t->hash); i++)
438 004aa293 2005-07-13 devnull for(n=t->hash[i]; n; n=n->nexthash)
439 004aa293 2005-07-13 devnull if(n->name[0] != '+')
440 004aa293 2005-07-13 devnull n->mark = 1;
441 004aa293 2005-07-13 devnull }
442 004aa293 2005-07-13 devnull
443 004aa293 2005-07-13 devnull int
444 004aa293 2005-07-13 devnull refreshdisk(void)
445 004aa293 2005-07-13 devnull {
446 004aa293 2005-07-13 devnull int i;
447 004aa293 2005-07-13 devnull Cnode *n;
448 004aa293 2005-07-13 devnull Ctree *t;
449 fa325e9b 2020-01-10 cross
450 004aa293 2005-07-13 devnull t = config.ctree;
451 004aa293 2005-07-13 devnull for(i=0; i<nelem(t->hash); i++)
452 004aa293 2005-07-13 devnull for(n=t->hash[i]; n; n=n->nexthash){
453 004aa293 2005-07-13 devnull if(n->mfsys)
454 004aa293 2005-07-13 devnull disksync(n->mfsys->disk);
455 004aa293 2005-07-13 devnull if(n->fsys)
456 004aa293 2005-07-13 devnull disksync(n->fsys->disk);
457 004aa293 2005-07-13 devnull }
458 004aa293 2005-07-13 devnull return 0;
459 004aa293 2005-07-13 devnull }
460 004aa293 2005-07-13 devnull
461 004aa293 2005-07-13 devnull void
462 004aa293 2005-07-13 devnull sweepctree(Ctree *t)
463 004aa293 2005-07-13 devnull {
464 004aa293 2005-07-13 devnull int i;
465 004aa293 2005-07-13 devnull Cnode *n;
466 004aa293 2005-07-13 devnull
467 004aa293 2005-07-13 devnull /* just zero all the garbage and leave it linked into the tree */
468 004aa293 2005-07-13 devnull for(i=0; i<nelem(t->hash); i++){
469 004aa293 2005-07-13 devnull for(n=t->hash[i]; n; n=n->nexthash){
470 004aa293 2005-07-13 devnull if(!n->mark)
471 004aa293 2005-07-13 devnull continue;
472 004aa293 2005-07-13 devnull n->fsys = nil;
473 004aa293 2005-07-13 devnull free(n->fsysimage);
474 004aa293 2005-07-13 devnull n->fsysimage = nil;
475 004aa293 2005-07-13 devnull memset(n->fsysscore, 0, sizeof n->fsysscore);
476 004aa293 2005-07-13 devnull n->mfsys = nil;
477 004aa293 2005-07-13 devnull n->ismtpt = 0;
478 004aa293 2005-07-13 devnull memset(&n->fsyshandle, 0, sizeof n->fsyshandle);
479 004aa293 2005-07-13 devnull memset(&n->mfsyshandle, 0, sizeof n->mfsyshandle);
480 004aa293 2005-07-13 devnull }
481 004aa293 2005-07-13 devnull }
482 004aa293 2005-07-13 devnull }
483 004aa293 2005-07-13 devnull
484 004aa293 2005-07-13 devnull static Cnode*
485 004aa293 2005-07-13 devnull cnodewalk(Cnode *n, char *name, uint len, int markokay)
486 004aa293 2005-07-13 devnull {
487 004aa293 2005-07-13 devnull Cnode *nn;
488 fa325e9b 2020-01-10 cross
489 004aa293 2005-07-13 devnull for(nn=n->kidlist; nn; nn=nn->nextsib)
490 004aa293 2005-07-13 devnull if(strncmp(nn->name, name, len) == 0 && nn->name[len] == 0)
491 004aa293 2005-07-13 devnull if(!nn->mark || markokay)
492 004aa293 2005-07-13 devnull return nn;
493 004aa293 2005-07-13 devnull return nil;
494 004aa293 2005-07-13 devnull }
495 004aa293 2005-07-13 devnull
496 004aa293 2005-07-13 devnull Cnode*
497 004aa293 2005-07-13 devnull ctreewalkpath(Ctree *t, char *name, ulong createmtime)
498 004aa293 2005-07-13 devnull {
499 004aa293 2005-07-13 devnull Cnode *n, *nn;
500 004aa293 2005-07-13 devnull char *p, *nextp;
501 fa325e9b 2020-01-10 cross
502 004aa293 2005-07-13 devnull n = t->root;
503 004aa293 2005-07-13 devnull p = name;
504 004aa293 2005-07-13 devnull for(; *p; p=nextp){
505 004aa293 2005-07-13 devnull n->mark = 0;
506 004aa293 2005-07-13 devnull assert(*p == '/');
507 004aa293 2005-07-13 devnull p++;
508 004aa293 2005-07-13 devnull nextp = strchr(p, '/');
509 004aa293 2005-07-13 devnull if(nextp == nil)
510 004aa293 2005-07-13 devnull nextp = p+strlen(p);
511 004aa293 2005-07-13 devnull if((nn = cnodewalk(n, p, nextp-p, 1)) == nil){
512 004aa293 2005-07-13 devnull if(createmtime == 0)
513 004aa293 2005-07-13 devnull return nil;
514 004aa293 2005-07-13 devnull nn = mkcnode(t, n, p, nextp-p, name, nextp-name);
515 004aa293 2005-07-13 devnull nn->mtime = createmtime;
516 004aa293 2005-07-13 devnull }
517 004aa293 2005-07-13 devnull if(nn->mark)
518 004aa293 2005-07-13 devnull nn->mark = 0;
519 004aa293 2005-07-13 devnull n = nn;
520 004aa293 2005-07-13 devnull }
521 004aa293 2005-07-13 devnull n->mark = 0;
522 004aa293 2005-07-13 devnull return n;
523 004aa293 2005-07-13 devnull }
524 004aa293 2005-07-13 devnull
525 004aa293 2005-07-13 devnull Ctree*
526 004aa293 2005-07-13 devnull mkctree(void)
527 004aa293 2005-07-13 devnull {
528 004aa293 2005-07-13 devnull Ctree *t;
529 fa325e9b 2020-01-10 cross
530 004aa293 2005-07-13 devnull t = emalloc(sizeof *t);
531 004aa293 2005-07-13 devnull t->root = mkcnode(t, nil, "", 0, "", 0);
532 fa325e9b 2020-01-10 cross
533 004aa293 2005-07-13 devnull ctreewalkpath(t, "/+log", time(0))->read = logread;
534 004aa293 2005-07-13 devnull ctreewalkpath(t, "/+refreshdisk", time(0))->read = refreshdiskread;
535 004aa293 2005-07-13 devnull ctreewalkpath(t, "/+refreshconfig", time(0))->read = refreshconfigread;
536 004aa293 2005-07-13 devnull
537 004aa293 2005-07-13 devnull return t;
538 004aa293 2005-07-13 devnull }
539 004aa293 2005-07-13 devnull
540 004aa293 2005-07-13 devnull Cnode*
541 004aa293 2005-07-13 devnull ctreemountfsys(Ctree *t, char *path, ulong time, uchar *score, char *file)
542 004aa293 2005-07-13 devnull {
543 004aa293 2005-07-13 devnull Cnode *n;
544 fa325e9b 2020-01-10 cross
545 004aa293 2005-07-13 devnull if(time == 0)
546 004aa293 2005-07-13 devnull time = 1;
547 004aa293 2005-07-13 devnull n = ctreewalkpath(t, path, time);
548 004aa293 2005-07-13 devnull if(score){
549 004aa293 2005-07-13 devnull if(n->ismtpt && (n->fsysimage || memcmp(n->fsysscore, score, VtScoreSize) != 0)){
550 004aa293 2005-07-13 devnull free(n->fsysimage);
551 004aa293 2005-07-13 devnull n->fsysimage = nil;
552 004aa293 2005-07-13 devnull n->fsys = nil; /* leak (might be other refs) */
553 004aa293 2005-07-13 devnull }
554 004aa293 2005-07-13 devnull memmove(n->fsysscore, score, VtScoreSize);
555 004aa293 2005-07-13 devnull }else{
556 004aa293 2005-07-13 devnull if(n->ismtpt && (n->fsysimage==nil || strcmp(n->fsysimage, file) != 0)){
557 004aa293 2005-07-13 devnull free(n->fsysimage);
558 004aa293 2005-07-13 devnull n->fsysimage = nil;
559 004aa293 2005-07-13 devnull n->fsys = nil; /* leak (might be other refs) */
560 004aa293 2005-07-13 devnull }
561 004aa293 2005-07-13 devnull n->fsysimage = emalloc(strlen(file)+1);
562 004aa293 2005-07-13 devnull strcpy(n->fsysimage, file);
563 004aa293 2005-07-13 devnull }
564 004aa293 2005-07-13 devnull n->ismtpt = 1;
565 004aa293 2005-07-13 devnull return n;
566 004aa293 2005-07-13 devnull }
567 004aa293 2005-07-13 devnull
568 004aa293 2005-07-13 devnull Cnode*
569 004aa293 2005-07-13 devnull cnodebyhandle(Ctree *t, uchar *p)
570 004aa293 2005-07-13 devnull {
571 004aa293 2005-07-13 devnull int h;
572 004aa293 2005-07-13 devnull Cnode *n;
573 fa325e9b 2020-01-10 cross
574 004aa293 2005-07-13 devnull h = dumbhash(p);
575 004aa293 2005-07-13 devnull for(n=t->hash[h]; n; n=n->nexthash)
576 004aa293 2005-07-13 devnull if(memcmp(n->handle, p, CnodeHandleSize) == 0)
577 004aa293 2005-07-13 devnull return n;
578 004aa293 2005-07-13 devnull return nil;
579 004aa293 2005-07-13 devnull }
580 004aa293 2005-07-13 devnull
581 004aa293 2005-07-13 devnull static int
582 004aa293 2005-07-13 devnull parseipandmask(char *s, uchar *ip, uchar *mask)
583 004aa293 2005-07-13 devnull {
584 004aa293 2005-07-13 devnull char *p, *q;
585 fa325e9b 2020-01-10 cross
586 004aa293 2005-07-13 devnull p = strchr(s, '/');
587 004aa293 2005-07-13 devnull if(p)
588 004aa293 2005-07-13 devnull *p++ = 0;
589 004aa293 2005-07-13 devnull if(parseip(ip, s) == ~0UL)
590 004aa293 2005-07-13 devnull return -1;
591 004aa293 2005-07-13 devnull if(p == nil)
592 004aa293 2005-07-13 devnull memset(mask, 0xFF, IPaddrlen);
593 004aa293 2005-07-13 devnull else{
594 2b3a8c4d 2005-10-29 devnull if(isdigit((uchar)*p) && strtol(p, &q, 10)>=0 && *q==0)
595 004aa293 2005-07-13 devnull *--p = '/';
596 004aa293 2005-07-13 devnull if(parseipmask(mask, p) == ~0UL)
597 004aa293 2005-07-13 devnull return -1;
598 004aa293 2005-07-13 devnull if(*p != '/')
599 004aa293 2005-07-13 devnull *--p = '/';
600 004aa293 2005-07-13 devnull }
601 cbeb0b26 2006-04-01 devnull /*fprint(2, "parseipandmask %s => %I %I\n", s, ip, mask); */
602 004aa293 2005-07-13 devnull return 0;
603 004aa293 2005-07-13 devnull }
604 004aa293 2005-07-13 devnull
605 004aa293 2005-07-13 devnull static int
606 004aa293 2005-07-13 devnull parsetime(char *s, ulong *time)
607 004aa293 2005-07-13 devnull {
608 004aa293 2005-07-13 devnull ulong x;
609 004aa293 2005-07-13 devnull char *p;
610 004aa293 2005-07-13 devnull int i;
611 004aa293 2005-07-13 devnull Tm tm;
612 fa325e9b 2020-01-10 cross
613 004aa293 2005-07-13 devnull /* decimal integer is seconds since 1970 */
614 004aa293 2005-07-13 devnull x = strtoul(s, &p, 10);
615 004aa293 2005-07-13 devnull if(x > 0 && *p == 0){
616 004aa293 2005-07-13 devnull *time = x;
617 004aa293 2005-07-13 devnull return 0;
618 004aa293 2005-07-13 devnull }
619 fa325e9b 2020-01-10 cross
620 004aa293 2005-07-13 devnull /* otherwise expect yyyy/mmdd/hhmm */
621 004aa293 2005-07-13 devnull if(strlen(s) != 14 || s[4] != '/' || s[9] != '/')
622 004aa293 2005-07-13 devnull return -1;
623 004aa293 2005-07-13 devnull for(i=0; i<4; i++)
624 2b3a8c4d 2005-10-29 devnull if(!isdigit((uchar)s[i]) || !isdigit((uchar)s[i+5]) || !isdigit((uchar)s[i+10]))
625 004aa293 2005-07-13 devnull return -1;
626 004aa293 2005-07-13 devnull memset(&tm, 0, sizeof tm);
627 004aa293 2005-07-13 devnull tm.year = atoi(s)-1900;
628 004aa293 2005-07-13 devnull if(tm.year < 0 || tm.year > 200)
629 004aa293 2005-07-13 devnull return -1;
630 004aa293 2005-07-13 devnull tm.mon = (s[5]-'0')*10+s[6]-'0' - 1;
631 004aa293 2005-07-13 devnull if(tm.mon < 0 || tm.mon > 11)
632 fa325e9b 2020-01-10 cross return -1;
633 004aa293 2005-07-13 devnull tm.mday = (s[7]-'0')*10+s[8]-'0';
634 004aa293 2005-07-13 devnull if(tm.mday < 0 || tm.mday > 31)
635 004aa293 2005-07-13 devnull return -1;
636 004aa293 2005-07-13 devnull tm.hour = (s[10]-'0')*10+s[11]-'0';
637 004aa293 2005-07-13 devnull if(tm.hour < 0 || tm.hour > 23)
638 004aa293 2005-07-13 devnull return -1;
639 004aa293 2005-07-13 devnull tm.min = (s[12]-'0')*10+s[13]-'0';
640 004aa293 2005-07-13 devnull if(tm.min < 0 || tm.min > 59)
641 004aa293 2005-07-13 devnull return -1;
642 004aa293 2005-07-13 devnull strcpy(tm.zone, "XXX"); /* anything but GMT */
643 004aa293 2005-07-13 devnull if(0){
644 004aa293 2005-07-13 devnull print("tm2sec %d/%d/%d/%d/%d\n",
645 004aa293 2005-07-13 devnull tm.year, tm.mon, tm.mday, tm.hour, tm.min);
646 004aa293 2005-07-13 devnull }
647 004aa293 2005-07-13 devnull *time = tm2sec(&tm);
648 004aa293 2005-07-13 devnull if(0) print("time %lud\n", *time);
649 004aa293 2005-07-13 devnull return 0;
650 004aa293 2005-07-13 devnull }
651 004aa293 2005-07-13 devnull
652 004aa293 2005-07-13 devnull
653 004aa293 2005-07-13 devnull int
654 004aa293 2005-07-13 devnull readconfigfile(Config *cp)
655 004aa293 2005-07-13 devnull {
656 004aa293 2005-07-13 devnull char *f[10], *image, *p, *pref, *q, *name;
657 004aa293 2005-07-13 devnull int nf, line;
658 004aa293 2005-07-13 devnull uchar scorebuf[VtScoreSize], *score;
659 004aa293 2005-07-13 devnull ulong time;
660 004aa293 2005-07-13 devnull Biobuf *b;
661 004aa293 2005-07-13 devnull Config c;
662 004aa293 2005-07-13 devnull Dir *dir;
663 004aa293 2005-07-13 devnull
664 004aa293 2005-07-13 devnull name = configfile;
665 004aa293 2005-07-13 devnull c = *cp;
666 004aa293 2005-07-13 devnull if((dir = dirstat(name)) == nil)
667 004aa293 2005-07-13 devnull return -1;
668 004aa293 2005-07-13 devnull if(c.mtime == dir->mtime){
669 004aa293 2005-07-13 devnull free(dir);
670 004aa293 2005-07-13 devnull return 0;
671 004aa293 2005-07-13 devnull }
672 004aa293 2005-07-13 devnull c.mtime = dir->mtime;
673 004aa293 2005-07-13 devnull free(dir);
674 ff3dce55 2007-03-25 devnull if((b = Bopen(name, OREAD)) == nil)
675 004aa293 2005-07-13 devnull return -1;
676 fa325e9b 2020-01-10 cross
677 004aa293 2005-07-13 devnull /*
678 004aa293 2005-07-13 devnull * Reuse old tree, garbage collecting entries that
679 004aa293 2005-07-13 devnull * are not mentioned in the new config file.
680 004aa293 2005-07-13 devnull */
681 004aa293 2005-07-13 devnull if(c.ctree == nil)
682 004aa293 2005-07-13 devnull c.ctree = mkctree();
683 004aa293 2005-07-13 devnull
684 004aa293 2005-07-13 devnull markctree(c.ctree);
685 004aa293 2005-07-13 devnull c.ok = nil;
686 004aa293 2005-07-13 devnull c.nok = 0;
687 fa325e9b 2020-01-10 cross
688 004aa293 2005-07-13 devnull line = 0;
689 004aa293 2005-07-13 devnull for(; (p=Brdstr(b, '\n', 1)) != nil; free(p)){
690 004aa293 2005-07-13 devnull line++;
691 004aa293 2005-07-13 devnull if((q = strchr(p, '#')) != nil)
692 004aa293 2005-07-13 devnull *q = 0;
693 004aa293 2005-07-13 devnull nf = tokenize(p, f, nelem(f));
694 004aa293 2005-07-13 devnull if(nf == 0)
695 004aa293 2005-07-13 devnull continue;
696 004aa293 2005-07-13 devnull if(strcmp(f[0], "mount") == 0){
697 004aa293 2005-07-13 devnull if(nf != 4){
698 004aa293 2005-07-13 devnull werrstr("syntax error: mount /path /dev|score mtime");
699 004aa293 2005-07-13 devnull goto badline;
700 004aa293 2005-07-13 devnull }
701 004aa293 2005-07-13 devnull if(f[1][0] != '/'){
702 004aa293 2005-07-13 devnull werrstr("unrooted path %s", f[1]);
703 004aa293 2005-07-13 devnull goto badline;
704 004aa293 2005-07-13 devnull }
705 004aa293 2005-07-13 devnull score = nil;
706 004aa293 2005-07-13 devnull image = nil;
707 004aa293 2005-07-13 devnull if(f[2][0] == '/'){
708 004aa293 2005-07-13 devnull if(access(f[2], AEXIST) < 0){
709 004aa293 2005-07-13 devnull werrstr("image %s does not exist", f[2]);
710 004aa293 2005-07-13 devnull goto badline;
711 004aa293 2005-07-13 devnull }
712 004aa293 2005-07-13 devnull image = f[2];
713 004aa293 2005-07-13 devnull }else{
714 004aa293 2005-07-13 devnull if(vtparsescore(f[2], &pref, scorebuf) < 0){
715 004aa293 2005-07-13 devnull werrstr("bad score %s", f[2]);
716 004aa293 2005-07-13 devnull goto badline;
717 004aa293 2005-07-13 devnull }
718 004aa293 2005-07-13 devnull score = scorebuf;
719 004aa293 2005-07-13 devnull }
720 004aa293 2005-07-13 devnull if(parsetime(f[3], &time) < 0){
721 004aa293 2005-07-13 devnull fprint(2, "%s:%d: bad time %s\n", name, line, f[3]);
722 004aa293 2005-07-13 devnull time = 1;
723 004aa293 2005-07-13 devnull }
724 004aa293 2005-07-13 devnull ctreemountfsys(c.ctree, f[1], time, score, image);
725 004aa293 2005-07-13 devnull continue;
726 004aa293 2005-07-13 devnull }
727 004aa293 2005-07-13 devnull if(strcmp(f[0], "allow") == 0 || strcmp(f[0], "deny") == 0){
728 004aa293 2005-07-13 devnull if(nf != 2){
729 fa325e9b 2020-01-10 cross werrstr("syntax error: allow|deny ip[/mask]");
730 004aa293 2005-07-13 devnull goto badline;
731 004aa293 2005-07-13 devnull }
732 004aa293 2005-07-13 devnull c.ok = erealloc(c.ok, (c.nok+1)*sizeof(c.ok[0]));
733 004aa293 2005-07-13 devnull if(parseipandmask(f[1], c.ok[c.nok].ip, c.ok[c.nok].mask) < 0){
734 004aa293 2005-07-13 devnull werrstr("bad ip[/mask]: %s", f[1]);
735 004aa293 2005-07-13 devnull goto badline;
736 004aa293 2005-07-13 devnull }
737 004aa293 2005-07-13 devnull c.ok[c.nok].okay = (strcmp(f[0], "allow") == 0);
738 004aa293 2005-07-13 devnull c.nok++;
739 004aa293 2005-07-13 devnull continue;
740 004aa293 2005-07-13 devnull }
741 004aa293 2005-07-13 devnull werrstr("unknown verb '%s'", f[0]);
742 004aa293 2005-07-13 devnull badline:
743 004aa293 2005-07-13 devnull fprint(2, "%s:%d: %r\n", name, line);
744 004aa293 2005-07-13 devnull }
745 004aa293 2005-07-13 devnull Bterm(b);
746 004aa293 2005-07-13 devnull
747 004aa293 2005-07-13 devnull sweepctree(c.ctree);
748 004aa293 2005-07-13 devnull free(cp->ok);
749 004aa293 2005-07-13 devnull *cp = c;
750 004aa293 2005-07-13 devnull return 0;
751 004aa293 2005-07-13 devnull }
752 004aa293 2005-07-13 devnull
753 004aa293 2005-07-13 devnull int
754 004aa293 2005-07-13 devnull ipokay(uchar *ip, ushort port)
755 004aa293 2005-07-13 devnull {
756 004aa293 2005-07-13 devnull int i;
757 004aa293 2005-07-13 devnull uchar ipx[IPaddrlen];
758 fa325e9b 2020-01-10 cross Ipokay *ok;
759 fa325e9b 2020-01-10 cross
760 004aa293 2005-07-13 devnull for(i=0; i<config.nok; i++){
761 004aa293 2005-07-13 devnull ok = &config.ok[i];
762 004aa293 2005-07-13 devnull maskip(ip, ok->mask, ipx);
763 004aa293 2005-07-13 devnull if(0) fprint(2, "%I & %I = %I (== %I?)\n",
764 004aa293 2005-07-13 devnull ip, ok->mask, ipx, ok->ip);
765 004aa293 2005-07-13 devnull if(memcmp(ipx, ok->ip, IPaddrlen) == 0)
766 004aa293 2005-07-13 devnull return ok->okay;
767 004aa293 2005-07-13 devnull }
768 004aa293 2005-07-13 devnull if(config.nok == 0) /* all is permitted */
769 004aa293 2005-07-13 devnull return 1;
770 004aa293 2005-07-13 devnull /* otherwise default is none allowed */
771 004aa293 2005-07-13 devnull return 0;
772 004aa293 2005-07-13 devnull }
773 004aa293 2005-07-13 devnull
774 004aa293 2005-07-13 devnull Nfs3Status
775 004aa293 2005-07-13 devnull cnodelookup(Ctree *t, Cnode **np, char *name)
776 004aa293 2005-07-13 devnull {
777 004aa293 2005-07-13 devnull Cnode *n, *nn;
778 fa325e9b 2020-01-10 cross
779 004aa293 2005-07-13 devnull n = *np;
780 004aa293 2005-07-13 devnull if(n->isblackhole)
781 004aa293 2005-07-13 devnull return Nfs3Ok;
782 004aa293 2005-07-13 devnull if((nn = cnodewalk(n, name, strlen(name), 0)) == nil){
783 004aa293 2005-07-13 devnull if(n->ismtpt || n->fsys){
784 004aa293 2005-07-13 devnull if((nn = cnodewalk(n, "", 0, 1)) == nil){
785 004aa293 2005-07-13 devnull nn = mkcnode(t, n, "", 0, (char*)n->handle, SHA1dlen);
786 004aa293 2005-07-13 devnull nn->isblackhole = 1;
787 004aa293 2005-07-13 devnull }
788 004aa293 2005-07-13 devnull nn->mark = 0;
789 004aa293 2005-07-13 devnull }
790 004aa293 2005-07-13 devnull }
791 004aa293 2005-07-13 devnull if(nn == nil)
792 004aa293 2005-07-13 devnull return Nfs3ErrNoEnt;
793 004aa293 2005-07-13 devnull *np = nn;
794 004aa293 2005-07-13 devnull return Nfs3Ok;
795 004aa293 2005-07-13 devnull }
796 004aa293 2005-07-13 devnull
797 004aa293 2005-07-13 devnull Nfs3Status
798 004aa293 2005-07-13 devnull cnodegetattr(Cnode *n, Nfs3Attr *attr)
799 004aa293 2005-07-13 devnull {
800 0c9c620f 2010-03-10 rsc uint64 u64;
801 0c9c620f 2010-03-10 rsc
802 004aa293 2005-07-13 devnull memset(attr, 0, sizeof *attr);
803 004aa293 2005-07-13 devnull if(n->read){
804 004aa293 2005-07-13 devnull attr->type = Nfs3FileReg;
805 004aa293 2005-07-13 devnull attr->mode = 0444;
806 004aa293 2005-07-13 devnull attr->size = 512;
807 004aa293 2005-07-13 devnull attr->nlink = 1;
808 004aa293 2005-07-13 devnull }else{
809 004aa293 2005-07-13 devnull attr->type = Nfs3FileDir;
810 004aa293 2005-07-13 devnull attr->mode = 0555;
811 004aa293 2005-07-13 devnull attr->size = 1024;
812 004aa293 2005-07-13 devnull attr->nlink = 10;
813 004aa293 2005-07-13 devnull }
814 0c9c620f 2010-03-10 rsc memmove(&u64, n->handle, 8);
815 0c9c620f 2010-03-10 rsc attr->fileid = u64;
816 004aa293 2005-07-13 devnull attr->atime.sec = n->mtime;
817 004aa293 2005-07-13 devnull attr->mtime.sec = n->mtime;
818 004aa293 2005-07-13 devnull attr->ctime.sec = n->mtime;
819 004aa293 2005-07-13 devnull return Nfs3Ok;
820 004aa293 2005-07-13 devnull }
821 004aa293 2005-07-13 devnull
822 004aa293 2005-07-13 devnull Nfs3Status
823 004aa293 2005-07-13 devnull cnodereaddir(Cnode *n, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
824 004aa293 2005-07-13 devnull {
825 004aa293 2005-07-13 devnull uchar *data, *p, *ep, *np;
826 004aa293 2005-07-13 devnull u64int c;
827 0c9c620f 2010-03-10 rsc u64int u64;
828 004aa293 2005-07-13 devnull Nfs3Entry ne;
829 fa325e9b 2020-01-10 cross
830 004aa293 2005-07-13 devnull n = n->kidlist;
831 004aa293 2005-07-13 devnull c = cookie;
832 004aa293 2005-07-13 devnull for(; c && n; c--)
833 004aa293 2005-07-13 devnull n = n->nextsib;
834 004aa293 2005-07-13 devnull if(n == nil){
835 004aa293 2005-07-13 devnull *pdata = 0;
836 004aa293 2005-07-13 devnull *pcount = 0;
837 004aa293 2005-07-13 devnull *peof = 1;
838 004aa293 2005-07-13 devnull return Nfs3Ok;
839 004aa293 2005-07-13 devnull }
840 fa325e9b 2020-01-10 cross
841 004aa293 2005-07-13 devnull data = emalloc(count);
842 004aa293 2005-07-13 devnull p = data;
843 004aa293 2005-07-13 devnull ep = data+count;
844 004aa293 2005-07-13 devnull while(n && p < ep){
845 004aa293 2005-07-13 devnull if(n->mark || n->name[0] == '+'){
846 004aa293 2005-07-13 devnull n = n->nextsib;
847 004aa293 2005-07-13 devnull ++cookie;
848 004aa293 2005-07-13 devnull continue;
849 004aa293 2005-07-13 devnull }
850 004aa293 2005-07-13 devnull ne.name = n->name;
851 80b4aedc 2006-05-04 devnull ne.namelen = strlen(n->name);
852 004aa293 2005-07-13 devnull ne.cookie = ++cookie;
853 0c9c620f 2010-03-10 rsc memmove(&u64, n->handle, 8);
854 0c9c620f 2010-03-10 rsc ne.fileid = u64;
855 004aa293 2005-07-13 devnull if(nfs3entrypack(p, ep, &np, &ne) < 0)
856 004aa293 2005-07-13 devnull break;
857 004aa293 2005-07-13 devnull p = np;
858 004aa293 2005-07-13 devnull n = n->nextsib;
859 004aa293 2005-07-13 devnull }
860 004aa293 2005-07-13 devnull *pdata = data;
861 004aa293 2005-07-13 devnull *pcount = p - data;
862 004aa293 2005-07-13 devnull *peof = n==nil;
863 004aa293 2005-07-13 devnull return Nfs3Ok;
864 004aa293 2005-07-13 devnull }
865 004aa293 2005-07-13 devnull
866 004aa293 2005-07-13 devnull void
867 004aa293 2005-07-13 devnull timerproc(void *v)
868 004aa293 2005-07-13 devnull {
869 004aa293 2005-07-13 devnull for(;;){
870 004aa293 2005-07-13 devnull sleep(60*1000);
871 004aa293 2005-07-13 devnull sendp(timerchan, 0);
872 004aa293 2005-07-13 devnull }
873 004aa293 2005-07-13 devnull }
874 004aa293 2005-07-13 devnull
875 004aa293 2005-07-13 devnull void
876 004aa293 2005-07-13 devnull timerthread(void *v)
877 004aa293 2005-07-13 devnull {
878 004aa293 2005-07-13 devnull for(;;){
879 004aa293 2005-07-13 devnull recvp(timerchan);
880 cbeb0b26 2006-04-01 devnull /* refreshconfig(); */
881 004aa293 2005-07-13 devnull }
882 004aa293 2005-07-13 devnull }
883 004aa293 2005-07-13 devnull
884 004aa293 2005-07-13 devnull /*
885 fa325e9b 2020-01-10 cross * Actually serve the NFS requests. Called from nfs3srv.c.
886 004aa293 2005-07-13 devnull * Each request runs in its own thread (coroutine).
887 004aa293 2005-07-13 devnull *
888 004aa293 2005-07-13 devnull * Decrypted handles have the form:
889 004aa293 2005-07-13 devnull *
890 004aa293 2005-07-13 devnull * config[20] - SHA1 hash identifying a config tree node
891 004aa293 2005-07-13 devnull * glob[10] - SHA1 hash prefix identifying a glob state
892 004aa293 2005-07-13 devnull * fsyshandle[<=10] - disk file system handle (usually 4 bytes)
893 004aa293 2005-07-13 devnull */
894 fa325e9b 2020-01-10 cross
895 004aa293 2005-07-13 devnull /*
896 004aa293 2005-07-13 devnull * A fid represents a point in the file tree.
897 004aa293 2005-07-13 devnull * There are three components, all derived from the handle:
898 004aa293 2005-07-13 devnull *
899 004aa293 2005-07-13 devnull * - config tree position (also used to find fsys)
900 004aa293 2005-07-13 devnull * - glob state for exclusions
901 004aa293 2005-07-13 devnull * - file system position
902 004aa293 2005-07-13 devnull */
903 004aa293 2005-07-13 devnull enum
904 004aa293 2005-07-13 devnull {
905 004aa293 2005-07-13 devnull HAccess,
906 004aa293 2005-07-13 devnull HAttr,
907 004aa293 2005-07-13 devnull HWalk,
908 004aa293 2005-07-13 devnull HDotdot,
909 004aa293 2005-07-13 devnull HRead
910 004aa293 2005-07-13 devnull };
911 004aa293 2005-07-13 devnull typedef struct Fid Fid;
912 004aa293 2005-07-13 devnull struct Fid
913 004aa293 2005-07-13 devnull {
914 004aa293 2005-07-13 devnull Cnode *cnode;
915 004aa293 2005-07-13 devnull Fsys *fsys;
916 004aa293 2005-07-13 devnull Nfs3Handle fsyshandle;
917 004aa293 2005-07-13 devnull };
918 004aa293 2005-07-13 devnull
919 004aa293 2005-07-13 devnull int
920 004aa293 2005-07-13 devnull handlecmp(Nfs3Handle *h, Nfs3Handle *h1)
921 004aa293 2005-07-13 devnull {
922 004aa293 2005-07-13 devnull if(h->len != h1->len)
923 004aa293 2005-07-13 devnull return h->len - h1->len;
924 004aa293 2005-07-13 devnull return memcmp(h->h, h1->h, h->len);
925 004aa293 2005-07-13 devnull }
926 004aa293 2005-07-13 devnull
927 004aa293 2005-07-13 devnull Nfs3Status
928 004aa293 2005-07-13 devnull handletofid(Nfs3Handle *eh, Fid *fid, int mode)
929 004aa293 2005-07-13 devnull {
930 004aa293 2005-07-13 devnull int domount;
931 004aa293 2005-07-13 devnull Cnode *n;
932 004aa293 2005-07-13 devnull Disk *disk, *cdisk;
933 004aa293 2005-07-13 devnull Fsys *fsys;
934 004aa293 2005-07-13 devnull Nfs3Status ok;
935 004aa293 2005-07-13 devnull Nfs3Handle h2, *h, *fh;
936 fa325e9b 2020-01-10 cross
937 004aa293 2005-07-13 devnull memset(fid, 0, sizeof *fid);
938 004aa293 2005-07-13 devnull
939 004aa293 2005-07-13 devnull domount = 1;
940 004aa293 2005-07-13 devnull if(mode == HDotdot)
941 004aa293 2005-07-13 devnull domount = 0;
942 004aa293 2005-07-13 devnull /*
943 004aa293 2005-07-13 devnull * Not necessary, but speeds up ls -l /dump/2005
944 004aa293 2005-07-13 devnull * HAttr and HAccess must be handled the same way
945 004aa293 2005-07-13 devnull * because both can be used to fetch attributes.
946 004aa293 2005-07-13 devnull * Acting differently yields inconsistencies at mount points,
947 004aa293 2005-07-13 devnull * and causes FreeBSD ls -l to fail.
948 004aa293 2005-07-13 devnull */
949 004aa293 2005-07-13 devnull if(mode == HAttr || mode == HAccess)
950 004aa293 2005-07-13 devnull domount = 0;
951 004aa293 2005-07-13 devnull
952 004aa293 2005-07-13 devnull /*
953 004aa293 2005-07-13 devnull * Decrypt handle.
954 004aa293 2005-07-13 devnull */
955 004aa293 2005-07-13 devnull h2 = *eh;
956 004aa293 2005-07-13 devnull h = &h2;
957 004aa293 2005-07-13 devnull if((ok = hdecrypt(h)) != Nfs3Ok)
958 004aa293 2005-07-13 devnull return ok;
959 004aa293 2005-07-13 devnull trace("handletofid: decrypted %.*lH\n", h->len, h->h);
960 004aa293 2005-07-13 devnull if(h->len < FsysHandleOffset)
961 004aa293 2005-07-13 devnull return Nfs3ErrBadHandle;
962 004aa293 2005-07-13 devnull
963 004aa293 2005-07-13 devnull /*
964 004aa293 2005-07-13 devnull * Find place in config tree.
965 004aa293 2005-07-13 devnull */
966 004aa293 2005-07-13 devnull if((n = cnodebyhandle(config.ctree, h->h)) == nil)
967 004aa293 2005-07-13 devnull return Nfs3ErrStale;
968 004aa293 2005-07-13 devnull fid->cnode = n;
969 004aa293 2005-07-13 devnull
970 004aa293 2005-07-13 devnull if(n->ismtpt && domount){
971 004aa293 2005-07-13 devnull /*
972 004aa293 2005-07-13 devnull * Open fsys for mount point if needed.
973 004aa293 2005-07-13 devnull */
974 004aa293 2005-07-13 devnull if(n->mfsys == nil){
975 004aa293 2005-07-13 devnull trace("handletofid: mounting %V/%s\n", n->fsysscore, n->fsysimage);
976 004aa293 2005-07-13 devnull if(n->fsysimage){
977 004aa293 2005-07-13 devnull if(strcmp(n->fsysimage, "/dev/null") == 0)
978 004aa293 2005-07-13 devnull return Nfs3ErrAcces;
979 004aa293 2005-07-13 devnull if((disk = diskopenfile(n->fsysimage)) == nil){
980 004aa293 2005-07-13 devnull fprint(2, "cannot open disk %s: %r\n", n->fsysimage);
981 004aa293 2005-07-13 devnull return Nfs3ErrIo;
982 004aa293 2005-07-13 devnull }
983 004aa293 2005-07-13 devnull if((cdisk = diskcache(disk, blocksize, 64)) == nil){
984 004aa293 2005-07-13 devnull fprint(2, "cannot cache disk %s: %r\n", n->fsysimage);
985 004aa293 2005-07-13 devnull diskclose(disk);
986 004aa293 2005-07-13 devnull }
987 004aa293 2005-07-13 devnull disk = cdisk;
988 004aa293 2005-07-13 devnull }else{
989 004aa293 2005-07-13 devnull if((disk = diskopenventi(vcache, n->fsysscore)) == nil){
990 004aa293 2005-07-13 devnull fprint(2, "cannot open venti disk %V: %r\n", n->fsysscore);
991 004aa293 2005-07-13 devnull return Nfs3ErrIo;
992 004aa293 2005-07-13 devnull }
993 004aa293 2005-07-13 devnull }
994 004aa293 2005-07-13 devnull if((fsys = fsysopen(disk)) == nil){
995 004aa293 2005-07-13 devnull fprint(2, "cannot open fsys on %V: %r\n", n->fsysscore);
996 004aa293 2005-07-13 devnull diskclose(disk);
997 004aa293 2005-07-13 devnull return Nfs3ErrIo;
998 004aa293 2005-07-13 devnull }
999 004aa293 2005-07-13 devnull n->mfsys = fsys;
1000 004aa293 2005-07-13 devnull fsysroot(fsys, &n->mfsyshandle);
1001 004aa293 2005-07-13 devnull }
1002 fa325e9b 2020-01-10 cross
1003 004aa293 2005-07-13 devnull /*
1004 004aa293 2005-07-13 devnull * Use inner handle.
1005 004aa293 2005-07-13 devnull */
1006 004aa293 2005-07-13 devnull fid->fsys = n->mfsys;
1007 004aa293 2005-07-13 devnull fid->fsyshandle = n->mfsyshandle;
1008 004aa293 2005-07-13 devnull }else{
1009 004aa293 2005-07-13 devnull /*
1010 004aa293 2005-07-13 devnull * Use fsys handle from tree or from handle.
1011 004aa293 2005-07-13 devnull * This assumes that fsyshandle was set by fidtohandle
1012 004aa293 2005-07-13 devnull * earlier, so it's not okay to reuse handles (except the root)
1013 fa325e9b 2020-01-10 cross * across sessions. The encryption above makes and
1014 004aa293 2005-07-13 devnull * enforces the same restriction, so this is okay.
1015 004aa293 2005-07-13 devnull */
1016 004aa293 2005-07-13 devnull fid->fsys = n->fsys;
1017 004aa293 2005-07-13 devnull fh = &fid->fsyshandle;
1018 004aa293 2005-07-13 devnull if(n->isblackhole){
1019 004aa293 2005-07-13 devnull fh->len = h->len-FsysHandleOffset;
1020 004aa293 2005-07-13 devnull memmove(fh->h, h->h+FsysHandleOffset, fh->len);
1021 004aa293 2005-07-13 devnull }else
1022 004aa293 2005-07-13 devnull *fh = n->fsyshandle;
1023 004aa293 2005-07-13 devnull trace("handletofid: fsyshandle %.*lH\n", fh->len, fh->h);
1024 004aa293 2005-07-13 devnull }
1025 004aa293 2005-07-13 devnull
1026 004aa293 2005-07-13 devnull /*
1027 004aa293 2005-07-13 devnull * TO DO (maybe): some sort of path restriction here.
1028 004aa293 2005-07-13 devnull */
1029 004aa293 2005-07-13 devnull trace("handletofid: cnode %s fsys %p fsyshandle %.*lH\n",
1030 004aa293 2005-07-13 devnull n->name, fid->fsys, fid->fsyshandle.len, fid->fsyshandle.h);
1031 004aa293 2005-07-13 devnull return Nfs3Ok;
1032 004aa293 2005-07-13 devnull }
1033 004aa293 2005-07-13 devnull
1034 004aa293 2005-07-13 devnull void
1035 004aa293 2005-07-13 devnull _fidtohandle(Fid *fid, Nfs3Handle *h)
1036 004aa293 2005-07-13 devnull {
1037 004aa293 2005-07-13 devnull Cnode *n;
1038 fa325e9b 2020-01-10 cross
1039 004aa293 2005-07-13 devnull n = fid->cnode;
1040 004aa293 2005-07-13 devnull /*
1041 004aa293 2005-07-13 devnull * Record fsys handle in n, don't bother sending it to client
1042 004aa293 2005-07-13 devnull * for black holes.
1043 004aa293 2005-07-13 devnull */
1044 004aa293 2005-07-13 devnull n->fsys = fid->fsys;
1045 004aa293 2005-07-13 devnull if(!n->isblackhole){
1046 004aa293 2005-07-13 devnull n->fsyshandle = fid->fsyshandle;
1047 004aa293 2005-07-13 devnull fid->fsyshandle.len = 0;
1048 004aa293 2005-07-13 devnull }
1049 004aa293 2005-07-13 devnull memmove(h->h, n->handle, CnodeHandleSize);
1050 004aa293 2005-07-13 devnull memmove(h->h+FsysHandleOffset, fid->fsyshandle.h, fid->fsyshandle.len);
1051 004aa293 2005-07-13 devnull h->len = FsysHandleOffset+fid->fsyshandle.len;
1052 004aa293 2005-07-13 devnull }
1053 004aa293 2005-07-13 devnull
1054 004aa293 2005-07-13 devnull void
1055 004aa293 2005-07-13 devnull fidtohandle(Fid *fid, Nfs3Handle *h)
1056 004aa293 2005-07-13 devnull {
1057 004aa293 2005-07-13 devnull _fidtohandle(fid, h);
1058 004aa293 2005-07-13 devnull hencrypt(h);
1059 004aa293 2005-07-13 devnull }
1060 004aa293 2005-07-13 devnull
1061 004aa293 2005-07-13 devnull void
1062 004aa293 2005-07-13 devnull setrootfid(void)
1063 004aa293 2005-07-13 devnull {
1064 004aa293 2005-07-13 devnull Fid fid;
1065 fa325e9b 2020-01-10 cross
1066 004aa293 2005-07-13 devnull memset(&fid, 0, sizeof fid);
1067 004aa293 2005-07-13 devnull fid.cnode = config.ctree->root;
1068 004aa293 2005-07-13 devnull _fidtohandle(&fid, &root);
1069 004aa293 2005-07-13 devnull }
1070 004aa293 2005-07-13 devnull
1071 004aa293 2005-07-13 devnull void
1072 004aa293 2005-07-13 devnull fsgetroot(Nfs3Handle *h)
1073 004aa293 2005-07-13 devnull {
1074 004aa293 2005-07-13 devnull *h = root;
1075 004aa293 2005-07-13 devnull hencrypt(h);
1076 004aa293 2005-07-13 devnull }
1077 004aa293 2005-07-13 devnull
1078 004aa293 2005-07-13 devnull Nfs3Status
1079 004aa293 2005-07-13 devnull fsgetattr(SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
1080 004aa293 2005-07-13 devnull {
1081 004aa293 2005-07-13 devnull Fid fid;
1082 004aa293 2005-07-13 devnull Nfs3Status ok;
1083 004aa293 2005-07-13 devnull
1084 004aa293 2005-07-13 devnull trace("getattr %.*lH\n", h->len, h->h);
1085 004aa293 2005-07-13 devnull if((ok = handletofid(h, &fid, HAttr)) != Nfs3Ok)
1086 004aa293 2005-07-13 devnull return ok;
1087 004aa293 2005-07-13 devnull if(fid.fsys)
1088 004aa293 2005-07-13 devnull return fsysgetattr(fid.fsys, au, &fid.fsyshandle, attr);
1089 004aa293 2005-07-13 devnull else
1090 004aa293 2005-07-13 devnull return cnodegetattr(fid.cnode, attr);
1091 004aa293 2005-07-13 devnull }
1092 004aa293 2005-07-13 devnull
1093 004aa293 2005-07-13 devnull /*
1094 004aa293 2005-07-13 devnull * Lookup is always the hard part.
1095 004aa293 2005-07-13 devnull */
1096 004aa293 2005-07-13 devnull Nfs3Status
1097 004aa293 2005-07-13 devnull fslookup(SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
1098 004aa293 2005-07-13 devnull {
1099 004aa293 2005-07-13 devnull Fid fid;
1100 004aa293 2005-07-13 devnull Cnode *n;
1101 004aa293 2005-07-13 devnull Nfs3Status ok;
1102 004aa293 2005-07-13 devnull Nfs3Handle xh;
1103 004aa293 2005-07-13 devnull int mode;
1104 fa325e9b 2020-01-10 cross
1105 004aa293 2005-07-13 devnull trace("lookup %.*lH %s\n", h->len, h->h, name);
1106 004aa293 2005-07-13 devnull
1107 004aa293 2005-07-13 devnull mode = HWalk;
1108 004aa293 2005-07-13 devnull if(strcmp(name, "..") == 0 || strcmp(name, ".") == 0)
1109 004aa293 2005-07-13 devnull mode = HDotdot;
1110 004aa293 2005-07-13 devnull if((ok = handletofid(h, &fid, mode)) != Nfs3Ok){
1111 004aa293 2005-07-13 devnull nfs3errstr(ok);
1112 004aa293 2005-07-13 devnull trace("lookup: handletofid %r\n");
1113 004aa293 2005-07-13 devnull return ok;
1114 004aa293 2005-07-13 devnull }
1115 fa325e9b 2020-01-10 cross
1116 004aa293 2005-07-13 devnull if(strcmp(name, ".") == 0){
1117 004aa293 2005-07-13 devnull fidtohandle(&fid, nh);
1118 004aa293 2005-07-13 devnull return Nfs3Ok;
1119 004aa293 2005-07-13 devnull }
1120 004aa293 2005-07-13 devnull
1121 004aa293 2005-07-13 devnull /*
1122 004aa293 2005-07-13 devnull * Walk down file system and cnode simultaneously.
1123 004aa293 2005-07-13 devnull * If dotdot and file system doesn't move, need to walk
1124 004aa293 2005-07-13 devnull * up cnode. Save the corresponding fsys handles in
1125 fa325e9b 2020-01-10 cross * the cnode as we walk down so that we'll have them
1126 004aa293 2005-07-13 devnull * for dotdotting back up.
1127 004aa293 2005-07-13 devnull */
1128 004aa293 2005-07-13 devnull n = fid.cnode;
1129 004aa293 2005-07-13 devnull if(mode == HWalk){
1130 004aa293 2005-07-13 devnull /*
1131 004aa293 2005-07-13 devnull * Walk down config tree and file system simultaneously.
1132 004aa293 2005-07-13 devnull */
1133 004aa293 2005-07-13 devnull if((ok = cnodelookup(config.ctree, &n, name)) != Nfs3Ok){
1134 004aa293 2005-07-13 devnull nfs3errstr(ok);
1135 004aa293 2005-07-13 devnull trace("lookup: cnodelookup: %r\n");
1136 004aa293 2005-07-13 devnull return ok;
1137 004aa293 2005-07-13 devnull }
1138 004aa293 2005-07-13 devnull fid.cnode = n;
1139 004aa293 2005-07-13 devnull if(fid.fsys){
1140 004aa293 2005-07-13 devnull if((ok = fsyslookup(fid.fsys, au, &fid.fsyshandle, name, &xh)) != Nfs3Ok){
1141 004aa293 2005-07-13 devnull nfs3errstr(ok);
1142 004aa293 2005-07-13 devnull trace("lookup: fsyslookup: %r\n");
1143 004aa293 2005-07-13 devnull return ok;
1144 004aa293 2005-07-13 devnull }
1145 004aa293 2005-07-13 devnull fid.fsyshandle = xh;
1146 fa325e9b 2020-01-10 cross }
1147 004aa293 2005-07-13 devnull }else{
1148 004aa293 2005-07-13 devnull /*
1149 004aa293 2005-07-13 devnull * Walking dotdot. Ick.
1150 004aa293 2005-07-13 devnull */
1151 004aa293 2005-07-13 devnull trace("lookup dotdot fsys=%p\n", fid.fsys);
1152 004aa293 2005-07-13 devnull if(fid.fsys){
1153 004aa293 2005-07-13 devnull /*
1154 004aa293 2005-07-13 devnull * Walk up file system, then try up config tree.
1155 004aa293 2005-07-13 devnull */
1156 004aa293 2005-07-13 devnull if((ok = fsyslookup(fid.fsys, au, &fid.fsyshandle, "..", &xh)) != Nfs3Ok){
1157 004aa293 2005-07-13 devnull nfs3errstr(ok);
1158 004aa293 2005-07-13 devnull trace("lookup fsyslookup: %r\n");
1159 004aa293 2005-07-13 devnull return ok;
1160 004aa293 2005-07-13 devnull }
1161 004aa293 2005-07-13 devnull fid.fsyshandle = xh;
1162 004aa293 2005-07-13 devnull
1163 004aa293 2005-07-13 devnull /*
1164 004aa293 2005-07-13 devnull * Usually just go to n->parent.
1165 fa325e9b 2020-01-10 cross *
1166 004aa293 2005-07-13 devnull * If we're in a subtree of the mounted file system that
1167 004aa293 2005-07-13 devnull * isn't represented explicitly by the config tree (instead
1168 004aa293 2005-07-13 devnull * the black hole node represents the entire file tree),
1169 004aa293 2005-07-13 devnull * then we only go to n->parent when we've dotdotted back
1170 004aa293 2005-07-13 devnull * to the right handle.
1171 004aa293 2005-07-13 devnull */
1172 004aa293 2005-07-13 devnull if(n->parent == nil)
1173 004aa293 2005-07-13 devnull trace("lookup dotdot: no parent\n");
1174 004aa293 2005-07-13 devnull else{
1175 004aa293 2005-07-13 devnull trace("lookup dotdot: parent %.*lH, have %.*lH\n",
1176 004aa293 2005-07-13 devnull n->parent->fsyshandle.len, n->parent->fsyshandle.h,
1177 004aa293 2005-07-13 devnull xh.len, xh.h);
1178 004aa293 2005-07-13 devnull }
1179 fa325e9b 2020-01-10 cross
1180 004aa293 2005-07-13 devnull if(n->isblackhole){
1181 004aa293 2005-07-13 devnull if(handlecmp(&n->parent->mfsyshandle, &xh) == 0)
1182 004aa293 2005-07-13 devnull n = n->parent;
1183 004aa293 2005-07-13 devnull }else{
1184 004aa293 2005-07-13 devnull if(n->parent)
1185 004aa293 2005-07-13 devnull n = n->parent;
1186 004aa293 2005-07-13 devnull }
1187 004aa293 2005-07-13 devnull }else{
1188 004aa293 2005-07-13 devnull /*
1189 004aa293 2005-07-13 devnull * No file system, just walk up.
1190 004aa293 2005-07-13 devnull */
1191 004aa293 2005-07-13 devnull if(n->parent)
1192 004aa293 2005-07-13 devnull n = n->parent;
1193 004aa293 2005-07-13 devnull }
1194 004aa293 2005-07-13 devnull fid.fsys = n->fsys;
1195 c59c3b21 2007-06-04 devnull if(!n->isblackhole)
1196 c59c3b21 2007-06-04 devnull fid.fsyshandle = n->fsyshandle;
1197 004aa293 2005-07-13 devnull fid.cnode = n;
1198 004aa293 2005-07-13 devnull }
1199 004aa293 2005-07-13 devnull fidtohandle(&fid, nh);
1200 004aa293 2005-07-13 devnull return Nfs3Ok;
1201 004aa293 2005-07-13 devnull }
1202 004aa293 2005-07-13 devnull
1203 004aa293 2005-07-13 devnull Nfs3Status
1204 004aa293 2005-07-13 devnull fsaccess(SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
1205 004aa293 2005-07-13 devnull {
1206 004aa293 2005-07-13 devnull Fid fid;
1207 004aa293 2005-07-13 devnull Nfs3Status ok;
1208 fa325e9b 2020-01-10 cross
1209 004aa293 2005-07-13 devnull trace("access %.*lH 0x%ux\n", h->len, h->h, want);
1210 004aa293 2005-07-13 devnull if((ok = handletofid(h, &fid, HAccess)) != Nfs3Ok)
1211 004aa293 2005-07-13 devnull return ok;
1212 004aa293 2005-07-13 devnull if(fid.fsys)
1213 004aa293 2005-07-13 devnull return fsysaccess(fid.fsys, au, &fid.fsyshandle, want, got, attr);
1214 004aa293 2005-07-13 devnull *got = want & (Nfs3AccessRead|Nfs3AccessLookup|Nfs3AccessExecute);
1215 004aa293 2005-07-13 devnull return cnodegetattr(fid.cnode, attr);
1216 004aa293 2005-07-13 devnull }
1217 004aa293 2005-07-13 devnull
1218 004aa293 2005-07-13 devnull Nfs3Status
1219 004aa293 2005-07-13 devnull fsreadlink(SunAuthUnix *au, Nfs3Handle *h, char **link)
1220 004aa293 2005-07-13 devnull {
1221 004aa293 2005-07-13 devnull Fid fid;
1222 004aa293 2005-07-13 devnull Nfs3Status ok;
1223 fa325e9b 2020-01-10 cross
1224 004aa293 2005-07-13 devnull trace("readlink %.*lH\n", h->len, h->h);
1225 004aa293 2005-07-13 devnull if((ok = handletofid(h, &fid, HRead)) != Nfs3Ok)
1226 004aa293 2005-07-13 devnull return ok;
1227 004aa293 2005-07-13 devnull if(fid.fsys)
1228 004aa293 2005-07-13 devnull return fsysreadlink(fid.fsys, au, &fid.fsyshandle, link);
1229 004aa293 2005-07-13 devnull *link = 0;
1230 004aa293 2005-07-13 devnull return Nfs3ErrNotSupp;
1231 004aa293 2005-07-13 devnull }
1232 004aa293 2005-07-13 devnull
1233 004aa293 2005-07-13 devnull Nfs3Status
1234 004aa293 2005-07-13 devnull fsreadfile(SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
1235 004aa293 2005-07-13 devnull {
1236 004aa293 2005-07-13 devnull Fid fid;
1237 004aa293 2005-07-13 devnull Nfs3Status ok;
1238 fa325e9b 2020-01-10 cross
1239 004aa293 2005-07-13 devnull trace("readfile %.*lH\n", h->len, h->h);
1240 004aa293 2005-07-13 devnull if((ok = handletofid(h, &fid, HRead)) != Nfs3Ok)
1241 004aa293 2005-07-13 devnull return ok;
1242 004aa293 2005-07-13 devnull if(fid.cnode->read)
1243 004aa293 2005-07-13 devnull return fid.cnode->read(fid.cnode, count, offset, data, pcount, peof);
1244 004aa293 2005-07-13 devnull if(fid.fsys)
1245 004aa293 2005-07-13 devnull return fsysreadfile(fid.fsys, au, &fid.fsyshandle, count, offset, data, pcount, peof);
1246 004aa293 2005-07-13 devnull return Nfs3ErrNotSupp;
1247 004aa293 2005-07-13 devnull }
1248 004aa293 2005-07-13 devnull
1249 004aa293 2005-07-13 devnull Nfs3Status
1250 004aa293 2005-07-13 devnull fsreaddir(SunAuthUnix *au, Nfs3Handle *h, u32int len, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
1251 004aa293 2005-07-13 devnull {
1252 004aa293 2005-07-13 devnull Fid fid;
1253 004aa293 2005-07-13 devnull Nfs3Status ok;
1254 004aa293 2005-07-13 devnull
1255 fa325e9b 2020-01-10 cross trace("readdir %.*lH\n", h->len, h->h);
1256 004aa293 2005-07-13 devnull if((ok = handletofid(h, &fid, HRead)) != Nfs3Ok)
1257 004aa293 2005-07-13 devnull return ok;
1258 004aa293 2005-07-13 devnull if(fid.fsys)
1259 004aa293 2005-07-13 devnull return fsysreaddir(fid.fsys, au, &fid.fsyshandle, len, cookie, pdata, pcount, peof);
1260 004aa293 2005-07-13 devnull return cnodereaddir(fid.cnode, len, cookie, pdata, pcount, peof);
1261 004aa293 2005-07-13 devnull }
1262 004aa293 2005-07-13 devnull
1263 004aa293 2005-07-13 devnull Nfs3Status
1264 004aa293 2005-07-13 devnull logread(Cnode *n, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
1265 004aa293 2005-07-13 devnull {
1266 004aa293 2005-07-13 devnull *pcount = 0;
1267 004aa293 2005-07-13 devnull *peof = 1;
1268 004aa293 2005-07-13 devnull return Nfs3Ok;
1269 004aa293 2005-07-13 devnull }
1270 004aa293 2005-07-13 devnull
1271 004aa293 2005-07-13 devnull Nfs3Status
1272 004aa293 2005-07-13 devnull refreshdiskread(Cnode *n, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
1273 004aa293 2005-07-13 devnull {
1274 004aa293 2005-07-13 devnull char buf[128];
1275 fa325e9b 2020-01-10 cross
1276 004aa293 2005-07-13 devnull if(offset != 0){
1277 004aa293 2005-07-13 devnull *pcount = 0;
1278 004aa293 2005-07-13 devnull *peof = 1;
1279 004aa293 2005-07-13 devnull return Nfs3Ok;
1280 004aa293 2005-07-13 devnull }
1281 004aa293 2005-07-13 devnull if(refreshdisk() < 0)
1282 004aa293 2005-07-13 devnull snprint(buf, sizeof buf, "refreshdisk: %r\n");
1283 004aa293 2005-07-13 devnull else
1284 004aa293 2005-07-13 devnull strcpy(buf, "ok\n");
1285 004aa293 2005-07-13 devnull *data = emalloc(strlen(buf));
1286 004aa293 2005-07-13 devnull strcpy((char*)*data, buf);
1287 004aa293 2005-07-13 devnull *pcount = strlen(buf);
1288 004aa293 2005-07-13 devnull *peof = 1;
1289 004aa293 2005-07-13 devnull return Nfs3Ok;
1290 004aa293 2005-07-13 devnull }
1291 004aa293 2005-07-13 devnull
1292 004aa293 2005-07-13 devnull Nfs3Status
1293 004aa293 2005-07-13 devnull refreshconfigread(Cnode *n, u32int count, u64int offset, uchar **data, u32int *pcount, u1int *peof)
1294 004aa293 2005-07-13 devnull {
1295 004aa293 2005-07-13 devnull char buf[128];
1296 fa325e9b 2020-01-10 cross
1297 004aa293 2005-07-13 devnull if(offset != 0){
1298 004aa293 2005-07-13 devnull *pcount = 0;
1299 004aa293 2005-07-13 devnull *peof = 1;
1300 004aa293 2005-07-13 devnull return Nfs3Ok;
1301 004aa293 2005-07-13 devnull }
1302 004aa293 2005-07-13 devnull if(readconfigfile(&config) < 0)
1303 004aa293 2005-07-13 devnull snprint(buf, sizeof buf, "readconfig: %r\n");
1304 004aa293 2005-07-13 devnull else
1305 004aa293 2005-07-13 devnull strcpy(buf, "ok\n");
1306 004aa293 2005-07-13 devnull *data = emalloc(strlen(buf));
1307 004aa293 2005-07-13 devnull strcpy((char*)*data, buf);
1308 004aa293 2005-07-13 devnull *pcount = strlen(buf);
1309 004aa293 2005-07-13 devnull *peof = 1;
1310 004aa293 2005-07-13 devnull return Nfs3Ok;
1311 004aa293 2005-07-13 devnull }