1 /* Test for access to file, relative to open directory. Hurd version.
2 Copyright (C) 2006-2018 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 <http://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 __hurd_at_flags (&at_flags
, &hurd_flags
);
65 error_t
reauthenticate_cwdir_at (file_t
*result
)
67 /* Get a port to the FD directory, authenticated with the real IDs. */
70 ref
= __mach_reply_port ();
74 err
= __io_reauthenticate (port
, ref
, MACH_MSG_TYPE_MAKE_SEND
);
76 err
= __auth_user_authenticate (_hurd_id
.rid_auth
,
77 ref
, MACH_MSG_TYPE_MAKE_SEND
,
81 __mach_port_destroy (__mach_task_self (), ref
);
85 error_t
reauthenticate (int which
, file_t
*result
)
87 /* Get a port to our root directory, authenticated with the real IDs. */
90 ref
= __mach_reply_port ();
94 err
= __io_reauthenticate (port
, ref
, MACH_MSG_TYPE_MAKE_SEND
);
96 err
= __auth_user_authenticate (_hurd_id
.rid_auth
,
97 ref
, MACH_MSG_TYPE_MAKE_SEND
,
101 __mach_port_destroy (__mach_task_self (), ref
);
105 error_t
init_port (int which
, error_t (*operate
) (mach_port_t
))
110 return (*operate
) (_hurd_id
.rid_auth
);
111 case INIT_PORT_CRDIR
:
112 return (reauthenticate (INIT_PORT_CRDIR
, &rcrdir
) ?:
113 (*operate
) (rcrdir
));
114 case INIT_PORT_CWDIR
:
115 if (fd
== AT_FDCWD
|| file
[0] == '/')
116 return (reauthenticate (INIT_PORT_CWDIR
, &rcwdir
) ?:
117 (*operate
) (rcwdir
));
119 return (reauthenticate_cwdir_at (&rcwdir
) ?:
120 (*operate
) (rcwdir
));
122 return _hurd_ports_use (which
, operate
);
126 rcrdir
= rcwdir
= MACH_PORT_NULL
;
130 __mutex_lock (&_hurd_id
.lock
);
131 /* Get _hurd_id up to date. */
132 if (err
= _hurd_check_ids ())
135 if (_hurd_id
.rid_auth
== MACH_PORT_NULL
)
137 /* Set up _hurd_id.rid_auth. This is a special auth server port
138 which uses the real uid and gid (the first aux uid and gid) as
139 the only effective uid and gid. */
141 if (_hurd_id
.aux
.nuids
< 1 || _hurd_id
.aux
.ngids
< 1)
143 /* We do not have a real UID and GID. Lose, lose, lose! */
148 /* Create a new auth port using our real UID and GID (the first
149 auxiliary UID and GID) as the only effective IDs. */
150 if (err
= __USEPORT (AUTH
,
151 __auth_makeauth (port
,
152 NULL
, MACH_MSG_TYPE_COPY_SEND
, 0,
153 _hurd_id
.aux
.uids
, 1,
156 _hurd_id
.aux
.gids
, 1,
159 &_hurd_id
.rid_auth
)))
164 /* Look up the file name using the modified init ports. */
165 err
= __hurd_file_name_lookup (&init_port
, &__getdport
, 0,
166 file
, hurd_flags
, 0, &io
);
168 /* We are done with _hurd_id.rid_auth now. */
170 __mutex_unlock (&_hurd_id
.lock
);
174 if (rcrdir
!= MACH_PORT_NULL
)
175 __mach_port_deallocate (__mach_task_self (), rcrdir
);
176 if (rcwdir
!= MACH_PORT_NULL
)
177 __mach_port_deallocate (__mach_task_self (), rcwdir
);
179 return errfunc (err
);
182 /* Find out what types of access we are allowed to this file. */
183 err
= __file_check_access (io
, &allowed
);
184 __mach_port_deallocate (__mach_task_self (), io
);
186 return errfunc (err
);
196 if (flags
& ~allowed
)
197 /* We are not allowed all the requested types of access. */
198 return errfunc (EACCES
);
204 __faccessat_noerrno (int fd
, const char *file
, int type
, int at_flags
)
206 return __faccessat_common (fd
, file
, type
, at_flags
, hurd_fail_noerrno
);
210 __faccessat (int fd
, const char *file
, int type
, int at_flags
)
212 return __faccessat_common (fd
, file
, type
, at_flags
, hurd_fail_seterrno
);
214 weak_alias (__faccessat
, faccessat
)