1 /*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
8 * %sccs.include.redist.c%
9 *
10 * @(#)nfs_syscalls.c 8.5 (Berkeley) 03/30/95
11 */
12
13 #include <sys/param.h>
14 #include <sys/systm.h>
15 #include <sys/kernel.h>
16 #include <sys/file.h>
17 #include <sys/stat.h>
18 #include <sys/vnode.h>
19 #include <sys/mount.h>
20 #include <sys/proc.h>
21 #include <sys/uio.h>
22 #include <sys/malloc.h>
23 #include <sys/buf.h>
24 #include <sys/mbuf.h>
25 #include <sys/socket.h>
26 #include <sys/socketvar.h>
27 #include <sys/domain.h>
28 #include <sys/protosw.h>
29 #include <sys/namei.h>
30 #include <sys/syslog.h>
31
32 #include <netinet/in.h>
33 #include <netinet/tcp.h>
34 #ifdef ISO
35 #include <netiso/iso.h>
36 #endif
37 #include <nfs/xdr_subs.h>
38 #include <nfs/rpcv2.h>
39 #include <nfs/nfsproto.h>
40 #include <nfs/nfs.h>
41 #include <nfs/nfsm_subs.h>
42 #include <nfs/nfsrvcache.h>
43 #include <nfs/nfsmount.h>
44 #include <nfs/nfsnode.h>
45 #include <nfs/nqnfs.h>
46 #include <nfs/nfsrtt.h>
47
48 void nfsrv_zapsock __P((struct nfssvc_sock *));
49
50 /* Global defs. */
51 extern int (*nfsrv3_procs[NFS_NPROCS])();
52 extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON];
53 extern int nfs_numasync;
54 extern time_t nqnfsstarttime;
55 extern int nqsrv_writeslack;
56 extern int nfsrtton;
57 extern struct nfsstats nfsstats;
58 extern int nfsrvw_procrastinate;
59 struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock;
60 int nuidhash_max = NFS_MAXUIDHASH;
61 static int nfs_numnfsd = 0;
62 int nfsd_waiting = 0;
63 static int notstarted = 1;
64 static int modify_flag = 0;
65 static struct nfsdrt nfsdrt;
66 void nfsrv_cleancache(), nfsrv_rcv(), nfsrv_wakenfsd(), nfs_sndunlock();
67 static void nfsd_rt();
68 void nfsrv_slpderef();
69
70 #define TRUE 1
71 #define FALSE 0
72
73 static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
74 /*
75 * NFS server system calls
76 * getfh() lives here too, but maybe should move to kern/vfs_syscalls.c
77 */
78
79 /*
80 * Get file handle system call
81 */
82 struct getfh_args {
83 char *fname;
84 fhandle_t *fhp;
85 };
86 int
getfh(p,uap,retval)87 getfh(p, uap, retval)
88 struct proc *p;
89 register struct getfh_args *uap;
90 int *retval;
91 {
92 register struct vnode *vp;
93 fhandle_t fh;
94 int error;
95 struct nameidata nd;
96
97 /*
98 * Must be super user
99 */
100 error = suser(p->p_ucred, &p->p_acflag);
101 if(error)
102 return (error);
103 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
104 error = namei(&nd);
105 if (error)
106 return (error);
107 vp = nd.ni_vp;
108 bzero((caddr_t)&fh, sizeof(fh));
109 fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid;
110 error = VFS_VPTOFH(vp, &fh.fh_fid);
111 vput(vp);
112 if (error)
113 return (error);
114 error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh));
115 return (error);
116 }
117
118 /*
119 * Nfs server psuedo system call for the nfsd's
120 * Based on the flag value it either:
121 * - adds a socket to the selection list
122 * - remains in the kernel as an nfsd
123 * - remains in the kernel as an nfsiod
124 */
125 struct nfssvc_args {
126 int flag;
127 caddr_t argp;
128 };
129 int
nfssvc(p,uap,retval)130 nfssvc(p, uap, retval)
131 struct proc *p;
132 register struct nfssvc_args *uap;
133 int *retval;
134 {
135 struct nameidata nd;
136 struct file *fp;
137 struct mbuf *nam;
138 struct nfsd_args nfsdarg;
139 struct nfsd_srvargs nfsd_srvargs, *nsd = &nfsd_srvargs;
140 struct nfsd_cargs ncd;
141 struct nfsd *nfsd;
142 struct nfssvc_sock *slp;
143 struct nfsuid *nuidp;
144 struct nfsmount *nmp;
145 int error;
146
147 /*
148 * Must be super user
149 */
150 error = suser(p->p_ucred, &p->p_acflag);
151 if(error)
152 return (error);
153 while (nfssvc_sockhead_flag & SLP_INIT) {
154 nfssvc_sockhead_flag |= SLP_WANTINIT;
155 (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
156 }
157 if (uap->flag & NFSSVC_BIOD)
158 error = nfssvc_iod(p);
159 else if (uap->flag & NFSSVC_MNTD) {
160 error = copyin(uap->argp, (caddr_t)&ncd, sizeof (ncd));
161 if (error)
162 return (error);
163 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
164 ncd.ncd_dirp, p);
165 error = namei(&nd);
166 if (error)
167 return (error);
168 if ((nd.ni_vp->v_flag & VROOT) == 0)
169 error = EINVAL;
170 nmp = VFSTONFS(nd.ni_vp->v_mount);
171 vput(nd.ni_vp);
172 if (error)
173 return (error);
174 if ((nmp->nm_flag & NFSMNT_MNTD) &&
175 (uap->flag & NFSSVC_GOTAUTH) == 0)
176 return (0);
177 nmp->nm_flag |= NFSMNT_MNTD;
178 error = nqnfs_clientd(nmp, p->p_ucred, &ncd, uap->flag,
179 uap->argp, p);
180 } else if (uap->flag & NFSSVC_ADDSOCK) {
181 error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
182 if (error)
183 return (error);
184 error = getsock(p->p_fd, nfsdarg.sock, &fp);
185 if (error)
186 return (error);
187 /*
188 * Get the client address for connected sockets.
189 */
190 if (nfsdarg.name == NULL || nfsdarg.namelen == 0)
191 nam = (struct mbuf *)0;
192 else {
193 error = sockargs(&nam, nfsdarg.name, nfsdarg.namelen,
194 MT_SONAME);
195 if (error)
196 return (error);
197 }
198 error = nfssvc_addsock(fp, nam);
199 } else {
200 error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd));
201 if (error)
202 return (error);
203 if ((uap->flag & NFSSVC_AUTHIN) && ((nfsd = nsd->nsd_nfsd)) &&
204 (nfsd->nfsd_slp->ns_flag & SLP_VALID)) {
205 slp = nfsd->nfsd_slp;
206
207 /*
208 * First check to see if another nfsd has already
209 * added this credential.
210 */
211 for (nuidp = NUIDHASH(slp,nsd->nsd_cr.cr_uid)->lh_first;
212 nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
213 if (nuidp->nu_cr.cr_uid == nsd->nsd_cr.cr_uid &&
214 (!nfsd->nfsd_nd->nd_nam2 ||
215 netaddr_match(NU_NETFAM(nuidp),
216 &nuidp->nu_haddr, nfsd->nfsd_nd->nd_nam2)))
217 break;
218 }
219 if (nuidp) {
220 nfsrv_setcred(&nuidp->nu_cr,&nfsd->nfsd_nd->nd_cr);
221 nfsd->nfsd_nd->nd_flag |= ND_KERBFULL;
222 } else {
223 /*
224 * Nope, so we will.
225 */
226 if (slp->ns_numuids < nuidhash_max) {
227 slp->ns_numuids++;
228 nuidp = (struct nfsuid *)
229 malloc(sizeof (struct nfsuid), M_NFSUID,
230 M_WAITOK);
231 } else
232 nuidp = (struct nfsuid *)0;
233 if ((slp->ns_flag & SLP_VALID) == 0) {
234 if (nuidp)
235 free((caddr_t)nuidp, M_NFSUID);
236 } else {
237 if (nuidp == (struct nfsuid *)0) {
238 nuidp = slp->ns_uidlruhead.tqh_first;
239 LIST_REMOVE(nuidp, nu_hash);
240 TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp,
241 nu_lru);
242 if (nuidp->nu_flag & NU_NAM)
243 m_freem(nuidp->nu_nam);
244 }
245 nuidp->nu_flag = 0;
246 nuidp->nu_cr = nsd->nsd_cr;
247 if (nuidp->nu_cr.cr_ngroups > NGROUPS)
248 nuidp->nu_cr.cr_ngroups = NGROUPS;
249 nuidp->nu_cr.cr_ref = 1;
250 nuidp->nu_timestamp = nsd->nsd_timestamp;
251 nuidp->nu_expire = time.tv_sec + nsd->nsd_ttl;
252 /*
253 * and save the session key in nu_key.
254 */
255 bcopy(nsd->nsd_key, nuidp->nu_key,
256 sizeof (nsd->nsd_key));
257 if (nfsd->nfsd_nd->nd_nam2) {
258 struct sockaddr_in *saddr;
259
260 saddr = mtod(nfsd->nfsd_nd->nd_nam2,
261 struct sockaddr_in *);
262 switch (saddr->sin_family) {
263 case AF_INET:
264 nuidp->nu_flag |= NU_INETADDR;
265 nuidp->nu_inetaddr =
266 saddr->sin_addr.s_addr;
267 break;
268 case AF_ISO:
269 default:
270 nuidp->nu_flag |= NU_NAM;
271 nuidp->nu_nam = m_copym(
272 nfsd->nfsd_nd->nd_nam2, 0,
273 M_COPYALL, M_WAIT);
274 break;
275 };
276 }
277 TAILQ_INSERT_TAIL(&slp->ns_uidlruhead, nuidp,
278 nu_lru);
279 LIST_INSERT_HEAD(NUIDHASH(slp, nsd->nsd_uid),
280 nuidp, nu_hash);
281 nfsrv_setcred(&nuidp->nu_cr,
282 &nfsd->nfsd_nd->nd_cr);
283 nfsd->nfsd_nd->nd_flag |= ND_KERBFULL;
284 }
285 }
286 }
287 if ((uap->flag & NFSSVC_AUTHINFAIL) && (nfsd = nsd->nsd_nfsd))
288 nfsd->nfsd_flag |= NFSD_AUTHFAIL;
289 error = nfssvc_nfsd(nsd, uap->argp, p);
290 }
291 if (error == EINTR || error == ERESTART)
292 error = 0;
293 return (error);
294 }
295
296 /*
297 * Adds a socket to the list for servicing by nfsds.
298 */
299 int
nfssvc_addsock(fp,mynam)300 nfssvc_addsock(fp, mynam)
301 struct file *fp;
302 struct mbuf *mynam;
303 {
304 register struct mbuf *m;
305 register int siz;
306 register struct nfssvc_sock *slp;
307 register struct socket *so;
308 struct nfssvc_sock *tslp;
309 int error, s;
310
311 so = (struct socket *)fp->f_data;
312 tslp = (struct nfssvc_sock *)0;
313 /*
314 * Add it to the list, as required.
315 */
316 if (so->so_proto->pr_protocol == IPPROTO_UDP) {
317 tslp = nfs_udpsock;
318 if (tslp->ns_flag & SLP_VALID) {
319 m_freem(mynam);
320 return (EPERM);
321 }
322 #ifdef ISO
323 } else if (so->so_proto->pr_protocol == ISOPROTO_CLTP) {
324 tslp = nfs_cltpsock;
325 if (tslp->ns_flag & SLP_VALID) {
326 m_freem(mynam);
327 return (EPERM);
328 }
329 #endif /* ISO */
330 }
331 if (so->so_type == SOCK_STREAM)
332 siz = NFS_MAXPACKET + sizeof (u_long);
333 else
334 siz = NFS_MAXPACKET;
335 error = soreserve(so, siz, siz);
336 if (error) {
337 m_freem(mynam);
338 return (error);
339 }
340
341 /*
342 * Set protocol specific options { for now TCP only } and
343 * reserve some space. For datagram sockets, this can get called
344 * repeatedly for the same socket, but that isn't harmful.
345 */
346 if (so->so_type == SOCK_STREAM) {
347 MGET(m, M_WAIT, MT_SOOPTS);
348 *mtod(m, int *) = 1;
349 m->m_len = sizeof(int);
350 sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
351 }
352 if (so->so_proto->pr_domain->dom_family == AF_INET &&
353 so->so_proto->pr_protocol == IPPROTO_TCP) {
354 MGET(m, M_WAIT, MT_SOOPTS);
355 *mtod(m, int *) = 1;
356 m->m_len = sizeof(int);
357 sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
358 }
359 so->so_rcv.sb_flags &= ~SB_NOINTR;
360 so->so_rcv.sb_timeo = 0;
361 so->so_snd.sb_flags &= ~SB_NOINTR;
362 so->so_snd.sb_timeo = 0;
363 if (tslp)
364 slp = tslp;
365 else {
366 slp = (struct nfssvc_sock *)
367 malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
368 bzero((caddr_t)slp, sizeof (struct nfssvc_sock));
369 TAILQ_INIT(&slp->ns_uidlruhead);
370 TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain);
371 }
372 slp->ns_so = so;
373 slp->ns_nam = mynam;
374 fp->f_count++;
375 slp->ns_fp = fp;
376 s = splnet();
377 so->so_upcallarg = (caddr_t)slp;
378 so->so_upcall = nfsrv_rcv;
379 slp->ns_flag = (SLP_VALID | SLP_NEEDQ);
380 nfsrv_wakenfsd(slp);
381 splx(s);
382 return (0);
383 }
384
385 /*
386 * Called by nfssvc() for nfsds. Just loops around servicing rpc requests
387 * until it is killed by a signal.
388 */
389 int
nfssvc_nfsd(nsd,argp,p)390 nfssvc_nfsd(nsd, argp, p)
391 struct nfsd_srvargs *nsd;
392 caddr_t argp;
393 struct proc *p;
394 {
395 register struct mbuf *m;
396 register int siz;
397 register struct nfssvc_sock *slp;
398 register struct socket *so;
399 register int *solockp;
400 struct nfsd *nfsd = nsd->nsd_nfsd;
401 struct nfsrv_descript *nd = NULL;
402 struct mbuf *mreq;
403 struct nfsuid *uidp;
404 int error = 0, cacherep, s, sotype, writes_todo;
405 u_quad_t cur_usec;
406
407 #ifndef nolint
408 cacherep = RC_DOIT;
409 writes_todo = 0;
410 #endif
411 s = splnet();
412 if (nfsd == (struct nfsd *)0) {
413 nsd->nsd_nfsd = nfsd = (struct nfsd *)
414 malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK);
415 bzero((caddr_t)nfsd, sizeof (struct nfsd));
416 nfsd->nfsd_procp = p;
417 TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain);
418 nfs_numnfsd++;
419 }
420 /*
421 * Loop getting rpc requests until SIGKILL.
422 */
423 for (;;) {
424 if ((nfsd->nfsd_flag & NFSD_REQINPROG) == 0) {
425 while (nfsd->nfsd_slp == (struct nfssvc_sock *)0 &&
426 (nfsd_head_flag & NFSD_CHECKSLP) == 0) {
427 nfsd->nfsd_flag |= NFSD_WAITING;
428 nfsd_waiting++;
429 error = tsleep((caddr_t)nfsd, PSOCK | PCATCH,
430 "nfsd", 0);
431 nfsd_waiting--;
432 if (error)
433 goto done;
434 }
435 if (nfsd->nfsd_slp == (struct nfssvc_sock *)0 &&
436 (nfsd_head_flag & NFSD_CHECKSLP) != 0) {
437 for (slp = nfssvc_sockhead.tqh_first; slp != 0;
438 slp = slp->ns_chain.tqe_next) {
439 if ((slp->ns_flag & (SLP_VALID | SLP_DOREC))
440 == (SLP_VALID | SLP_DOREC)) {
441 slp->ns_flag &= ~SLP_DOREC;
442 slp->ns_sref++;
443 nfsd->nfsd_slp = slp;
444 break;
445 }
446 }
447 if (slp == 0)
448 nfsd_head_flag &= ~NFSD_CHECKSLP;
449 }
450 if ((slp = nfsd->nfsd_slp) == (struct nfssvc_sock *)0)
451 continue;
452 if (slp->ns_flag & SLP_VALID) {
453 if (slp->ns_flag & SLP_DISCONN)
454 nfsrv_zapsock(slp);
455 else if (slp->ns_flag & SLP_NEEDQ) {
456 slp->ns_flag &= ~SLP_NEEDQ;
457 (void) nfs_sndlock(&slp->ns_solock,
458 (struct nfsreq *)0);
459 nfsrv_rcv(slp->ns_so, (caddr_t)slp,
460 M_WAIT);
461 nfs_sndunlock(&slp->ns_solock);
462 }
463 error = nfsrv_dorec(slp, nfsd, &nd);
464 cur_usec = (u_quad_t)time.tv_sec * 1000000 +
465 (u_quad_t)time.tv_usec;
466 if (error && slp->ns_tq.lh_first &&
467 slp->ns_tq.lh_first->nd_time <= cur_usec) {
468 error = 0;
469 cacherep = RC_DOIT;
470 writes_todo = 1;
471 } else
472 writes_todo = 0;
473 nfsd->nfsd_flag |= NFSD_REQINPROG;
474 }
475 } else {
476 error = 0;
477 slp = nfsd->nfsd_slp;
478 }
479 if (error || (slp->ns_flag & SLP_VALID) == 0) {
480 if (nd) {
481 free((caddr_t)nd, M_NFSRVDESC);
482 nd = NULL;
483 }
484 nfsd->nfsd_slp = (struct nfssvc_sock *)0;
485 nfsd->nfsd_flag &= ~NFSD_REQINPROG;
486 nfsrv_slpderef(slp);
487 continue;
488 }
489 splx(s);
490 so = slp->ns_so;
491 sotype = so->so_type;
492 if (so->so_proto->pr_flags & PR_CONNREQUIRED)
493 solockp = &slp->ns_solock;
494 else
495 solockp = (int *)0;
496 if (nd) {
497 nd->nd_starttime = time;
498 if (nd->nd_nam2)
499 nd->nd_nam = nd->nd_nam2;
500 else
501 nd->nd_nam = slp->ns_nam;
502
503 /*
504 * Check to see if authorization is needed.
505 */
506 if (nfsd->nfsd_flag & NFSD_NEEDAUTH) {
507 nfsd->nfsd_flag &= ~NFSD_NEEDAUTH;
508 nsd->nsd_haddr = mtod(nd->nd_nam,
509 struct sockaddr_in *)->sin_addr.s_addr;
510 nsd->nsd_authlen = nfsd->nfsd_authlen;
511 nsd->nsd_verflen = nfsd->nfsd_verflen;
512 if (!copyout(nfsd->nfsd_authstr,nsd->nsd_authstr,
513 nfsd->nfsd_authlen) &&
514 !copyout(nfsd->nfsd_verfstr, nsd->nsd_verfstr,
515 nfsd->nfsd_verflen) &&
516 !copyout((caddr_t)nsd, argp, sizeof (*nsd)))
517 return (ENEEDAUTH);
518 cacherep = RC_DROPIT;
519 } else
520 cacherep = nfsrv_getcache(nd, slp, &mreq);
521
522 /*
523 * Check for just starting up for NQNFS and send
524 * fake "try again later" replies to the NQNFS clients.
525 */
526 if (notstarted && nqnfsstarttime <= time.tv_sec) {
527 if (modify_flag) {
528 nqnfsstarttime = time.tv_sec + nqsrv_writeslack;
529 modify_flag = 0;
530 } else
531 notstarted = 0;
532 }
533 if (notstarted) {
534 if ((nd->nd_flag & ND_NQNFS) == 0)
535 cacherep = RC_DROPIT;
536 else if (nd->nd_procnum != NFSPROC_WRITE) {
537 nd->nd_procnum = NFSPROC_NOOP;
538 nd->nd_repstat = NQNFS_TRYLATER;
539 cacherep = RC_DOIT;
540 } else
541 modify_flag = 1;
542 } else if (nfsd->nfsd_flag & NFSD_AUTHFAIL) {
543 nfsd->nfsd_flag &= ~NFSD_AUTHFAIL;
544 nd->nd_procnum = NFSPROC_NOOP;
545 nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK);
546 cacherep = RC_DOIT;
547 }
548 }
549
550 /*
551 * Loop to get all the write rpc relies that have been
552 * gathered together.
553 */
554 do {
555 switch (cacherep) {
556 case RC_DOIT:
557 if (writes_todo || (nd->nd_procnum == NFSPROC_WRITE &&
558 nfsrvw_procrastinate > 0 && !notstarted))
559 error = nfsrv_writegather(&nd, slp,
560 nfsd->nfsd_procp, &mreq);
561 else
562 error = (*(nfsrv3_procs[nd->nd_procnum]))(nd,
563 slp, nfsd->nfsd_procp, &mreq);
564 if (mreq == NULL)
565 break;
566 if (error) {
567 if (nd->nd_procnum != NQNFSPROC_VACATED)
568 nfsstats.srv_errs++;
569 nfsrv_updatecache(nd, FALSE, mreq);
570 if (nd->nd_nam2)
571 m_freem(nd->nd_nam2);
572 break;
573 }
574 nfsstats.srvrpccnt[nd->nd_procnum]++;
575 nfsrv_updatecache(nd, TRUE, mreq);
576 nd->nd_mrep = (struct mbuf *)0;
577 case RC_REPLY:
578 m = mreq;
579 siz = 0;
580 while (m) {
581 siz += m->m_len;
582 m = m->m_next;
583 }
584 if (siz <= 0 || siz > NFS_MAXPACKET) {
585 printf("mbuf siz=%d\n",siz);
586 panic("Bad nfs svc reply");
587 }
588 m = mreq;
589 m->m_pkthdr.len = siz;
590 m->m_pkthdr.rcvif = (struct ifnet *)0;
591 /*
592 * For stream protocols, prepend a Sun RPC
593 * Record Mark.
594 */
595 if (sotype == SOCK_STREAM) {
596 M_PREPEND(m, NFSX_UNSIGNED, M_WAIT);
597 *mtod(m, u_long *) = htonl(0x80000000 | siz);
598 }
599 if (solockp)
600 (void) nfs_sndlock(solockp, (struct nfsreq *)0);
601 if (slp->ns_flag & SLP_VALID)
602 error = nfs_send(so, nd->nd_nam2, m, NULL);
603 else {
604 error = EPIPE;
605 m_freem(m);
606 }
607 if (nfsrtton)
608 nfsd_rt(sotype, nd, cacherep);
609 if (nd->nd_nam2)
610 MFREE(nd->nd_nam2, m);
611 if (nd->nd_mrep)
612 m_freem(nd->nd_mrep);
613 if (error == EPIPE)
614 nfsrv_zapsock(slp);
615 if (solockp)
616 nfs_sndunlock(solockp);
617 if (error == EINTR || error == ERESTART) {
618 free((caddr_t)nd, M_NFSRVDESC);
619 nfsrv_slpderef(slp);
620 s = splnet();
621 goto done;
622 }
623 break;
624 case RC_DROPIT:
625 if (nfsrtton)
626 nfsd_rt(sotype, nd, cacherep);
627 m_freem(nd->nd_mrep);
628 m_freem(nd->nd_nam2);
629 break;
630 };
631 if (nd) {
632 FREE((caddr_t)nd, M_NFSRVDESC);
633 nd = NULL;
634 }
635
636 /*
637 * Check to see if there are outstanding writes that
638 * need to be serviced.
639 */
640 cur_usec = (u_quad_t)time.tv_sec * 1000000 +
641 (u_quad_t)time.tv_usec;
642 s = splsoftclock();
643 if (slp->ns_tq.lh_first &&
644 slp->ns_tq.lh_first->nd_time <= cur_usec) {
645 cacherep = RC_DOIT;
646 writes_todo = 1;
647 } else
648 writes_todo = 0;
649 splx(s);
650 } while (writes_todo);
651 s = splnet();
652 if (nfsrv_dorec(slp, nfsd, &nd)) {
653 nfsd->nfsd_flag &= ~NFSD_REQINPROG;
654 nfsd->nfsd_slp = NULL;
655 nfsrv_slpderef(slp);
656 }
657 }
658 done:
659 TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain);
660 splx(s);
661 free((caddr_t)nfsd, M_NFSD);
662 nsd->nsd_nfsd = (struct nfsd *)0;
663 if (--nfs_numnfsd == 0)
664 nfsrv_init(TRUE); /* Reinitialize everything */
665 return (error);
666 }
667
668 /*
669 * Asynchronous I/O daemons for client nfs.
670 * They do read-ahead and write-behind operations on the block I/O cache.
671 * Never returns unless it fails or gets killed.
672 */
673 int
nfssvc_iod(p)674 nfssvc_iod(p)
675 struct proc *p;
676 {
677 register struct buf *bp, *nbp;
678 register int i, myiod;
679 struct vnode *vp;
680 int error = 0, s;
681
682 /*
683 * Assign my position or return error if too many already running
684 */
685 myiod = -1;
686 for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
687 if (nfs_asyncdaemon[i] == 0) {
688 nfs_asyncdaemon[i]++;
689 myiod = i;
690 break;
691 }
692 if (myiod == -1)
693 return (EBUSY);
694 nfs_numasync++;
695 /*
696 * Just loop around doin our stuff until SIGKILL
697 */
698 for (;;) {
699 while (nfs_bufq.tqh_first == NULL && error == 0) {
700 nfs_iodwant[myiod] = p;
701 error = tsleep((caddr_t)&nfs_iodwant[myiod],
702 PWAIT | PCATCH, "nfsidl", 0);
703 }
704 while ((bp = nfs_bufq.tqh_first) != NULL) {
705 /* Take one off the front of the list */
706 TAILQ_REMOVE(&nfs_bufq, bp, b_freelist);
707 if (bp->b_flags & B_READ)
708 (void) nfs_doio(bp, bp->b_rcred, (struct proc *)0);
709 else do {
710 /*
711 * Look for a delayed write for the same vnode, so I can do
712 * it now. We must grab it before calling nfs_doio() to
713 * avoid any risk of the vnode getting vclean()'d while
714 * we are doing the write rpc.
715 */
716 vp = bp->b_vp;
717 s = splbio();
718 for (nbp = vp->v_dirtyblkhd.lh_first; nbp;
719 nbp = nbp->b_vnbufs.le_next) {
720 if ((nbp->b_flags &
721 (B_BUSY|B_DELWRI|B_NEEDCOMMIT|B_NOCACHE))!=B_DELWRI)
722 continue;
723 bremfree(nbp);
724 nbp->b_flags |= (B_BUSY|B_ASYNC);
725 break;
726 }
727 splx(s);
728 /*
729 * For the delayed write, do the first part of nfs_bwrite()
730 * up to, but not including nfs_strategy().
731 */
732 if (nbp) {
733 nbp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI);
734 reassignbuf(nbp, nbp->b_vp);
735 nbp->b_vp->v_numoutput++;
736 }
737 (void) nfs_doio(bp, bp->b_wcred, (struct proc *)0);
738 } while (bp = nbp);
739 }
740 if (error) {
741 nfs_asyncdaemon[myiod] = 0;
742 nfs_numasync--;
743 return (error);
744 }
745 }
746 }
747
748 /*
749 * Shut down a socket associated with an nfssvc_sock structure.
750 * Should be called with the send lock set, if required.
751 * The trick here is to increment the sref at the start, so that the nfsds
752 * will stop using it and clear ns_flag at the end so that it will not be
753 * reassigned during cleanup.
754 */
755 void
nfsrv_zapsock(slp)756 nfsrv_zapsock(slp)
757 register struct nfssvc_sock *slp;
758 {
759 register struct nfsuid *nuidp, *nnuidp;
760 register struct nfsrv_descript *nwp, *nnwp;
761 struct socket *so;
762 struct file *fp;
763 struct mbuf *m;
764 int s;
765
766 slp->ns_flag &= ~SLP_ALLFLAGS;
767 fp = slp->ns_fp;
768 if (fp) {
769 slp->ns_fp = (struct file *)0;
770 so = slp->ns_so;
771 so->so_upcall = NULL;
772 soshutdown(so, 2);
773 closef(fp, (struct proc *)0);
774 if (slp->ns_nam)
775 MFREE(slp->ns_nam, m);
776 m_freem(slp->ns_raw);
777 m_freem(slp->ns_rec);
778 for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0;
779 nuidp = nnuidp) {
780 nnuidp = nuidp->nu_lru.tqe_next;
781 LIST_REMOVE(nuidp, nu_hash);
782 TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru);
783 if (nuidp->nu_flag & NU_NAM)
784 m_freem(nuidp->nu_nam);
785 free((caddr_t)nuidp, M_NFSUID);
786 }
787 s = splsoftclock();
788 for (nwp = slp->ns_tq.lh_first; nwp; nwp = nnwp) {
789 nnwp = nwp->nd_tq.le_next;
790 LIST_REMOVE(nwp, nd_tq);
791 free((caddr_t)nwp, M_NFSRVDESC);
792 }
793 LIST_INIT(&slp->ns_tq);
794 splx(s);
795 }
796 }
797
798 /*
799 * Get an authorization string for the uid by having the mount_nfs sitting
800 * on this mount point porpous out of the kernel and do it.
801 */
802 int
nfs_getauth(nmp,rep,cred,auth_str,auth_len,verf_str,verf_len,key)803 nfs_getauth(nmp, rep, cred, auth_str, auth_len, verf_str, verf_len, key)
804 register struct nfsmount *nmp;
805 struct nfsreq *rep;
806 struct ucred *cred;
807 char **auth_str;
808 int *auth_len;
809 char *verf_str;
810 int *verf_len;
811 NFSKERBKEY_T key; /* return session key */
812 {
813 int error = 0;
814
815 while ((nmp->nm_flag & NFSMNT_WAITAUTH) == 0) {
816 nmp->nm_flag |= NFSMNT_WANTAUTH;
817 (void) tsleep((caddr_t)&nmp->nm_authtype, PSOCK,
818 "nfsauth1", 2 * hz);
819 error = nfs_sigintr(nmp, rep, rep->r_procp);
820 if (error) {
821 nmp->nm_flag &= ~NFSMNT_WANTAUTH;
822 return (error);
823 }
824 }
825 nmp->nm_flag &= ~(NFSMNT_WAITAUTH | NFSMNT_WANTAUTH);
826 nmp->nm_authstr = *auth_str = (char *)malloc(RPCAUTH_MAXSIZ, M_TEMP, M_WAITOK);
827 nmp->nm_authlen = RPCAUTH_MAXSIZ;
828 nmp->nm_verfstr = verf_str;
829 nmp->nm_verflen = *verf_len;
830 nmp->nm_authuid = cred->cr_uid;
831 wakeup((caddr_t)&nmp->nm_authstr);
832
833 /*
834 * And wait for mount_nfs to do its stuff.
835 */
836 while ((nmp->nm_flag & NFSMNT_HASAUTH) == 0 && error == 0) {
837 (void) tsleep((caddr_t)&nmp->nm_authlen, PSOCK,
838 "nfsauth2", 2 * hz);
839 error = nfs_sigintr(nmp, rep, rep->r_procp);
840 }
841 if (nmp->nm_flag & NFSMNT_AUTHERR) {
842 nmp->nm_flag &= ~NFSMNT_AUTHERR;
843 error = EAUTH;
844 }
845 if (error)
846 free((caddr_t)*auth_str, M_TEMP);
847 else {
848 *auth_len = nmp->nm_authlen;
849 *verf_len = nmp->nm_verflen;
850 bcopy((caddr_t)nmp->nm_key, (caddr_t)key, sizeof (key));
851 }
852 nmp->nm_flag &= ~NFSMNT_HASAUTH;
853 nmp->nm_flag |= NFSMNT_WAITAUTH;
854 if (nmp->nm_flag & NFSMNT_WANTAUTH) {
855 nmp->nm_flag &= ~NFSMNT_WANTAUTH;
856 wakeup((caddr_t)&nmp->nm_authtype);
857 }
858 return (error);
859 }
860
861 /*
862 * Get a nickname authenticator and verifier.
863 */
864 int
nfs_getnickauth(nmp,cred,auth_str,auth_len,verf_str,verf_len)865 nfs_getnickauth(nmp, cred, auth_str, auth_len, verf_str, verf_len)
866 struct nfsmount *nmp;
867 struct ucred *cred;
868 char **auth_str;
869 int *auth_len;
870 char *verf_str;
871 int verf_len;
872 {
873 register struct nfsuid *nuidp;
874 register u_long *nickp, *verfp;
875 struct timeval ktvin, ktvout;
876 NFSKERBKEYSCHED_T keys; /* stores key schedule */
877
878 #ifdef DIAGNOSTIC
879 if (verf_len < (4 * NFSX_UNSIGNED))
880 panic("nfs_getnickauth verf too small");
881 #endif
882 for (nuidp = NMUIDHASH(nmp, cred->cr_uid)->lh_first;
883 nuidp != 0; nuidp = nuidp->nu_hash.le_next) {
884 if (nuidp->nu_cr.cr_uid == cred->cr_uid)
885 break;
886 }
887 if (!nuidp || nuidp->nu_expire < time.tv_sec)
888 return (EACCES);
889
890 /*
891 * Move to the end of the lru list (end of lru == most recently used).
892 */
893 TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp, nu_lru);
894 TAILQ_INSERT_TAIL(&nmp->nm_uidlruhead, nuidp, nu_lru);
895
896 nickp = (u_long *)malloc(2 * NFSX_UNSIGNED, M_TEMP, M_WAITOK);
897 *nickp++ = txdr_unsigned(RPCAKN_NICKNAME);
898 *nickp = txdr_unsigned(nuidp->nu_nickname);
899 *auth_str = (char *)nickp;
900 *auth_len = 2 * NFSX_UNSIGNED;
901
902 /*
903 * Now we must encrypt the verifier and package it up.
904 */
905 verfp = (u_long *)verf_str;
906 *verfp++ = txdr_unsigned(RPCAKN_NICKNAME);
907 if (time.tv_sec > nuidp->nu_timestamp.tv_sec ||
908 (time.tv_sec == nuidp->nu_timestamp.tv_sec &&
909 time.tv_usec > nuidp->nu_timestamp.tv_usec))
910 nuidp->nu_timestamp = time;
911 else
912 nuidp->nu_timestamp.tv_usec++;
913 ktvin.tv_sec = txdr_unsigned(nuidp->nu_timestamp.tv_sec);
914 ktvin.tv_usec = txdr_unsigned(nuidp->nu_timestamp.tv_usec);
915
916 /*
917 * Now encrypt the timestamp verifier in ecb mode using the session
918 * key.
919 */
920 #ifdef NFSKERB
921 XXX
922 #endif
923
924 *verfp++ = ktvout.tv_sec;
925 *verfp++ = ktvout.tv_usec;
926 *verfp = 0;
927 return (0);
928 }
929
930 /*
931 * Save the current nickname in a hash list entry on the mount point.
932 */
933 int
nfs_savenickauth(nmp,cred,len,key,mdp,dposp,mrep)934 nfs_savenickauth(nmp, cred, len, key, mdp, dposp, mrep)
935 register struct nfsmount *nmp;
936 struct ucred *cred;
937 int len;
938 NFSKERBKEY_T key;
939 struct mbuf **mdp;
940 char **dposp;
941 struct mbuf *mrep;
942 {
943 register struct nfsuid *nuidp;
944 register u_long *tl;
945 register long t1;
946 struct mbuf *md = *mdp;
947 struct timeval ktvin, ktvout;
948 u_long nick;
949 NFSKERBKEYSCHED_T keys;
950 char *dpos = *dposp, *cp2;
951 int deltasec, error = 0;
952
953 if (len == (3 * NFSX_UNSIGNED)) {
954 nfsm_dissect(tl, u_long *, 3 * NFSX_UNSIGNED);
955 ktvin.tv_sec = *tl++;
956 ktvin.tv_usec = *tl++;
957 nick = fxdr_unsigned(u_long, *tl);
958
959 /*
960 * Decrypt the timestamp in ecb mode.
961 */
962 #ifdef NFSKERB
963 XXX
964 #endif
965 ktvout.tv_sec = fxdr_unsigned(long, ktvout.tv_sec);
966 ktvout.tv_usec = fxdr_unsigned(long, ktvout.tv_usec);
967 deltasec = time.tv_sec - ktvout.tv_sec;
968 if (deltasec < 0)
969 deltasec = -deltasec;
970 /*
971 * If ok, add it to the hash list for the mount point.
972 */
973 if (deltasec <= NFS_KERBCLOCKSKEW) {
974 if (nmp->nm_numuids < nuidhash_max) {
975 nmp->nm_numuids++;
976 nuidp = (struct nfsuid *)
977 malloc(sizeof (struct nfsuid), M_NFSUID,
978 M_WAITOK);
979 } else {
980 nuidp = nmp->nm_uidlruhead.tqh_first;
981 LIST_REMOVE(nuidp, nu_hash);
982 TAILQ_REMOVE(&nmp->nm_uidlruhead, nuidp,
983 nu_lru);
984 }
985 nuidp->nu_flag = 0;
986 nuidp->nu_cr.cr_uid = cred->cr_uid;
987 nuidp->nu_expire = time.tv_sec + NFS_KERBTTL;
988 nuidp->nu_timestamp = ktvout;
989 nuidp->nu_nickname = nick;
990 bcopy(key, nuidp->nu_key, sizeof (key));
991 TAILQ_INSERT_TAIL(&nmp->nm_uidlruhead, nuidp,
992 nu_lru);
993 LIST_INSERT_HEAD(NMUIDHASH(nmp, cred->cr_uid),
994 nuidp, nu_hash);
995 }
996 } else
997 nfsm_adv(nfsm_rndup(len));
998 nfsmout:
999 *mdp = md;
1000 *dposp = dpos;
1001 return (error);
1002 }
1003
1004 /*
1005 * Derefence a server socket structure. If it has no more references and
1006 * is no longer valid, you can throw it away.
1007 */
1008 void
nfsrv_slpderef(slp)1009 nfsrv_slpderef(slp)
1010 register struct nfssvc_sock *slp;
1011 {
1012 if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) {
1013 TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
1014 free((caddr_t)slp, M_NFSSVC);
1015 }
1016 }
1017
1018 /*
1019 * Initialize the data structures for the server.
1020 * Handshake with any new nfsds starting up to avoid any chance of
1021 * corruption.
1022 */
1023 void
nfsrv_init(terminating)1024 nfsrv_init(terminating)
1025 int terminating;
1026 {
1027 register struct nfssvc_sock *slp, *nslp;
1028
1029 if (nfssvc_sockhead_flag & SLP_INIT)
1030 panic("nfsd init");
1031 nfssvc_sockhead_flag |= SLP_INIT;
1032 if (terminating) {
1033 for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) {
1034 nslp = slp->ns_chain.tqe_next;
1035 if (slp->ns_flag & SLP_VALID)
1036 nfsrv_zapsock(slp);
1037 TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
1038 free((caddr_t)slp, M_NFSSVC);
1039 }
1040 nfsrv_cleancache(); /* And clear out server cache */
1041 }
1042
1043 TAILQ_INIT(&nfssvc_sockhead);
1044 nfssvc_sockhead_flag &= ~SLP_INIT;
1045 if (nfssvc_sockhead_flag & SLP_WANTINIT) {
1046 nfssvc_sockhead_flag &= ~SLP_WANTINIT;
1047 wakeup((caddr_t)&nfssvc_sockhead);
1048 }
1049
1050 TAILQ_INIT(&nfsd_head);
1051 nfsd_head_flag &= ~NFSD_CHECKSLP;
1052
1053 nfs_udpsock = (struct nfssvc_sock *)
1054 malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
1055 bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock));
1056 TAILQ_INIT(&nfs_udpsock->ns_uidlruhead);
1057 TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain);
1058
1059 nfs_cltpsock = (struct nfssvc_sock *)
1060 malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK);
1061 bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock));
1062 TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead);
1063 TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain);
1064 }
1065
1066 /*
1067 * Add entries to the server monitor log.
1068 */
1069 static void
nfsd_rt(sotype,nd,cacherep)1070 nfsd_rt(sotype, nd, cacherep)
1071 int sotype;
1072 register struct nfsrv_descript *nd;
1073 int cacherep;
1074 {
1075 register struct drt *rt;
1076
1077 rt = &nfsdrt.drt[nfsdrt.pos];
1078 if (cacherep == RC_DOIT)
1079 rt->flag = 0;
1080 else if (cacherep == RC_REPLY)
1081 rt->flag = DRT_CACHEREPLY;
1082 else
1083 rt->flag = DRT_CACHEDROP;
1084 if (sotype == SOCK_STREAM)
1085 rt->flag |= DRT_TCP;
1086 if (nd->nd_flag & ND_NQNFS)
1087 rt->flag |= DRT_NQNFS;
1088 else if (nd->nd_flag & ND_NFSV3)
1089 rt->flag |= DRT_NFSV3;
1090 rt->proc = nd->nd_procnum;
1091 if (mtod(nd->nd_nam, struct sockaddr *)->sa_family == AF_INET)
1092 rt->ipadr = mtod(nd->nd_nam, struct sockaddr_in *)->sin_addr.s_addr;
1093 else
1094 rt->ipadr = INADDR_ANY;
1095 rt->resptime = ((time.tv_sec - nd->nd_starttime.tv_sec) * 1000000) +
1096 (time.tv_usec - nd->nd_starttime.tv_usec);
1097 rt->tstamp = time;
1098 nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ;
1099 }
1100