Back to index

glibc  2.9
access.c File Reference
#include <unistd.h>
#include <hurd.h>
#include <hurd/port.h>
#include <hurd/id.h>
#include <hurd/lookup.h>
#include <fcntl.h>

Go to the source code of this file.


int __access (char *file, int type) const

Function Documentation

int __access ( char *  file,
int  type 
) const

Definition at line 28 of file access.c.

  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
          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,
      __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));
         return _hurd_ports_use (which, operate);

  rcrdir = rcwdir = MACH_PORT_NULL;


  __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.gids, 1,
       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.  */
  __mutex_unlock (&_hurd_id.lock);


  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;

Here is the call graph for this function: