1 | /* Copyright (C) 1991-2022 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) |
122 | |