Exemplo n.º 1
0
const strbuf &
strbuf_cat (const strbuf &sb, sfsstat err)
{
  switch (err) {
  case SFS_REDIRECT:
    return strbuf_cat (sb, "hostname or public key has changed", false);
  default:
    return strbuf_cat (sb, nfsstat3 (err));
  }
}
Exemplo n.º 2
0
bool
filesrv::fixres (svccb *sbp, void *res, reqstate *rqsp)
{
  filesys *fsp = &fstab[rqsp->fsno];

  if (sbp->proc () == NFSPROC3_READDIR)
    fixrdres (res, fsp, rqsp->rootfh);
  else if (sbp->proc () == NFSPROC3_READDIRPLUS)
    fixrdplusres (res, fsp, rqsp->rootfh);

  bool subst = false;
  fh3trans fht (fh3trans::ENCODE, fhkey, rqsp->fsno,
		wrap (this, &filesrv::fhsubst, &subst, fsp));

  fht.fattr_hook = wrap (xor_ino, this);
  if (!nfs3exp_transres (fht, res, sbp->proc ())) {
    warn ("nfs3reply: nfs3_transres encode failed (err %d)\n", fht.err);
    nfs3exp_err (sbp, nfsstat3 (fht.err));
    return false;
  }

  switch (sbp->proc ()) {
  case NFSPROC3_LOOKUP:
    {
      ex_lookup3res *dor = static_cast<ex_lookup3res *> (res);
      if (rqsp->rootfh) {
	if (dor->status)
	  dor->resfail->set_present (false);
	else
	  dor->resok->dir_attributes.set_present (false);
      }
      if (subst && !dor->status)
	dor->resok->obj_attributes.set_present (false);
      break;
    }
  case NFSPROC3_ACCESS:
    if (!sbp->getaui () && fsp->options != filesys::ANON_READWRITE) {
      ex_access3res *ar = static_cast<ex_access3res *> (res);
      if ((fsp->options & filesys::ANON_READ) != filesys::ANON_READ) {
	if (ar->status)
	  ar->resfail->set_present (false);
	else {
	  ar->resok->access = 0;
	  ar->resok->obj_attributes.set_present (false);
	}
      }
      else if (!ar->status)
	ar->resok->access &= ACCESS3_READ|ACCESS3_LOOKUP|ACCESS3_EXECUTE;
    }
    break;
  }
  return true;
}
Exemplo n.º 3
0
bool
filesrv::fixarg (svccb *sbp, reqstate *rqsp)
{
  fh3trans fht (fh3trans::DECODE, fhkey);
  if (!nfs3_transarg (fht, sbp->Xtmpl getarg<void> (), sbp->proc ())) {
    nfs3exp_err (sbp, nfsstat3 (fht.err));
    return false;
  }
  if (fht.srvno >= fstab.size ()) {
    nfs3exp_err (sbp, NFS3ERR_BADHANDLE);
    return false;
  }
  rqsp->fsno = fht.srvno;
  filesys *fsp = &fstab[rqsp->fsno];
  rqsp->rootfh = false;
  rqsp->c = fsp->c;

#if 1
  /* We let anonymous users GETATTR any root file handle, not just the
   * root of all exported files.  This is to help client
   * implementations that want to avoid (st_ino, st_dev) conflicts by
   * creating multiple mount points for each server.  Is this bad? */
  if (!sbp->getaui ()
      && !anon_checkperm (sbp, fsp->options,
			  *sbp->Xtmpl getarg<nfs_fh3> () == fsp->fh_root))
    return false;
#else
  /* The other option is to disallow this.  Then commands like "ls
   * -al" will return a bunch of permission denied errors.  */
  if (!sbp->getaui ()
      && !anon_checkperm (sbp, fsp->options,
			  (fsp == fstab.base ()
			   && (*sbp->Xtmpl getarg<nfs_fh3> ()
			       == fsp->fh_root))))
    return false;
#endif

  switch (sbp->proc ()) {
  case NFSPROC3_LOOKUP:
    {
      diropargs3 *doa = sbp->Xtmpl getarg<diropargs3> ();
      if (doa->name == ".." && doa->dir == fsp->fh_root) {
	if (!getfsno (fsp)) {
	  nfs3exp_err (sbp, NFS3ERR_ACCES);
	  return false;
	}
	doa->dir = fsp->fh_mntpt;
	rqsp->fsno = getfsno (fsp->parent);
	fsp = &fstab[rqsp->fsno];
	rqsp->rootfh = true;
	rqsp->c = fsp->c;
      }
      break;
    }
  case NFSPROC3_READDIR:
  case NFSPROC3_READDIRPLUS:
    {
      nfs_fh3 *rpa = sbp->Xtmpl getarg<nfs_fh3> ();
      if (*rpa == fsp->fh_root)
	rqsp->rootfh = true;
      break;
    }
  }
  return true;
}