Commit | Line | Data |
---|---|---|
a2907882 KM |
1 | /* |
2 | * Copyright (c) 1989 The Regents of the University of California. | |
3 | * 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 | * Redistribution and use in source and binary forms are permitted | |
9 | * provided that the above copyright notice and this paragraph are | |
10 | * duplicated in all such forms and that any documentation, | |
11 | * advertising materials, and other materials related to such | |
12 | * distribution and use acknowledge that the software was developed | |
13 | * by the University of California, Berkeley. The name of the | |
14 | * University may not be used to endorse or promote products derived | |
15 | * from this software without specific prior written permission. | |
16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
19 | * | |
20 | * @(#)nfs_syscalls.c 7.1 (Berkeley) %G% | |
21 | */ | |
22 | ||
23 | #include "param.h" | |
24 | #include "systm.h" | |
25 | #include "user.h" | |
26 | #include "kernel.h" | |
27 | #include "file.h" | |
28 | #include "stat.h" | |
29 | #include "vnode.h" | |
30 | #include "mount.h" | |
31 | #include "proc.h" | |
32 | #include "uio.h" | |
33 | #include "malloc.h" | |
34 | #include "mbuf.h" | |
35 | #include "socket.h" | |
36 | #include "socketvar.h" | |
37 | #include "nfsv2.h" | |
38 | #include "nfs.h" | |
39 | ||
40 | /* Global defs. */ | |
41 | extern u_long nfs_prog, nfs_vers; | |
42 | extern int (*nfsrv_procs[NFS_NPROCS])(); | |
43 | struct file *getsock(); | |
44 | ||
45 | /* | |
46 | * NFS server system calls | |
47 | * getfh() lives here too, but maybe should move to kern/vfs_syscalls.c | |
48 | */ | |
49 | #define RETURN(value) { u.u_error = (value); return; } | |
50 | ||
51 | /* | |
52 | * Get file handle system call | |
53 | */ | |
54 | getfh() | |
55 | { | |
56 | register struct a { | |
57 | char *fname; | |
58 | fhandle_t *fhp; | |
59 | } *uap = (struct a *)u.u_ap; | |
60 | register struct nameidata *ndp = &u.u_nd; | |
61 | register struct vnode *vp; | |
62 | fhandle_t fh; | |
63 | int error; | |
64 | ||
65 | /* | |
66 | * Must be super user | |
67 | */ | |
68 | if (error = suser(u.u_cred, &u.u_acflag)) | |
69 | RETURN (error); | |
70 | ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW; | |
71 | ndp->ni_segflg = UIO_USERSPACE; | |
72 | ndp->ni_dirp = uap->fname; | |
73 | if (error = namei(ndp)) | |
74 | RETURN (error); | |
75 | vp = ndp->ni_vp; | |
76 | bzero((caddr_t)&fh, sizeof(fh)); | |
77 | fh.fh_fsid = vp->v_mount->m_fsid; | |
78 | error = VFS_VPTOFH(vp, &fh.fh_fid); | |
79 | vput(vp); | |
80 | if (error) | |
81 | RETURN (error); | |
82 | error = copyout((caddr_t)&fh, (caddr_t)uap->fhp, sizeof (fh)); | |
83 | RETURN (error); | |
84 | } | |
85 | ||
86 | /* | |
87 | * Mark a mount point in the filesystem exported | |
88 | */ | |
89 | exportfs() | |
90 | { | |
91 | register struct a { | |
92 | char *fname; | |
93 | int rootuid; | |
94 | int exflags; | |
95 | } *uap = (struct a *)u.u_ap; | |
96 | register struct nameidata *ndp = &u.u_nd; | |
97 | register struct vnode *vp; | |
98 | register struct mount *mp; | |
99 | int error; | |
100 | ||
101 | /* | |
102 | * Must be super user | |
103 | */ | |
104 | if (error = suser(u.u_cred, &u.u_acflag)) | |
105 | RETURN (error); | |
106 | ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW; /* Or NOFOLLOW ?? */ | |
107 | ndp->ni_segflg = UIO_USERSPACE; | |
108 | ndp->ni_dirp = uap->fname; | |
109 | if (error = namei(ndp)) | |
110 | RETURN (error); | |
111 | vp = ndp->ni_vp; | |
112 | if (vp->v_type != VDIR) { | |
113 | vput(vp); | |
114 | RETURN (ENOENT); | |
115 | } | |
116 | mp = vp->v_mount; | |
117 | ||
118 | /* | |
119 | * If the filesystem has already been exported, just relax | |
120 | * security as required. | |
121 | * Otherwise export it with the given security | |
122 | */ | |
123 | if (mp->m_flag & M_EXPORTED) { | |
124 | if (uap->rootuid == 0) | |
125 | mp->m_exroot = 0; | |
126 | if ((uap->exflags & M_EXRDONLY) == 0) | |
127 | mp->m_flag &= ~M_EXRDONLY; | |
128 | } else { | |
129 | mp->m_exroot = uap->rootuid; | |
130 | if (uap->exflags & M_EXRDONLY) | |
131 | mp->m_flag |= M_EXRDONLY; | |
132 | mp->m_flag |= M_EXPORTED; | |
133 | } | |
134 | vput(vp); | |
135 | RETURN (0); | |
136 | } | |
137 | ||
138 | /* | |
139 | * Nfs server psuedo system call for the nfsd's | |
140 | * Never returns unless it fails or gets killed | |
141 | */ | |
142 | nfssvc() | |
143 | { | |
144 | register struct a { | |
145 | int s; | |
146 | } *uap = (struct a *)u.u_ap; | |
147 | register struct mbuf *m; | |
148 | register int siz; | |
149 | register struct ucred *cr; | |
150 | struct file *fp; | |
151 | struct mbuf *mreq, *mrep, *nam, *md; | |
152 | struct socket *so; | |
153 | caddr_t dpos; | |
154 | int proc; | |
155 | u_long retxid; | |
156 | int error; | |
157 | ||
158 | /* | |
159 | * Must be super user | |
160 | */ | |
161 | if (error = suser(u.u_cred, &u.u_acflag)) | |
162 | RETURN (error); | |
163 | fp = getsock(uap->s); | |
164 | if (fp == 0) | |
165 | return; | |
166 | so = (struct socket *)fp->f_data; | |
167 | cr = u.u_cred = crcopy(u.u_cred); /* Copy it so others don't see changes */ | |
168 | /* | |
169 | * Just loop arround doin our stuff until SIGKILL | |
170 | */ | |
171 | for (;;) { | |
172 | if (error = nfs_getreq(so, nfs_prog, nfs_vers, NFS_NPROCS-1, | |
173 | &nam, &mrep, &md, &dpos, &retxid, &proc, cr)) { | |
174 | m_freem(nam); | |
175 | continue; | |
176 | } | |
177 | if (error = (*(nfsrv_procs[proc]))(mrep, md, dpos, | |
178 | cr, retxid, &mreq)) { | |
179 | m_freem(nam); | |
180 | nfsstats.srv_errs++; | |
181 | continue; | |
182 | } else | |
183 | nfsstats.srvrpccnt[proc]++; | |
184 | m = mreq; | |
185 | siz = 0; | |
186 | while (m) { | |
187 | siz += m->m_len; | |
188 | m = m->m_next; | |
189 | } | |
190 | if (siz <= 0 || siz > 9216) { | |
191 | printf("mbuf siz=%d\n",siz); | |
192 | panic("Bad nfs svc reply"); | |
193 | } | |
194 | error = nfs_udpsend(so, nam, mreq, 0, siz); | |
195 | m_freem(nam); | |
196 | } | |
197 | } |