/* Copyright (C) 1991-2018 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, see
   <http://www.gnu.org/licenses/>.  */

#include <hurd.h>
#include <hurd/port.h>
#include <hurd/id.h>
#include "set-hooks.h"

/* Things in the library which want to be run when the auth port changes.  */
DEFINE_HOOK (_hurd_reauth_hook, (auth_t new_auth));

#include <cthreads.h>
static struct mutex reauth_lock = MUTEX_INITIALIZER;


/* Set the auth port to NEW, and reauthenticate
   everything used by the library.  */
error_t
_hurd_setauth (auth_t new)
{
  error_t err;
  unsigned int d;
  mach_port_t newport, ref;

  /* Give the new send right a user reference.
     This is a good way to check that it is valid.  */
  if (err = __mach_port_mod_refs (__mach_task_self (), new,
				  MACH_PORT_RIGHT_SEND, 1))
    return err;

  HURD_CRITICAL_BEGIN;

  /* We lock against another thread doing setauth.  Anyone who sets
     _hurd_ports[INIT_PORT_AUTH] some other way is asking to lose.  */
  __mutex_lock (&reauth_lock);

  /* Install the new port in the cell.  */
  __mutex_lock (&_hurd_id.lock);
  _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], new);
  _hurd_id.valid = 0;
  if (_hurd_id.rid_auth)
    {
      __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth);
      _hurd_id.rid_auth = MACH_PORT_NULL;
    }
  __mutex_unlock (&_hurd_id.lock);

  if (_hurd_init_dtable != NULL)
    /* We just have the simple table we got at startup.
       Otherwise, a reauth_hook in dtable.c takes care of this.  */
    for (d = 0; d < _hurd_init_dtablesize; ++d)
      if (_hurd_init_dtable[d] != MACH_PORT_NULL)
	{
	  mach_port_t new;
	  ref = __mach_reply_port ();
	  if (! __io_reauthenticate (_hurd_init_dtable[d],
				     ref, MACH_MSG_TYPE_MAKE_SEND) &&
	      ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH],
			       __auth_user_authenticate
			       (port,
				ref, MACH_MSG_TYPE_MAKE_SEND,
				&new)))
	    {
	      __mach_port_deallocate (__mach_task_self (),
				      _hurd_init_dtable[d]);
	      _hurd_init_dtable[d] = new;
	    }
	  __mach_port_destroy (__mach_task_self (), ref);
	}

  ref = __mach_reply_port ();
  if (__USEPORT (CRDIR,
		 ! __io_reauthenticate (port,
					ref, MACH_MSG_TYPE_MAKE_SEND) &&
		 ! __auth_user_authenticate (new,
					     ref, MACH_MSG_TYPE_MAKE_SEND,
					     &newport)))
    _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport);
  __mach_port_destroy (__mach_task_self (), ref);

  ref = __mach_reply_port ();
  if (__USEPORT (CWDIR,
		 ! __io_reauthenticate (port,
					ref, MACH_MSG_TYPE_MAKE_SEND) &&
		 ! __auth_user_authenticate (new,
					     ref, MACH_MSG_TYPE_MAKE_SEND,
					     &newport)))
    _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport);
  __mach_port_destroy (__mach_task_self (), ref);

  /* Run things which want to do reauthorization stuff.  */
  RUN_HOOK (_hurd_reauth_hook, (new));

  __mutex_unlock (&reauth_lock);

  HURD_CRITICAL_END;

  return 0;
}

int
__setauth (auth_t new)
{
  error_t err = _hurd_setauth (new);
  return err ? __hurd_fail (err) : 0;
}

weak_alias (__setauth, setauth)
