19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier
39a747e4fSDavid du Colombier /*
49a747e4fSDavid du Colombier * Cf. /lib/rfc/rfc1094
59a747e4fSDavid du Colombier */
69a747e4fSDavid du Colombier
79a747e4fSDavid du Colombier static int mntnull(int, Rpccall*, Rpccall*);
89a747e4fSDavid du Colombier static int mntmnt(int, Rpccall*, Rpccall*);
99a747e4fSDavid du Colombier static int mntdump(int, Rpccall*, Rpccall*);
109a747e4fSDavid du Colombier static int mntumnt(int, Rpccall*, Rpccall*);
119a747e4fSDavid du Colombier static int mntumntall(int, Rpccall*, Rpccall*);
129a747e4fSDavid du Colombier static int mntexport(int, Rpccall*, Rpccall*);
139a747e4fSDavid du Colombier
149a747e4fSDavid du Colombier Procmap mntproc[] = {
159a747e4fSDavid du Colombier 0, mntnull,
169a747e4fSDavid du Colombier 1, mntmnt,
179a747e4fSDavid du Colombier 2, mntdump,
189a747e4fSDavid du Colombier 3, mntumnt,
199a747e4fSDavid du Colombier 4, mntumntall,
209a747e4fSDavid du Colombier 5, mntexport,
219a747e4fSDavid du Colombier 0, 0
229a747e4fSDavid du Colombier };
239a747e4fSDavid du Colombier
249a747e4fSDavid du Colombier long starttime;
259a747e4fSDavid du Colombier static int noauth;
269a747e4fSDavid du Colombier char * config;
279a747e4fSDavid du Colombier Session * head;
289a747e4fSDavid du Colombier Session * tail;
299a747e4fSDavid du Colombier int staletime = 10*60;
309a747e4fSDavid du Colombier
319a747e4fSDavid du Colombier void
mnttimer(long now)329a747e4fSDavid du Colombier mnttimer(long now)
339a747e4fSDavid du Colombier {
349a747e4fSDavid du Colombier Session *s;
359a747e4fSDavid du Colombier
369a747e4fSDavid du Colombier for(s=head; s; s=s->next)
379a747e4fSDavid du Colombier fidtimer(s, now);
389a747e4fSDavid du Colombier }
399a747e4fSDavid du Colombier
408c41de82SDavid du Colombier static void
usage(void)418c41de82SDavid du Colombier usage(void)
428c41de82SDavid du Colombier {
438c41de82SDavid du Colombier sysfatal("usage: %s %s [-ns] [-a dialstring] [-c uidmap] [-f srvfile] "
448c41de82SDavid du Colombier "[-T staletime]", argv0, commonopts);
458c41de82SDavid du Colombier }
468c41de82SDavid du Colombier
479a747e4fSDavid du Colombier void
mntinit(int argc,char ** argv)489a747e4fSDavid du Colombier mntinit(int argc, char **argv)
499a747e4fSDavid du Colombier {
509a747e4fSDavid du Colombier int tries;
519a747e4fSDavid du Colombier
529a747e4fSDavid du Colombier config = "config";
539a747e4fSDavid du Colombier starttime = time(0);
549a747e4fSDavid du Colombier clog("nfs mount server init, starttime = %lud\n", starttime);
559a747e4fSDavid du Colombier tries = 0;
569a747e4fSDavid du Colombier ARGBEGIN{
579a747e4fSDavid du Colombier case 'a':
589a747e4fSDavid du Colombier ++tries;
598c41de82SDavid du Colombier srvinit(-1, 0, EARGF(usage()));
608c41de82SDavid du Colombier break;
618c41de82SDavid du Colombier case 'c':
628c41de82SDavid du Colombier config = EARGF(usage());
639a747e4fSDavid du Colombier break;
649a747e4fSDavid du Colombier case 'f':
659a747e4fSDavid du Colombier ++tries;
668c41de82SDavid du Colombier srvinit(-1, EARGF(usage()), 0);
678c41de82SDavid du Colombier break;
688c41de82SDavid du Colombier case 'n':
698c41de82SDavid du Colombier ++noauth;
709a747e4fSDavid du Colombier break;
719a747e4fSDavid du Colombier case 's':
729a747e4fSDavid du Colombier ++tries;
739a747e4fSDavid du Colombier srvinit(1, 0, 0);
749a747e4fSDavid du Colombier break;
759a747e4fSDavid du Colombier case 'T':
768c41de82SDavid du Colombier staletime = atoi(EARGF(usage()));
779a747e4fSDavid du Colombier break;
78363b328dSDavid du Colombier default:
79363b328dSDavid du Colombier if(argopt(ARGC()) < 0)
808c41de82SDavid du Colombier sysfatal("usage: %s %s [-ns] [-a dialstring] "
818c41de82SDavid du Colombier "[-c uidmap] [-f srvfile] [-T staletime]",
82363b328dSDavid du Colombier argv0, commonopts);
83363b328dSDavid du Colombier break;
849a747e4fSDavid du Colombier }ARGEND
859a747e4fSDavid du Colombier noauth=1; /* ZZZ */
869a747e4fSDavid du Colombier if(tries == 0 && head == 0)
878c41de82SDavid du Colombier srvinit(-1, 0, "tcp!fs");
889a747e4fSDavid du Colombier if(head == 0)
899a747e4fSDavid du Colombier panic("can't initialize services");
909a747e4fSDavid du Colombier readunixidmaps(config);
919a747e4fSDavid du Colombier }
929a747e4fSDavid du Colombier
939a747e4fSDavid du Colombier void
srvinit(int fd,char * file,char * addr)949a747e4fSDavid du Colombier srvinit(int fd, char *file, char *addr)
959a747e4fSDavid du Colombier {
969a747e4fSDavid du Colombier char fdservice[16], *naddr;
979a747e4fSDavid du Colombier Session *s;
989a747e4fSDavid du Colombier Xfile *xp;
999a747e4fSDavid du Colombier Xfid *xf;
1009a747e4fSDavid du Colombier Fid *f;
1019a747e4fSDavid du Colombier
1029a747e4fSDavid du Colombier s = calloc(1, sizeof(Session));
1039a747e4fSDavid du Colombier s->spec = "";
1049a747e4fSDavid du Colombier s->fd = -1;
1059a747e4fSDavid du Colombier if(fd >= 0){
1069a747e4fSDavid du Colombier s->fd = fd;
1079a747e4fSDavid du Colombier sprint(fdservice, "/fd/%d", s->fd);
1089a747e4fSDavid du Colombier s->service = strstore(fdservice);
1099a747e4fSDavid du Colombier chat("fd = %d\n", s->fd);
1109a747e4fSDavid du Colombier }else if(file){
1119a747e4fSDavid du Colombier chat("file = \"%s\"\n", file);
1129a747e4fSDavid du Colombier s->service = file;
1139a747e4fSDavid du Colombier s->fd = open(file, ORDWR);
1149a747e4fSDavid du Colombier if(s->fd < 0){
1159a747e4fSDavid du Colombier clog("can't open %s: %r\n", file);
1169a747e4fSDavid du Colombier goto error;
1179a747e4fSDavid du Colombier }
1189a747e4fSDavid du Colombier }else if(addr){
1199a747e4fSDavid du Colombier chat("addr = \"%s\"\n", addr);
1209a747e4fSDavid du Colombier naddr = netmkaddr(addr, 0, "9fs");
1219a747e4fSDavid du Colombier s->service = addr;
1229a747e4fSDavid du Colombier s->fd = dial(naddr, 0, 0, 0);
1239a747e4fSDavid du Colombier if(s->fd < 0){
1249a747e4fSDavid du Colombier clog("can't dial %s: %r\n", naddr);
1259a747e4fSDavid du Colombier goto error;
1269a747e4fSDavid du Colombier }
1279a747e4fSDavid du Colombier }
1289a747e4fSDavid du Colombier
1299a747e4fSDavid du Colombier chat("version...");
1309a747e4fSDavid du Colombier s->tag = NOTAG-1;
1319a747e4fSDavid du Colombier s->f.msize = Maxfdata+IOHDRSZ;
1329a747e4fSDavid du Colombier s->f.version = "9P2000";
1339a747e4fSDavid du Colombier xmesg(s, Tversion);
1349a747e4fSDavid du Colombier messagesize = IOHDRSZ+s->f.msize;
1359a747e4fSDavid du Colombier chat("version spec %s size %d\n", s->f.version, s->f.msize);
1369a747e4fSDavid du Colombier
137b985bfb9SDavid du Colombier s->tag = 0;
138b985bfb9SDavid du Colombier
139b985bfb9SDavid du Colombier chat("authenticate...");
140b985bfb9SDavid du Colombier if(authhostowner(s) < 0){
141b985bfb9SDavid du Colombier clog("auth failed %r\n");
1429a747e4fSDavid du Colombier goto error;
1439a747e4fSDavid du Colombier }
1449a747e4fSDavid du Colombier
145b985bfb9SDavid du Colombier chat("attach as none...");
1469a747e4fSDavid du Colombier f = newfid(s);
1479a747e4fSDavid du Colombier s->f.fid = f - s->fids;
1489a747e4fSDavid du Colombier s->f.afid = ~0x0UL;
1499a747e4fSDavid du Colombier s->f.uname = "none";
1509a747e4fSDavid du Colombier s->f.aname = s->spec;
1519a747e4fSDavid du Colombier if(xmesg(s, Tattach)){
1529a747e4fSDavid du Colombier clog("attach failed\n");
1539a747e4fSDavid du Colombier goto error;
1549a747e4fSDavid du Colombier }
1559a747e4fSDavid du Colombier
1569a747e4fSDavid du Colombier xp = xfile(&s->f.qid, s, 1);
1579a747e4fSDavid du Colombier s->root = xp;
1589a747e4fSDavid du Colombier xp->parent = xp;
1599a747e4fSDavid du Colombier xp->name = "/";
1609a747e4fSDavid du Colombier xf = xfid("none", xp, 1);
1619a747e4fSDavid du Colombier xf->urfid = f;
1629a747e4fSDavid du Colombier clog("service=%s uid=%s fid=%ld\n",
1639a747e4fSDavid du Colombier s->service, xf->uid, xf->urfid - s->fids);
1649a747e4fSDavid du Colombier if(tail)
1659a747e4fSDavid du Colombier tail->next = s;
1669a747e4fSDavid du Colombier else
1679a747e4fSDavid du Colombier head = s;
1689a747e4fSDavid du Colombier tail = s;
1699a747e4fSDavid du Colombier return;
1709a747e4fSDavid du Colombier
1719a747e4fSDavid du Colombier error:
1729a747e4fSDavid du Colombier if(s->fd >= 0)
1739a747e4fSDavid du Colombier close(s->fd);
1749a747e4fSDavid du Colombier free(s);
1759a747e4fSDavid du Colombier }
1769a747e4fSDavid du Colombier
1779a747e4fSDavid du Colombier static int
mntnull(int n,Rpccall * cmd,Rpccall * reply)1789a747e4fSDavid du Colombier mntnull(int n, Rpccall *cmd, Rpccall *reply)
1799a747e4fSDavid du Colombier {
1809a747e4fSDavid du Colombier USED(n, cmd, reply);
1819a747e4fSDavid du Colombier chat("mntnull\n");
1829a747e4fSDavid du Colombier return 0;
1839a747e4fSDavid du Colombier }
1849a747e4fSDavid du Colombier
1859a747e4fSDavid du Colombier static char*
Str2str(String s,char * buf,int nbuf)1869a747e4fSDavid du Colombier Str2str(String s, char *buf, int nbuf)
1879a747e4fSDavid du Colombier {
1889a747e4fSDavid du Colombier int i;
1899a747e4fSDavid du Colombier i = s.n;
1909a747e4fSDavid du Colombier if(i >= nbuf)
1919a747e4fSDavid du Colombier i = nbuf-1;
1929a747e4fSDavid du Colombier memmove(buf, s.s, i);
1939a747e4fSDavid du Colombier buf[i] = 0;
1949a747e4fSDavid du Colombier return buf;
1959a747e4fSDavid du Colombier }
1969a747e4fSDavid du Colombier
1979a747e4fSDavid du Colombier static int
mntmnt(int n,Rpccall * cmd,Rpccall * reply)1989a747e4fSDavid du Colombier mntmnt(int n, Rpccall *cmd, Rpccall *reply)
1999a747e4fSDavid du Colombier {
2009a747e4fSDavid du Colombier int i;
2019a747e4fSDavid du Colombier char dom[64];
2029a747e4fSDavid du Colombier uchar *argptr = cmd->args;
2039a747e4fSDavid du Colombier uchar *dataptr = reply->results;
2049a747e4fSDavid du Colombier Authunix au;
2059a747e4fSDavid du Colombier Xfile *xp;
2069a747e4fSDavid du Colombier String root;
2079a747e4fSDavid du Colombier
2089a747e4fSDavid du Colombier chat("mntmnt...\n");
2099a747e4fSDavid du Colombier if(n < 8)
2109a747e4fSDavid du Colombier return garbage(reply, "n too small");
2119a747e4fSDavid du Colombier argptr += string2S(argptr, &root);
2129a747e4fSDavid du Colombier if(argptr != &((uchar *)cmd->args)[n])
2139a747e4fSDavid du Colombier return garbage(reply, "bad count");
2149a747e4fSDavid du Colombier clog("host=%I, port=%ld, root=\"%.*s\"...",
2159a747e4fSDavid du Colombier cmd->host, cmd->port, utfnlen(root.s, root.n), root.s);
2169a747e4fSDavid du Colombier if(auth2unix(&cmd->cred, &au) != 0){
2179a747e4fSDavid du Colombier chat("auth flavor=%ld, count=%ld\n",
2189a747e4fSDavid du Colombier cmd->cred.flavor, cmd->cred.count);
2199a747e4fSDavid du Colombier for(i=0; i<cmd->cred.count; i++)
2209a747e4fSDavid du Colombier chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
2219a747e4fSDavid du Colombier chat("\n");
2229a747e4fSDavid du Colombier clog("auth: bad credentials");
2239a747e4fSDavid du Colombier return error(reply, 1);
2249a747e4fSDavid du Colombier }
2259a747e4fSDavid du Colombier clog("auth: %ld %.*s u=%ld g=%ld",
2269a747e4fSDavid du Colombier au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
2279a747e4fSDavid du Colombier for(i=0; i<au.gidlen; i++)
2289a747e4fSDavid du Colombier chat(", %ld", au.gids[i]);
2299a747e4fSDavid du Colombier chat("...");
2309a747e4fSDavid du Colombier if(getdom(cmd->host, dom, sizeof(dom))<0){
2319a747e4fSDavid du Colombier clog("auth: unknown ip address");
2329a747e4fSDavid du Colombier return error(reply, 1);
2339a747e4fSDavid du Colombier }
2349a747e4fSDavid du Colombier chat("dom=%s...", dom);
2359a747e4fSDavid du Colombier xp = xfroot(root.s, root.n);
2369a747e4fSDavid du Colombier if(xp == 0){
2379a747e4fSDavid du Colombier chat("xp=0...");
2389a747e4fSDavid du Colombier clog("mntmnt: no fs");
2399a747e4fSDavid du Colombier return error(reply, 3);
2409a747e4fSDavid du Colombier }
2419a747e4fSDavid du Colombier
2429a747e4fSDavid du Colombier PLONG(0);
2439a747e4fSDavid du Colombier dataptr += xp2fhandle(xp, dataptr);
2449a747e4fSDavid du Colombier chat("OK\n");
2459a747e4fSDavid du Colombier return dataptr - (uchar *)reply->results;
2469a747e4fSDavid du Colombier }
2479a747e4fSDavid du Colombier
2489a747e4fSDavid du Colombier static int
mntdump(int n,Rpccall * cmd,Rpccall * reply)2499a747e4fSDavid du Colombier mntdump(int n, Rpccall *cmd, Rpccall *reply)
2509a747e4fSDavid du Colombier {
2519a747e4fSDavid du Colombier if(n != 0)
2529a747e4fSDavid du Colombier return garbage(reply, "mntdump");
2539a747e4fSDavid du Colombier USED(cmd);
2549a747e4fSDavid du Colombier chat("mntdump...");
2559a747e4fSDavid du Colombier return error(reply, FALSE);
2569a747e4fSDavid du Colombier }
2579a747e4fSDavid du Colombier
2589a747e4fSDavid du Colombier static int
mntumnt(int n,Rpccall * cmd,Rpccall * reply)2599a747e4fSDavid du Colombier mntumnt(int n, Rpccall *cmd, Rpccall *reply)
2609a747e4fSDavid du Colombier {
2619a747e4fSDavid du Colombier if(n <= 0)
2629a747e4fSDavid du Colombier return garbage(reply, "mntumnt");
2639a747e4fSDavid du Colombier USED(cmd);
2649a747e4fSDavid du Colombier chat("mntumnt\n");
2659a747e4fSDavid du Colombier return 0;
2669a747e4fSDavid du Colombier }
2679a747e4fSDavid du Colombier
2689a747e4fSDavid du Colombier static int
mntumntall(int n,Rpccall * cmd,Rpccall * reply)2699a747e4fSDavid du Colombier mntumntall(int n, Rpccall *cmd, Rpccall *reply)
2709a747e4fSDavid du Colombier {
2719a747e4fSDavid du Colombier if(n != 0)
2729a747e4fSDavid du Colombier return garbage(reply, "mntumntall");
2739a747e4fSDavid du Colombier USED(cmd);
2749a747e4fSDavid du Colombier chat("mntumntall\n");
2759a747e4fSDavid du Colombier return 0;
2769a747e4fSDavid du Colombier }
2779a747e4fSDavid du Colombier
2789a747e4fSDavid du Colombier static int
mntexport(int n,Rpccall * cmd,Rpccall * reply)2799a747e4fSDavid du Colombier mntexport(int n, Rpccall *cmd, Rpccall *reply)
2809a747e4fSDavid du Colombier {
2819a747e4fSDavid du Colombier uchar *dataptr = reply->results;
2829a747e4fSDavid du Colombier Authunix au;
2839a747e4fSDavid du Colombier int i;
2849a747e4fSDavid du Colombier
2859a747e4fSDavid du Colombier chat("mntexport...");
2869a747e4fSDavid du Colombier if(n != 0)
2879a747e4fSDavid du Colombier return garbage(reply, "mntexport");
2889a747e4fSDavid du Colombier if(auth2unix(&cmd->cred, &au) != 0){
2899a747e4fSDavid du Colombier chat("auth flavor=%ld, count=%ld\n",
2909a747e4fSDavid du Colombier cmd->cred.flavor, cmd->cred.count);
2919a747e4fSDavid du Colombier for(i=0; i<cmd->cred.count; i++)
2929a747e4fSDavid du Colombier chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
2939a747e4fSDavid du Colombier chat("...");
2949a747e4fSDavid du Colombier au.mach.n = 0;
2959a747e4fSDavid du Colombier }else
2969a747e4fSDavid du Colombier chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, au.mach.n), au.mach.s);
2979a747e4fSDavid du Colombier PLONG(TRUE);
2989a747e4fSDavid du Colombier PLONG(1);
2999a747e4fSDavid du Colombier PPTR("/", 1);
3009a747e4fSDavid du Colombier if(au.mach.n > 0){
3019a747e4fSDavid du Colombier PLONG(TRUE);
3029a747e4fSDavid du Colombier PLONG(au.mach.n);
3039a747e4fSDavid du Colombier PPTR(au.mach.s, au.mach.n);
3049a747e4fSDavid du Colombier }
3059a747e4fSDavid du Colombier PLONG(FALSE);
3069a747e4fSDavid du Colombier PLONG(FALSE);
3079a747e4fSDavid du Colombier chat("OK\n");
3089a747e4fSDavid du Colombier return dataptr - (uchar *)reply->results;
3099a747e4fSDavid du Colombier }
3109a747e4fSDavid du Colombier
3119a747e4fSDavid du Colombier Xfile *
xfroot(char * name,int n)3129a747e4fSDavid du Colombier xfroot(char *name, int n)
3139a747e4fSDavid du Colombier {
3149a747e4fSDavid du Colombier Session *s;
3159a747e4fSDavid du Colombier char *p;
3169a747e4fSDavid du Colombier
3179a747e4fSDavid du Colombier if(n <= 0)
3189a747e4fSDavid du Colombier n = strlen(name);
3199a747e4fSDavid du Colombier chat("xfroot: %.*s...", utfnlen(name, n), name);
3209a747e4fSDavid du Colombier if(n == 1 && name[0] == '/')
3219a747e4fSDavid du Colombier return head->root;
3229a747e4fSDavid du Colombier for(s=head; s; s=s->next){
3239a747e4fSDavid du Colombier if(strncmp(name, s->service, n) == 0)
3249a747e4fSDavid du Colombier return s->root;
3258c41de82SDavid du Colombier p = strrchr(s->service, '!'); /* for -a tcp!foo */
326d9306527SDavid du Colombier if(p && strncmp(name, p+1, n) == 0)
327d9306527SDavid du Colombier return s->root;
328*883a8c51SDavid du Colombier p = strrchr(s->service, '/'); /* for -f /srv/foo */
3299a747e4fSDavid du Colombier if(p && strncmp(name, p+1, n) == 0)
3309a747e4fSDavid du Colombier return s->root;
3319a747e4fSDavid du Colombier }
3329a747e4fSDavid du Colombier return 0;
3339a747e4fSDavid du Colombier }
334