add some Kerberos detail
[unix-history] / usr / src / sys / nfs / nfs_syscalls.c
CommitLineData
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. */
41extern u_long nfs_prog, nfs_vers;
42extern int (*nfsrv_procs[NFS_NPROCS])();
43struct 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 */
54getfh()
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 */
89exportfs()
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 */
142nfssvc()
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}