]>
git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/mach/hurd/faccessat.c
1 /* Test for access to file, relative to open directory. Hurd version.
2 Copyright (C) 2006-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
23 #include <sys/types.h>
26 #include <hurd/port.h>
28 #include <hurd/lookup.h>
31 hurd_fail_seterrno (error_t err
)
33 return __hurd_fail (err
);
37 hurd_fail_noerrno (error_t err
)
43 __faccessat_common (int fd
, const char *file
, int type
, int at_flags
,
44 int (*errfunc
) (error_t
))
47 file_t rcrdir
, rcwdir
, io
;
50 if ((at_flags
& AT_EACCESS
) == AT_EACCESS
)
52 /* Use effective permissions. */
53 io
= __file_name_lookup_at (fd
, at_flags
&~ AT_EACCESS
, file
, 0, 0);
54 if (io
== MACH_PORT_NULL
)
59 /* We have to use real permissions instead of the
60 usual effective permissions. */
63 err
= __hurd_at_flags (&at_flags
, &hurd_flags
);
67 error_t
reauthenticate_cwdir_at (file_t
*result
)
69 /* Get a port to the FD directory, authenticated with the real IDs. */
72 ref
= __mach_reply_port ();
76 err
= __io_reauthenticate (port
, ref
, MACH_MSG_TYPE_MAKE_SEND
);
78 err
= __auth_user_authenticate (_hurd_id
.rid_auth
,
79 ref
, MACH_MSG_TYPE_MAKE_SEND
,
83 __mach_port_destroy (__mach_task_self (), ref
);
87 error_t
reauthenticate (int which
, file_t
*result
)
89 /* Get a port to our root directory, authenticated with the real IDs. */
92 ref
= __mach_reply_port ();
96 err
= __io_reauthenticate (port
, ref
, MACH_MSG_TYPE_MAKE_SEND
);
98 err
= __auth_user_authenticate (_hurd_id
.rid_auth
,
99 ref
, MACH_MSG_TYPE_MAKE_SEND
,
103 __mach_port_destroy (__mach_task_self (), ref
);
107 error_t
init_port (int which
, error_t (*operate
) (mach_port_t
))
112 return (*operate
) (_hurd_id
.rid_auth
);
113 case INIT_PORT_CRDIR
:
114 return (reauthenticate (INIT_PORT_CRDIR
, &rcrdir
) ?:
115 (*operate
) (rcrdir
));
116 case INIT_PORT_CWDIR
:
117 if (fd
== AT_FDCWD
|| file
[0] == '/')
118 return (reauthenticate (INIT_PORT_CWDIR
, &rcwdir
) ?:
119 (*operate
) (rcwdir
));
121 return (reauthenticate_cwdir_at (&rcwdir
) ?:
122 (*operate
) (rcwdir
));
124 return _hurd_ports_use (which
, operate
);
128 rcrdir
= rcwdir
= MACH_PORT_NULL
;
132 __mutex_lock (&_hurd_id
.lock
);
133 /* Get _hurd_id up to date. */
134 if (err
= _hurd_check_ids ())
137 if (_hurd_id
.rid_auth
== MACH_PORT_NULL
)
139 /* Set up _hurd_id.rid_auth. This is a special auth server port
140 which uses the real uid and gid (the first aux uid and gid) as
141 the only effective uid and gid. */
143 if (_hurd_id
.aux
.nuids
< 1 || _hurd_id
.aux
.ngids
< 1)
145 /* We do not have a real UID and GID. Lose, lose, lose! */
150 /* Create a new auth port using our real UID and GID (the first
151 auxiliary UID and GID) as the only effective IDs. */
152 if (err
= __USEPORT (AUTH
,
153 __auth_makeauth (port
,
154 NULL
, MACH_MSG_TYPE_COPY_SEND
, 0,
155 _hurd_id
.aux
.uids
, 1,
158 _hurd_id
.aux
.gids
, 1,
161 &_hurd_id
.rid_auth
)))
166 /* Look up the file name using the modified init ports. */
167 err
= __hurd_file_name_lookup (&init_port
, &__getdport
, 0,
168 file
, hurd_flags
, 0, &io
);
170 /* We are done with _hurd_id.rid_auth now. */
172 __mutex_unlock (&_hurd_id
.lock
);
176 if (rcrdir
!= MACH_PORT_NULL
)
177 __mach_port_deallocate (__mach_task_self (), rcrdir
);
178 if (rcwdir
!= MACH_PORT_NULL
)
179 __mach_port_deallocate (__mach_task_self (), rcwdir
);
181 return errfunc (err
);
184 /* Find out what types of access we are allowed to this file. */
185 err
= __file_check_access (io
, &allowed
);
186 __mach_port_deallocate (__mach_task_self (), io
);
188 return errfunc (err
);
198 if (flags
& ~allowed
)
199 /* We are not allowed all the requested types of access. */
200 return errfunc (EACCES
);
206 __faccessat_noerrno (int fd
, const char *file
, int type
, int at_flags
)
208 return __faccessat_common (fd
, file
, type
, at_flags
, hurd_fail_noerrno
);
212 __faccessat (int fd
, const char *file
, int type
, int at_flags
)
214 return __faccessat_common (fd
, file
, type
, at_flags
, hurd_fail_seterrno
);
216 weak_alias (__faccessat
, faccessat
)