Beispiel #1
0
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));
}
Beispiel #2
0
//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;
}
Beispiel #3
0
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));
  }
}
Beispiel #4
0
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");
}