xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* Copyright (C) 1991-2016 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 | <http://www.gnu.org/licenses/>. */ |
| 17 | |
| 18 | #include <hurd.h> |
| 19 | #include <hurd/port.h> |
| 20 | #include <hurd/id.h> |
| 21 | #include "set-hooks.h" |
| 22 | |
| 23 | /* Things in the library which want to be run when the auth port changes. */ |
| 24 | DEFINE_HOOK (_hurd_reauth_hook, (auth_t new_auth)); |
| 25 | |
| 26 | #include <cthreads.h> |
| 27 | static struct mutex reauth_lock = MUTEX_INITIALIZER; |
| 28 | |
| 29 | |
| 30 | /* Set the auth port to NEW, and reauthenticate |
| 31 | everything used by the library. */ |
| 32 | error_t |
| 33 | _hurd_setauth (auth_t new) |
| 34 | { |
| 35 | error_t err; |
| 36 | unsigned int d; |
| 37 | mach_port_t newport, ref; |
| 38 | |
| 39 | /* Give the new send right a user reference. |
| 40 | This is a good way to check that it is valid. */ |
| 41 | if (err = __mach_port_mod_refs (__mach_task_self (), new, |
| 42 | MACH_PORT_RIGHT_SEND, 1)) |
| 43 | return err; |
| 44 | |
| 45 | HURD_CRITICAL_BEGIN; |
| 46 | |
| 47 | /* We lock against another thread doing setauth. Anyone who sets |
| 48 | _hurd_ports[INIT_PORT_AUTH] some other way is asking to lose. */ |
| 49 | __mutex_lock (&reauth_lock); |
| 50 | |
| 51 | /* Install the new port in the cell. */ |
| 52 | __mutex_lock (&_hurd_id.lock); |
| 53 | _hurd_port_set (&_hurd_ports[INIT_PORT_AUTH], new); |
| 54 | _hurd_id.valid = 0; |
| 55 | if (_hurd_id.rid_auth) |
| 56 | { |
| 57 | __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth); |
| 58 | _hurd_id.rid_auth = MACH_PORT_NULL; |
| 59 | } |
| 60 | __mutex_unlock (&_hurd_id.lock); |
| 61 | |
| 62 | if (_hurd_init_dtable != NULL) |
| 63 | /* We just have the simple table we got at startup. |
| 64 | Otherwise, a reauth_hook in dtable.c takes care of this. */ |
| 65 | for (d = 0; d < _hurd_init_dtablesize; ++d) |
| 66 | if (_hurd_init_dtable[d] != MACH_PORT_NULL) |
| 67 | { |
| 68 | mach_port_t new; |
| 69 | ref = __mach_reply_port (); |
| 70 | if (! __io_reauthenticate (_hurd_init_dtable[d], |
| 71 | ref, MACH_MSG_TYPE_MAKE_SEND) && |
| 72 | ! HURD_PORT_USE (&_hurd_ports[INIT_PORT_AUTH], |
| 73 | __auth_user_authenticate |
| 74 | (port, |
| 75 | ref, MACH_MSG_TYPE_MAKE_SEND, |
| 76 | &new))) |
| 77 | { |
| 78 | __mach_port_deallocate (__mach_task_self (), |
| 79 | _hurd_init_dtable[d]); |
| 80 | _hurd_init_dtable[d] = new; |
| 81 | } |
| 82 | __mach_port_destroy (__mach_task_self (), ref); |
| 83 | } |
| 84 | |
| 85 | ref = __mach_reply_port (); |
| 86 | if (__USEPORT (CRDIR, |
| 87 | ! __io_reauthenticate (port, |
| 88 | ref, MACH_MSG_TYPE_MAKE_SEND) && |
| 89 | ! __auth_user_authenticate (new, |
| 90 | ref, MACH_MSG_TYPE_MAKE_SEND, |
| 91 | &newport))) |
| 92 | _hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], newport); |
| 93 | __mach_port_destroy (__mach_task_self (), ref); |
| 94 | |
| 95 | ref = __mach_reply_port (); |
| 96 | if (__USEPORT (CWDIR, |
| 97 | ! __io_reauthenticate (port, |
| 98 | ref, MACH_MSG_TYPE_MAKE_SEND) && |
| 99 | ! __auth_user_authenticate (new, |
| 100 | ref, MACH_MSG_TYPE_MAKE_SEND, |
| 101 | &newport))) |
| 102 | _hurd_port_set (&_hurd_ports[INIT_PORT_CWDIR], newport); |
| 103 | __mach_port_destroy (__mach_task_self (), ref); |
| 104 | |
| 105 | /* Run things which want to do reauthorization stuff. */ |
| 106 | RUN_HOOK (_hurd_reauth_hook, (new)); |
| 107 | |
| 108 | __mutex_unlock (&reauth_lock); |
| 109 | |
| 110 | HURD_CRITICAL_END; |
| 111 | |
| 112 | return 0; |
| 113 | } |
| 114 | |
| 115 | int |
| 116 | __setauth (auth_t new) |
| 117 | { |
| 118 | error_t err = _hurd_setauth (new); |
| 119 | return err ? __hurd_fail (err) : 0; |
| 120 | } |
| 121 | |
| 122 | weak_alias (__setauth, setauth) |