(root)/
glibc-2.38/
hurd/
setauth.c
       1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <hurd.h>
      19  #include <hurd/port.h>
      20  #include <hurd/id.h>
      21  #include <hurdlock.h>
      22  #include "set-hooks.h"
      23  
      24  /* Things in the library which want to be run when the auth port changes.  */
      25  DEFINE_HOOK (_hurd_reauth_hook, (auth_t new_auth));
      26  
      27  static unsigned int reauth_lock = LLL_LOCK_INITIALIZER;
      28  
      29  /* Set the auth port to NEW, and reauthenticate
      30     everything used by the library.  */
      31  error_t
      32  _hurd_setauth (auth_t new)
      33  {
      34    error_t err;
      35    unsigned int d;
      36    mach_port_t newport, ref;
      37  
      38    /* Give the new send right a user reference.
      39       This is a good way to check that it is valid.  */
      40    if (err = __mach_port_mod_refs (__mach_task_self (), new,
      41  				  MACH_PORT_RIGHT_SEND, 1))
      42      return err;
      43  
      44    HURD_CRITICAL_BEGIN;
      45  
      46    /* We lock against another thread doing setauth.  Anyone who sets
      47       _hurd_ports[INIT_PORT_AUTH] some other way is asking to lose.  */
      48    __mutex_lock (&reauth_lock);
      49  
      50    /* Install the new port in the cell.  */
      51    __mutex_lock (&_hurd_id.lock);
      52    _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], new);
      53    _hurd_id.valid = 0;
      54    if (_hurd_id.rid_auth)
      55      {
      56        __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth);
      57        _hurd_id.rid_auth = MACH_PORT_NULL;
      58      }
      59    __mutex_unlock (&_hurd_id.lock);
      60  
      61    if (_hurd_init_dtable != NULL)
      62      /* We just have the simple table we got at startup.
      63         Otherwise, a reauth_hook in dtable.c takes care of this.  */
      64      for (d = 0; d < _hurd_init_dtablesize; ++d)
      65        if (_hurd_init_dtable[d] != MACH_PORT_NULL)
      66  	{
      67  	  mach_port_t new;
      68  	  ref = __mach_reply_port ();
      69  	  if (! __io_reauthenticate (_hurd_init_dtable[d],
      70  				     ref, MACH_MSG_TYPE_MAKE_SEND)
      71  	      && ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH],
      72  				  __auth_user_authenticate
      73  				  (port,
      74  				   ref, MACH_MSG_TYPE_MAKE_SEND,
      75  				   &new)))
      76  	    {
      77  	      __mach_port_deallocate (__mach_task_self (),
      78  				      _hurd_init_dtable[d]);
      79  	      _hurd_init_dtable[d] = new;
      80  	    }
      81  	  __mach_port_destroy (__mach_task_self (), ref);
      82  	}
      83  
      84    ref = __mach_reply_port ();
      85    if (__USEPORT (CRDIR,
      86  		 ! __io_reauthenticate (port,
      87  					ref, MACH_MSG_TYPE_MAKE_SEND)
      88  		 && ! __auth_user_authenticate (new,
      89  						ref, MACH_MSG_TYPE_MAKE_SEND,
      90  						&newport)))
      91      _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport);
      92    __mach_port_destroy (__mach_task_self (), ref);
      93  
      94    ref = __mach_reply_port ();
      95    if (__USEPORT (CWDIR,
      96  		 ! __io_reauthenticate (port,
      97  					ref, MACH_MSG_TYPE_MAKE_SEND)
      98  		 && ! __auth_user_authenticate (new,
      99  						ref, MACH_MSG_TYPE_MAKE_SEND,
     100  						&newport)))
     101      _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport);
     102    __mach_port_destroy (__mach_task_self (), ref);
     103  
     104    /* Run things which want to do reauthorization stuff.  */
     105    RUN_HOOK (_hurd_reauth_hook, (new));
     106  
     107    __mutex_unlock (&reauth_lock);
     108  
     109    HURD_CRITICAL_END;
     110  
     111    return 0;
     112  }
     113  
     114  int
     115  __setauth (auth_t new)
     116  {
     117    error_t err = _hurd_setauth (new);
     118    return err ? __hurd_fail (err) : 0;
     119  }
     120  
     121  weak_alias (__setauth, setauth)