xref: /plan9/sys/src/cmd/9nfs/nfsmount.c (revision 883a8c51bed350ea85a0220461d31e311550db04)
1 #include "all.h"
2 
3 /*
4  *	Cf. /lib/rfc/rfc1094
5  */
6 
7 static int	mntnull(int, Rpccall*, Rpccall*);
8 static int	mntmnt(int, Rpccall*, Rpccall*);
9 static int	mntdump(int, Rpccall*, Rpccall*);
10 static int	mntumnt(int, Rpccall*, Rpccall*);
11 static int	mntumntall(int, Rpccall*, Rpccall*);
12 static int	mntexport(int, Rpccall*, Rpccall*);
13 
14 Procmap mntproc[] = {
15 	0, mntnull,
16 	1, mntmnt,
17 	2, mntdump,
18 	3, mntumnt,
19 	4, mntumntall,
20 	5, mntexport,
21 	0, 0
22 };
23 
24 long		starttime;
25 static int	noauth;
26 char *		config;
27 Session *	head;
28 Session *	tail;
29 int staletime = 10*60;
30 
31 void
mnttimer(long now)32 mnttimer(long now)
33 {
34 	Session *s;
35 
36 	for(s=head; s; s=s->next)
37 		fidtimer(s, now);
38 }
39 
40 static void
usage(void)41 usage(void)
42 {
43 	sysfatal("usage: %s %s [-ns] [-a dialstring] [-c uidmap] [-f srvfile] "
44 		"[-T staletime]", argv0, commonopts);
45 }
46 
47 void
mntinit(int argc,char ** argv)48 mntinit(int argc, char **argv)
49 {
50 	int tries;
51 
52 	config = "config";
53 	starttime = time(0);
54 	clog("nfs mount server init, starttime = %lud\n", starttime);
55 	tries = 0;
56 	ARGBEGIN{
57 	case 'a':
58 		++tries;
59 		srvinit(-1, 0, EARGF(usage()));
60 		break;
61 	case 'c':
62 		config = EARGF(usage());
63 		break;
64 	case 'f':
65 		++tries;
66 		srvinit(-1, EARGF(usage()), 0);
67 		break;
68 	case 'n':
69 		++noauth;
70 		break;
71 	case 's':
72 		++tries;
73 		srvinit(1, 0, 0);
74 		break;
75 	case 'T':
76 		staletime = atoi(EARGF(usage()));
77 		break;
78 	default:
79 		if(argopt(ARGC()) < 0)
80 			sysfatal("usage: %s %s [-ns] [-a dialstring] "
81 				"[-c uidmap] [-f srvfile] [-T staletime]",
82 				argv0, commonopts);
83 		break;
84 	}ARGEND
85 noauth=1;	/* ZZZ */
86 	if(tries == 0 && head == 0)
87 		srvinit(-1, 0, "tcp!fs");
88 	if(head == 0)
89 		panic("can't initialize services");
90 	readunixidmaps(config);
91 }
92 
93 void
srvinit(int fd,char * file,char * addr)94 srvinit(int fd, char *file, char *addr)
95 {
96 	char fdservice[16], *naddr;
97 	Session *s;
98 	Xfile *xp;
99 	Xfid *xf;
100 	Fid *f;
101 
102 	s = calloc(1, sizeof(Session));
103 	s->spec = "";
104 	s->fd = -1;
105 	if(fd >= 0){
106 		s->fd = fd;
107 		sprint(fdservice, "/fd/%d", s->fd);
108 		s->service = strstore(fdservice);
109 		chat("fd = %d\n", s->fd);
110 	}else if(file){
111 		chat("file = \"%s\"\n", file);
112 		s->service = file;
113 		s->fd = open(file, ORDWR);
114 		if(s->fd < 0){
115 			clog("can't open %s: %r\n", file);
116 			goto error;
117 		}
118 	}else if(addr){
119 		chat("addr = \"%s\"\n", addr);
120 		naddr = netmkaddr(addr, 0, "9fs");
121 		s->service = addr;
122 		s->fd = dial(naddr, 0, 0, 0);
123 		if(s->fd < 0){
124 			clog("can't dial %s: %r\n", naddr);
125 			goto error;
126 		}
127 	}
128 
129 	chat("version...");
130 	s->tag = NOTAG-1;
131 	s->f.msize = Maxfdata+IOHDRSZ;
132 	s->f.version = "9P2000";
133 	xmesg(s, Tversion);
134 	messagesize = IOHDRSZ+s->f.msize;
135 	chat("version spec %s size %d\n", s->f.version, s->f.msize);
136 
137 	s->tag = 0;
138 
139 	chat("authenticate...");
140 	if(authhostowner(s) < 0){
141 		clog("auth failed %r\n");
142 		goto error;
143 	}
144 
145 	chat("attach as none...");
146 	f = newfid(s);
147 	s->f.fid = f - s->fids;
148 	s->f.afid = ~0x0UL;
149 	s->f.uname = "none";
150 	s->f.aname = s->spec;
151 	if(xmesg(s, Tattach)){
152 		clog("attach failed\n");
153 		goto error;
154 	}
155 
156 	xp = xfile(&s->f.qid, s, 1);
157 	s->root = xp;
158 	xp->parent = xp;
159 	xp->name = "/";
160 	xf = xfid("none", xp, 1);
161 	xf->urfid = f;
162 	clog("service=%s uid=%s fid=%ld\n",
163 		s->service, xf->uid, xf->urfid - s->fids);
164 	if(tail)
165 		tail->next = s;
166 	else
167 		head = s;
168 	tail = s;
169 	return;
170 
171 error:
172 	if(s->fd >= 0)
173 		close(s->fd);
174 	free(s);
175 }
176 
177 static int
mntnull(int n,Rpccall * cmd,Rpccall * reply)178 mntnull(int n, Rpccall *cmd, Rpccall *reply)
179 {
180 	USED(n, cmd, reply);
181 	chat("mntnull\n");
182 	return 0;
183 }
184 
185 static char*
Str2str(String s,char * buf,int nbuf)186 Str2str(String s, char *buf, int nbuf)
187 {
188 	int i;
189 	i = s.n;
190 	if(i >= nbuf)
191 		i = nbuf-1;
192 	memmove(buf, s.s, i);
193 	buf[i] = 0;
194 	return buf;
195 }
196 
197 static int
mntmnt(int n,Rpccall * cmd,Rpccall * reply)198 mntmnt(int n, Rpccall *cmd, Rpccall *reply)
199 {
200 	int i;
201 	char dom[64];
202 	uchar *argptr = cmd->args;
203 	uchar *dataptr = reply->results;
204 	Authunix au;
205 	Xfile *xp;
206 	String root;
207 
208 	chat("mntmnt...\n");
209 	if(n < 8)
210 		return garbage(reply, "n too small");
211 	argptr += string2S(argptr, &root);
212 	if(argptr != &((uchar *)cmd->args)[n])
213 		return garbage(reply, "bad count");
214 	clog("host=%I, port=%ld, root=\"%.*s\"...",
215 		cmd->host, cmd->port, utfnlen(root.s, root.n), root.s);
216 	if(auth2unix(&cmd->cred, &au) != 0){
217 		chat("auth flavor=%ld, count=%ld\n",
218 			cmd->cred.flavor, cmd->cred.count);
219 		for(i=0; i<cmd->cred.count; i++)
220 			chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
221 		chat("\n");
222 		clog("auth: bad credentials");
223 		return error(reply, 1);
224 	}
225 	clog("auth: %ld %.*s u=%ld g=%ld",
226 		au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
227 	for(i=0; i<au.gidlen; i++)
228 		chat(", %ld", au.gids[i]);
229 	chat("...");
230 	if(getdom(cmd->host, dom, sizeof(dom))<0){
231 		clog("auth: unknown ip address");
232 		return error(reply, 1);
233 	}
234 	chat("dom=%s...", dom);
235 	xp = xfroot(root.s, root.n);
236 	if(xp == 0){
237 		chat("xp=0...");
238 		clog("mntmnt: no fs");
239 		return error(reply, 3);
240 	}
241 
242 	PLONG(0);
243 	dataptr += xp2fhandle(xp, dataptr);
244 	chat("OK\n");
245 	return dataptr - (uchar *)reply->results;
246 }
247 
248 static int
mntdump(int n,Rpccall * cmd,Rpccall * reply)249 mntdump(int n, Rpccall *cmd, Rpccall *reply)
250 {
251 	if(n != 0)
252 		return garbage(reply, "mntdump");
253 	USED(cmd);
254 	chat("mntdump...");
255 	return error(reply, FALSE);
256 }
257 
258 static int
mntumnt(int n,Rpccall * cmd,Rpccall * reply)259 mntumnt(int n, Rpccall *cmd, Rpccall *reply)
260 {
261 	if(n <= 0)
262 		return garbage(reply, "mntumnt");
263 	USED(cmd);
264 	chat("mntumnt\n");
265 	return 0;
266 }
267 
268 static int
mntumntall(int n,Rpccall * cmd,Rpccall * reply)269 mntumntall(int n, Rpccall *cmd, Rpccall *reply)
270 {
271 	if(n != 0)
272 		return garbage(reply, "mntumntall");
273 	USED(cmd);
274 	chat("mntumntall\n");
275 	return 0;
276 }
277 
278 static int
mntexport(int n,Rpccall * cmd,Rpccall * reply)279 mntexport(int n, Rpccall *cmd, Rpccall *reply)
280 {
281 	uchar *dataptr = reply->results;
282 	Authunix au;
283 	int i;
284 
285 	chat("mntexport...");
286 	if(n != 0)
287 		return garbage(reply, "mntexport");
288 	if(auth2unix(&cmd->cred, &au) != 0){
289 		chat("auth flavor=%ld, count=%ld\n",
290 			cmd->cred.flavor, cmd->cred.count);
291 		for(i=0; i<cmd->cred.count; i++)
292 			chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
293 		chat("...");
294 		au.mach.n = 0;
295 	}else
296 		chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, au.mach.n), au.mach.s);
297 	PLONG(TRUE);
298 	PLONG(1);
299 	PPTR("/", 1);
300 	if(au.mach.n > 0){
301 		PLONG(TRUE);
302 		PLONG(au.mach.n);
303 		PPTR(au.mach.s, au.mach.n);
304 	}
305 	PLONG(FALSE);
306 	PLONG(FALSE);
307 	chat("OK\n");
308 	return dataptr - (uchar *)reply->results;
309 }
310 
311 Xfile *
xfroot(char * name,int n)312 xfroot(char *name, int n)
313 {
314 	Session *s;
315 	char *p;
316 
317 	if(n <= 0)
318 		n = strlen(name);
319 	chat("xfroot: %.*s...", utfnlen(name, n), name);
320 	if(n == 1 && name[0] == '/')
321 		return head->root;
322 	for(s=head; s; s=s->next){
323 		if(strncmp(name, s->service, n) == 0)
324 			return s->root;
325 		p = strrchr(s->service, '!');	/* for -a tcp!foo */
326 		if(p && strncmp(name, p+1, n) == 0)
327 			return s->root;
328 		p = strrchr(s->service, '/');	/* for -f /srv/foo */
329 		if(p && strncmp(name, p+1, n) == 0)
330 			return s->root;
331 	}
332 	return 0;
333 }
334