Beispiel #1
0
kern_return_t
S_exec_init (struct trivfs_protid *protid,
	     auth_t auth, process_t proc)
{
  mach_port_t host_priv, startup;
  error_t err;

  if (! protid || ! protid->isroot)
    return EPERM;

  _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], proc); /* Consume.  */
  _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], auth); /* Consume.  */

  /* Do initial setup with the proc server.  */
  _hurd_proc_init (save_argv, NULL, 0);

  procserver = getproc ();

  /* Have the proc server notify us when the canonical ints and ports
     change.  This will generate an immediate callback giving us the
     initial boot-time canonical sets.  */
  {
    struct iouser *user;
    struct trivfs_protid *cred;
    mach_port_t right;

    err = iohelp_create_empty_iouser (&user);
    assert_perror (err);
    err = trivfs_open (fsys, user, 0, MACH_PORT_NULL, &cred);
    assert_perror (err);

    right = ports_get_send_right (cred);
    proc_execdata_notify (procserver, right, MACH_MSG_TYPE_COPY_SEND);
    mach_port_deallocate (mach_task_self (), right);
  }

  err = get_privileged_ports (&host_priv, NULL);
  assert_perror (err);

  proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION);

  err = proc_getmsgport (procserver, 1, &startup);
  assert_perror (err);
  mach_port_deallocate (mach_task_self (), procserver);

  /* Call startup_essential task last; init assumes we are ready to
     run once we call it. */
  err = startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL,
				"exec", host_priv);
  assert_perror (err);
  mach_port_deallocate (mach_task_self (), startup);

  mach_port_deallocate (mach_task_self (), host_priv);

  return 0;
}
Beispiel #2
0
kern_return_t
trivfs_S_fsys_getroot (struct trivfs_control *cntl,
		       mach_port_t reply_port,
		       mach_msg_type_name_t reply_port_type,
		       mach_port_t dotdot,
		       uid_t *uids, size_t nuids,
		       uid_t *gids, size_t ngids,
		       int flags,
		       retry_type *do_retry,
		       char *retry_name,
		       mach_port_t *newpt,
		       mach_msg_type_name_t *newpttype)
{
  int perms;
  error_t err = 0;
  mach_port_t new_realnode;
  struct trivfs_protid *cred;
  struct iouser *user;

  if (!cntl)
    return EOPNOTSUPP;

  if (trivfs_getroot_hook)
    {
      err = (*trivfs_getroot_hook) (cntl, reply_port, reply_port_type, dotdot,
				    uids, nuids, gids, ngids, flags,
				    do_retry, retry_name, newpt, newpttype);
      if (err != EAGAIN)
	return err;
    }

  if ((flags & O_WRITE & trivfs_allow_open) != (flags & O_WRITE))
    return EROFS;
  if ((flags & (O_READ|O_WRITE|O_EXEC) & trivfs_allow_open)
      != (flags & (O_READ|O_WRITE|O_EXEC)))
    return EACCES;

  /* O_CREAT and O_EXCL are not meaningful here; O_NOLINK and O_NOTRANS
     will only be useful when trivfs supports translators (which it doesn't
     now). */
  flags &= O_HURD;
  flags &= ~(O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS);

  struct idvec idvec = {
    .ids = uids,
    .num = nuids,
    .alloced = nuids,
  };

  if (_is_privileged (&idvec))
    /* Privileged users should be given all our rights.  */
    err = io_duplicate (cntl->underlying, &new_realnode);
  else
    /* Non-privileged, restrict rights.  */
    err = io_restrict_auth (cntl->underlying,
			    &new_realnode, uids, nuids, gids, ngids);

  if (err)
    return err;

  err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
  if (err)
    return err;

  /* Validate permissions.  */
  if (! trivfs_check_access_hook)
    file_check_access (new_realnode, &perms);
  else
    (*trivfs_check_access_hook) (cntl, user, new_realnode, &perms);
  if ((flags & (O_READ|O_WRITE|O_EXEC) & perms)
      != (flags & (O_READ|O_WRITE|O_EXEC)))
    err = EACCES;

  if (!err && trivfs_check_open_hook)
    err = (*trivfs_check_open_hook) (cntl, user, flags);
  if (!err)
    {
      if (! trivfs_open_hook)
	{
	  err = trivfs_open (cntl, user, flags, new_realnode, &cred);
	  if (!err)
	    mach_port_deallocate (mach_task_self (), dotdot);
	}
      else
	err = (*trivfs_open_hook) (cntl, user, dotdot, flags, new_realnode,
				   &cred);
    }

  if (err)
    {
      mach_port_deallocate (mach_task_self (), new_realnode);
      iohelp_free_iouser (user);
    }
  else
    {
      *do_retry = FS_RETRY_NORMAL;
      *retry_name = '\0';
      *newpt = ports_get_right (cred);
      *newpttype = MACH_MSG_TYPE_MAKE_SEND;
      ports_port_deref (cred);
    }

  return err;
}
Beispiel #3
0
kern_return_t
trivfs_S_dir_lookup (struct trivfs_protid *cred,
		     mach_port_t reply, mach_msg_type_name_t reply_type,
		     char *filename,
		     int flags,
		     mode_t mode,
		     retry_type *retry_type,
		     char *retry_name,
		     mach_port_t *retrypt,
		     mach_msg_type_name_t *retrypt_type)
{
  int perms;
  error_t err;
  struct trivfs_protid *newcred;

  if (!cred)
    return EOPNOTSUPP;

  if (filename[0])
    return ENOTDIR;

  /* This is a null-pathname "reopen" call; do the right thing. */

  /* Burn off flags we don't actually implement */
  flags &= O_HURD;
  flags &= ~(O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS);

  /* Validate permissions */
  if (! trivfs_check_access_hook)
    file_check_access (cred->realnode, &perms);
  else
    (*trivfs_check_access_hook) (cred->po->cntl, cred->user,
				 cred->realnode, &perms);
  if ((flags & (O_READ|O_WRITE|O_EXEC) & perms)
      != (flags & (O_READ|O_WRITE|O_EXEC)))
    return EACCES;

  /* Execute the open */
  err = 0;
  if (trivfs_check_open_hook)
    err = (*trivfs_check_open_hook) (cred->po->cntl, cred->user, flags);
  if (!err)
    {
      struct iouser *user;

      err = iohelp_dup_iouser (&user, cred->user);
      if (err)
	return err;

      err = trivfs_open (cred->po->cntl, user, flags,
			 cred->realnode, &newcred);
      if (err)
	iohelp_free_iouser (user);
      else
	mach_port_mod_refs (mach_task_self (), cred->realnode,
			    MACH_PORT_RIGHT_SEND, +1);
    }
  if (err)
    return err;

  *retry_type = FS_RETRY_NORMAL;
  *retry_name = '\0';
  *retrypt = ports_get_right (newcred);
  *retrypt_type = MACH_MSG_TYPE_MAKE_SEND;
  ports_port_deref (newcred);
  return 0;
}