/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <unistd.h>
#include <hurd.h>
#include <hurd/port.h>
#include <hurd/id.h>
#include <hurd/lookup.h>
#include <fcntl.h>

/* Test for access to FILE by our real user and group IDs.  */
int
__access (file, type)
     const char *file;
     int type;
{
  error_t err;
  file_t rcrdir, rcwdir, io;
  int flags, allowed;

  error_t reauthenticate (int which, file_t *result)
    {
      /* Get a port to our root directory, authenticated with the real IDs.  */
      error_t err;
      mach_port_t ref;
      ref = __mach_reply_port ();
      err = HURD_PORT_USE
	(&_hurd_ports[which],
	 ({
	   err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
	   if (!err)
	     err = __auth_user_authenticate (_hurd_id.rid_auth,
					     ref, MACH_MSG_TYPE_MAKE_SEND,
					     result);
	   err;
	 }));
      __mach_port_destroy (__mach_task_self (), ref);
      return err;
    }

  error_t init_port (int which, error_t (*operate) (mach_port_t))
    {
      switch (which)
	{
	case INIT_PORT_AUTH:
	  return (*operate) (_hurd_id.rid_auth);
	case INIT_PORT_CRDIR:
	  return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
		  (*operate) (rcrdir));
	case INIT_PORT_CWDIR:
	  return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
		  (*operate) (rcwdir));
	default:
	  return _hurd_ports_use (which, operate);
	}
    }

  rcrdir = rcwdir = MACH_PORT_NULL;

  HURD_CRITICAL_BEGIN;

  __mutex_lock (&_hurd_id.lock);
  /* Get _hurd_id up to date.  */
  if (err = _hurd_check_ids ())
    goto lose;

  if (_hurd_id.rid_auth == MACH_PORT_NULL)
    {
      /* Set up _hurd_id.rid_auth.  This is a special auth server port
	 which uses the real uid and gid (the first aux uid and gid) as
	 the only effective uid and gid.  */

      if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
	{
	  /* We do not have a real UID and GID.  Lose, lose, lose!  */
	  err = EGRATUITOUS;
	  goto lose;
	}

      /* Create a new auth port using our real UID and GID (the first
	 auxiliary UID and GID) as the only effective IDs.  */
      if (err = __USEPORT (AUTH,
			   __auth_makeauth (port,
					    NULL, MACH_MSG_TYPE_COPY_SEND, 0,
					    _hurd_id.aux.uids, 1,
					    _hurd_id.aux.uids,
					    _hurd_id.aux.nuids,
					    _hurd_id.aux.gids, 1,
					    _hurd_id.aux.gids,
					    _hurd_id.aux.ngids,
					    &_hurd_id.rid_auth)))
	goto lose;
    }

  if (!err)
    /* Look up the file name using the modified init ports.  */
    err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
				   file, 0, 0, &io);

  /* We are done with _hurd_id.rid_auth now.  */
 lose:
  __mutex_unlock (&_hurd_id.lock);

  HURD_CRITICAL_END;

  if (rcrdir != MACH_PORT_NULL)
    __mach_port_deallocate (__mach_task_self (), rcrdir);
  if (rcwdir != MACH_PORT_NULL)
    __mach_port_deallocate (__mach_task_self (), rcwdir);
  if (err)
    return __hurd_fail (err);

  /* Find out what types of access we are allowed to this file.  */
  err = __file_check_access (io, &allowed);
  __mach_port_deallocate (__mach_task_self (), io);
  if (err)
    return __hurd_fail (err);

  flags = 0;
  if (type & R_OK)
    flags |= O_READ;
  if (type & W_OK)
    flags |= O_WRITE;
  if (type & X_OK)
    flags |= O_EXEC;

  if (flags & ~allowed)
    /* We are not allowed all the requested types of access.  */
    return __hurd_fail (EACCES);

  return 0;
}

weak_alias (__access, access)
