void afsusrroot::nfs_lookup (svccb *sbp, str name) { afsnode *e = lookup (name, aid); if (e) { if (int err = srvinfo::geterr (name)) nfs_error (sbp, err); else lookup_reply (sbp, e); return; } else if ((!sfs_parsepath (name) && (!namedprotrx.match (name) /*|| !nptab[namedprotrx[1]]*/)) || terminating) { nfs_error (sbp, ENOENT); return; } ref<delaypt> dpt = delaypt::alloc (); ref<setupstate> ss = New refcounted<setupstate> (name, dpt); link (dpt, name); if (ptr<aclnt> ch = agentc ()) ch->timedcall (agent_timeout, AGENTCB_REVOKED, &name, &ss->revres, wrap (mkref (this), &afsusrroot::revcb, ss)); else { ss->revdone = true; finish (ss, NFS_OK); } lookup_reply (sbp, afsdir::lookup (name, aid)); }
//for looking up self-certifying hostnames in certprog interface int path2sch (str path, str *sch) { *sch = NULL; if (!path || !path.len ()) return ENOENT; if (sfs_parsepath (path)) { *sch = path; return 0; } str lookup; if (path[0] == '/') lookup = path; else lookup = strbuf () << sfsroot << "/" << path; str result = pathiterate (lookup, sch, 0, true); // warn << "RESULT: " << result << "\n"; if (errno == EINVAL) errno = 0; // if (*sch) // warn << "RETURNING: " << *sch << "\n"; // warn << "RETURNING ERROR CODE: " << strerror (errno) << "\n"; return errno; }
void afsusrdir::nfs_remove (svccb *sbp) { if (!chkaid (sbp)) return; str name = sbp->vers () == 2 ? str (sbp->Xtmpl getarg<diropargs> ()->name) : str (sbp->Xtmpl getarg<diropargs3> ()->name); if (!entries[name]) nfs_error (sbp, NFSERR_NOENT); else if (!nameok (name) && !sfs_parsepath (name)) nfs_error (sbp, NFSERR_ACCES); else { clrulink (name); if (sbp->vers () == 2) sbp->replyref (NFS_OK); else sbp->replyref (wccstat3 (NFS3_OK)); } }
static str slashsfs2sch (str path) { size_t lsfsroot = strlen (sfsroot); if (strncmp (sfsroot, path.cstr (), lsfsroot)) return NULL; const char *nosfs = path.cstr () + lsfsroot; // skip over slashes after sfsroot while (nosfs[0] && nosfs[0] == '/') nosfs++; str s; char *firstslash = strchr (nosfs, '/'); if (firstslash) s = strbuf (nosfs, firstslash - nosfs); else s = strbuf ("%s", nosfs); if (sfs_parsepath (s)) return s; else return NULL; }
static void sclone (ref<asrv> s, ref<axprt_clone> x, sockaddr_in sin, svccb *sbp) { s->setcb (NULL); if (!sbp) { warn ("invalid connect from %s\n", inet_ntoa (sin.sin_addr)); return; } if (sbp->proc () != SFSPROC_CONNECT) { sbp->reject (PROC_UNAVAIL); return; } sfs_connectarg *arg = sbp->Xtmpl getarg<sfs_connectarg> (); u_int32_t rel; sfs_service service; str name; sfs_hash hostid; rpc_vec<sfs_extension, RPC_INFINITY> *extensions; switch (arg->civers) { case 4: rel = 4; service = arg->ci4->service; name = arg->ci4->name; hostid = arg->ci4->hostid; extensions = &arg->ci4->extensions; break; case 5: rel = arg->ci5->release; service = arg->ci5->service; if (!sfs_parsepath (arg->ci5->sname, &name, &hostid)) name = arg->ci5->sname; extensions = &arg->ci5->extensions; break; default: sbp->reject (GARBAGE_ARGS); return; } bhash<str> eh; for (const sfs_extension *ep = extensions->base (); ep < extensions->lim (); ep++) eh.insert (*ep); sfs_pathrevoke cert; str rawcert = file2str (revocationdir << "/" << armor32 (hostid.base (), hostid.size ())); if (rawcert && str2xdr (cert, rawcert)) { sfs_connectres res(SFS_REDIRECT); res.revoke->msg = cert.msg; res.revoke->sig = cert.sig; sbp->reply (&res); return; } const char *source = inet_ntoa (sin.sin_addr); server *srv; for (srv = serverlist.first; srv; srv = serverlist.next (srv)) if (srv->host == name && srv->hostid && *srv->hostid == hostid) if (srv->clone (x, sbp, source, rel, service, eh)) return; else break; for (srv = serverlist.first; srv; srv = serverlist.next (srv)) if (srv->host == name && !srv->hostid) if (srv->clone (x, sbp, source, rel, service, eh)) return; else break; for (srv = serverlist.first; srv; srv = serverlist.next (srv)) if (srv->host == name) if (srv->clone (x, sbp, source, rel, service, eh)) return; for (srv = serverlist.first; srv; srv = serverlist.next (srv)) if (srv->clone (x, sbp, source, rel, service, eh)) return; sbp->replyref (sfs_connectres (SFS_NOSUCHHOST)); }
static void parseconfig () { str cf = configfile; parseargs pa (cf); bool errors = false; str hostname; rpc_ptr<sfs_hash> hostid; server *s = NULL; release *r = NULL; extension *e = NULL; char *c; int line; vec<str> av; while (pa.getline (&av, &line)) { if (!strcasecmp (av[0], "BindAddr")) { in_addr addr; u_int16_t port = 0; if (av.size () < 2 || av.size () > 3 || !inet_aton (av[1], &addr) || (av.size () == 3 && !convertint (av[2], &port))) { warn << cf << ":" << line << ": usage: BindAddr addr [port]\n"; errors = true; continue; } if (!port) port = sfs_defport ? sfs_defport : SFS_PORT; sockaddr_in *sinp = static_cast<sockaddr_in *> (xmalloc (sizeof (*sinp))); bzero (sinp, sizeof (*sinp)); sinp->sin_family = AF_INET; sinp->sin_port = htons (port); sinp->sin_addr = addr; #ifdef HAVE_SA_LEN sinp->sin_len = sizeof (*sinp); #endif /* HAVE_SA_LEN */ listenaddrs.push_back (reinterpret_cast<sockaddr *> (sinp)); } else if (!strcasecmp (av[0], "Server")) { if (av.size () != 2) { warn << cf << ":" << line << ": usage: Server {hostname|*}[:hostid]\n"; errors = true; continue; } if (strchr (av[1], ':') || ((c = strchr (av[1], '@')) && strchr (c, ','))) { hostid.alloc (); if (!sfs_parsepath (av[1], &hostname, hostid)) { warn << cf << ":" << line << ": bad hostname/hostid\n"; errors = true; continue; } } else { hostid.clear (); if (av[1] == "*") hostname = sfshostname (); else hostname = av[1]; } for (s = serverlist.first; s; s = serverlist.next (s)) if (hostname == s->host && ((hostid && s->hostid && *hostid == *s->hostid) || (!hostid && !s->hostid))) break; if (!s) s = New server (hostname, hostid); r = NULL; e = NULL; } else if (!strcasecmp (av[0], "Release")) { static rxx relrx ("^(\\d+)\\.(\\d\\d?)$"); if (av.size () != 2 || (!relrx.search (av[1]) && av[1] != "*")) { warn << cf << ":" << line << ": usage Release { N.NN | * }\n"; errors = true; r = NULL; continue; } if (!s) { warn << cf << ":" << line << ": Release must follow Server\n"; errors = true; r = NULL; continue; } u_int32_t rel; if (av[1] == "*") rel = 0xffffffff; else rel = strtoi64 (relrx[1]) * 100 + strtoi64 (relrx[2]); r = s->reltab[rel]; if (!r) s->reltab.insert ((r = New release (rel))); for (e = r->extlist.first; r->extlist.next (e); e = r->extlist.next (e)) ; } else if (!strcasecmp (av[0], "Extensions")) { av.pop_front (); e = r->getext (av); } else if (!strcasecmp (av[0], "Service")) { if (!parse_service (av, e, cf << ":" << line)) errors = true; } else if (!strcasecmp (av[0], "HashCost")) { if (av.size () != 2 || !convertint (av[1], &sfs_hashcost)) { warn << cf << ":" << line << ": usage: HashCost <nbits>\n"; errors = true; } else { if (sfs_hashcost > sfs_maxhashcost) sfs_hashcost = sfs_maxhashcost; str s (strbuf ("SFS_HASHCOST=%d", sfs_hashcost)); xputenv (const_cast<char*>(s.cstr())); } } else if (!strcasecmp (av[0], "RevocationDir")) { if (av.size () != 2) { warn << cf << ":" << line << ": usage: RevocationDir <directory>\n"; errors = true; } else { revocationdir = av[1]; } } else { errors = true; warn << cf << ":" << line << ": unknown directive '" << av[0] << "'\n"; } } if (errors) fatal ("parse errors in configuration file\n"); }