diff options
Diffstat (limited to 'libfshelp')
-rw-r--r-- | libfshelp/ChangeLog | 570 | ||||
-rw-r--r-- | libfshelp/Makefile | 38 | ||||
-rw-r--r-- | libfshelp/delegate.c | 65 | ||||
-rw-r--r-- | libfshelp/drop-transbox.c | 28 | ||||
-rw-r--r-- | libfshelp/exec-reauth.c | 152 | ||||
-rw-r--r-- | libfshelp/fetch-control.c | 31 | ||||
-rw-r--r-- | libfshelp/fetch-root.c | 193 | ||||
-rw-r--r-- | libfshelp/fshelp.h | 263 | ||||
-rw-r--r-- | libfshelp/get-identity.c | 88 | ||||
-rw-r--r-- | libfshelp/lock-acquire.c | 134 | ||||
-rw-r--r-- | libfshelp/lock-init.c | 32 | ||||
-rw-r--r-- | libfshelp/locks.h | 28 | ||||
-rw-r--r-- | libfshelp/perms-access.c | 43 | ||||
-rw-r--r-- | libfshelp/perms-checkdirmod.c | 44 | ||||
-rw-r--r-- | libfshelp/perms-isowner.c | 39 | ||||
-rw-r--r-- | libfshelp/set-active.c | 63 | ||||
-rw-r--r-- | libfshelp/set-options.c | 46 | ||||
-rw-r--r-- | libfshelp/start-translator-long.c | 296 | ||||
-rw-r--r-- | libfshelp/start-translator.c | 63 | ||||
-rw-r--r-- | libfshelp/touch.c | 48 | ||||
-rw-r--r-- | libfshelp/trans.h | 32 | ||||
-rw-r--r-- | libfshelp/transbox-init.c | 35 | ||||
-rw-r--r-- | libfshelp/translated.c | 28 |
23 files changed, 2359 insertions, 0 deletions
diff --git a/libfshelp/ChangeLog b/libfshelp/ChangeLog new file mode 100644 index 00000000..dfe88e94 --- /dev/null +++ b/libfshelp/ChangeLog @@ -0,0 +1,570 @@ +1999-10-07 Thomas Bushnell, BSG <tb@mit.edu> + + * start-translator-long.c (fshelp_start_translator_long): Doc fix. + * fshelp.h (fshelp_start_translator_long): Document OWNER_UID. + +1999-10-07 Roland McGrath <roland@baalperazim.frob.com> + + * start-translator-long.c (fshelp_start_translator_long): Take new + argument OWNER_UID. Get child's proc port and do proc_setowner on it. + * fshelp.h: Update decl. + * start-translator.c (fshelp_start_translator): Pass new arg to + fshelp_start_translator_long with value from geteuid (). + * fetch-root.c (fshelp_fetch_root): Pass UID as new arg to + fshelp_start_translator_long. + +1999-09-12 Roland McGrath <roland@baalperazim.frob.com> + + * delegate.c (fshelp_delegate_translation): Free ARGZ after RPC. + +1999-07-11 Thomas Bushnell, BSG <tb@mit.edu> + + * set-options.c (fshelp_set_options): Explicitly cast first arg to + argz_extract to keep GCC quiet. + +1999-07-01 Thomas Bushnell, BSG <tb@mit.edu> + + * translated.c: New file; guts from fshelp.h. + * perms-isowner.c: Likewise. + * perms-access.c: Likewise. + * prems-checkdirmod.c: Likewise. + * touch.c: Likewise. + * fshelp.h (fshelp_translated, fshelp_isowner, fshelp_access, + fshelp_checkdirmod, fshelp_touch): Replace inline definitions with + ordinary declarations. + (FSHELP_EI): Removed macro. + * fshelp.c: Deleted file. + * Makefile (SRCS): Added translated.c, perms-isowner.c, + perms-access.c, perms-checkdirmod.c, touch.c. Removed fshelp.c. + +Wed Apr 28 03:06:19 1999 Thomas Bushnell, BSG <tb@mit.edu> + + * fetch-root.c (fshelp_fetch_root): Don't deallocate the + INIT_PORT_CWDIR after starting the passive translator; we still + need to keep our reference around until the getroot call happens. + Reported by Marcus Brinkmann (Marcus.Brinkmann@ruhr-uni-bochum.de). + +Tue Apr 20 21:43:20 1999 Thomas Bushnell, BSG <tb@mit.edu> + + * fetch-root.c (fshelp_fetch_root): When starting a passive + translator, set cwd to be DOTDOT instead of our own cwd. + +Sat Mar 6 17:03:02 1999 Thomas Bushnell, BSG <tb@mit.edu> + + * start-translator-long.c (service_fsys_startup): Doc fixes, and + omit unused member `dead' from REQUEST. + +1999-02-28 Roland McGrath <roland@baalperazim.frob.com> + + * get-identity.c (fshelp_get_identity): Use ports_class_iterate. + +1998-12-19 Roland McGrath <roland@baalperazim.frob.com> + + * fetch-root.c (fshelp_fetch_root): Cope when we have a null auth + server port (pass our own ports). + +1998-09-04 Roland McGrath <roland@baalperazim.frob.com> + + * fshelp.h (fshelp_set_options): Use `const' for `char *' parameter. + * set-options.c (fshelp_set_options): Fix defn. + +1998-08-21 Roland McGrath <roland@baalperazim.frob.com> + + * Makefile (SRCS): Remove return-buffer.c. + +1998-08-20 Roland McGrath <roland@baalperazim.frob.com> + + * fshelp.h: Moved fshelp_return_malloced_buffer to libiohelp. + * return-buffer.c: Moved to ../libiohelp/return-buffer.c. + (fshelp_return_malloced_buffer): Renamed to iohelp_*. + +Tue Jul 1 16:45:27 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * exec-reauth.c (fshelp_exec_reauth): If the new set of eff_uids + is empty, then still do proc_setowner, but this time to set it to + "unowned" status. + +1997-06-12 Miles Bader <miles@gnu.ai.mit.edu> + + * fshelp.h (fshelp_touch): New function. + (TOUCH_ATIME, TOUCH_MTIME, TOUCH_CTIME): New macros. + Include <maptime.h>. + +1997-06-11 Miles Bader <miles@gnu.ai.mit.edu> + + * fshelp.h (fshelp_fetch_root_callback1_t): Chage ARGZ_LEN to type + size_t. + +Fri Nov 15 14:43:44 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * fshelp.h (fshelp_access): Uh, shift bits the right direction. + +Tue Nov 12 22:07:41 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Name idvec members correctly. + + * fshelp.h: <iohelp.h> -> <hurd/iohelp.h>. + Include <sys/stat.h>. + (fshelp_access): Declare `gotit'. + +Wed Nov 6 17:49:33 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * fshelp.h (fshelp_fetch_root): Delete args `uids', `gids', + `uids_len', and `gids_len'. New arg `user'. + * fetch-root.c (fshelp_fetch_root): Ditto. + + * fshelp.h: Include <iohelp.h>. + (fshelp_access, fshelp_isowner, fshelp_checkdirmod): New + functions. + +Mon Oct 21 21:55:21 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * fshelp.h: Add extern inline protection. + * fshelp.c: New file. + * Makefile (SRCS): Add fshelp.c. + +Sun Oct 13 21:46:18 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * lock-acquire.c (fshelp_acquire_lock): Return success, not EBADF, + when unlocking a file which we don't have locked; this is netbsd's + behavior. + +Thu Oct 10 17:12:19 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * lock-acquire.c (fshelp_acquire_lock): Use hurd_condition_wait so + we are properly interruptible. + +Thu Sep 12 16:21:51 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * Makefile (HURDLIBS): New variable. + (libfshelp.so): Delete special dependency. + +Tue Jul 16 11:30:42 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * lock-acquire.c (EWOULDBLOCK): Define, to work around new libc + bug. + +Sun Jul 7 21:26:02 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * start-translator.c (fshelp_start_translator): Don't use unsafe + MOVE_SEND in call to fshelp_start_translator_long. + * fetch-root.c (fshelp_fetch_root): Don't use unsafe MOVE_SEND in + call to fshelp_start_translator_long. + +Thu Jul 4 15:38:36 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * get-identity.c (fshelp_get_identity): Bother to initialize + I->fileno. + +Wed Jul 3 11:29:49 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * get-identity.c: New file. + * fshelp.h (struct port_bucket): Mention name in global scope. + (fshelp_get_identity): New declaration. + * Makefile (SRCS): Add get-identity.c. + +Thu Jun 27 17:56:44 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * Makefile (LCLHDRS): Add trans.h. + +Mon Jun 24 16:00:48 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Deal properly with errors from + auth_makeauth. + +Fri Jun 21 00:07:26 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * set-options.c (fshelp_set_options): Add & use INPUT arg. + * fshelp.h (fshelp_set_options): Add INPUT argument. + (fshelp_return_malloced_buffer): New declaration. + * return-buffer.c: New file. + * Makefile (SRCS): Add return-buffer.c. + +Wed Jun 19 18:50:01 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * set-options.c: New file. + * fshelp.h: Add fshelp_set_options. + * Makefile (SRCS): Add set-options.c. + +Fri May 10 16:12:50 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * delegate.c (fshelp_delegate_translation): Don't cast ARGV when + calling arg_create. + +Thu May 9 11:17:08 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * exec-reauth.c (fshelp_exec_reauth): Provide new third arg to + proc_setowner. + + * delegate.c (fshelp_delegate_translation): Cast first arg to + argz_create appropriately. + + * fetch-root.c (fshelp_fetch_root) [reauth]: Use new args for + auth_user_authenticate. + +Fri Apr 26 18:51:07 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * start-translator-long.c (service_fsys_startup): Make mach_msg + calls interruptible. + +Wed Feb 21 17:09:12 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * set-active.c (fshelp_set_active): When EXCL, make sure the + active translator is really active. + + * fetch-root.c (fshelp_fetch_root): Make sure the returned fsys control + port is valid. + +Wed Feb 14 16:42:31 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * start-translator-long.c (fshelp_start_translator_long): + Terminate TASK if the exec fails. + +Mon Jan 29 15:32:54 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Use hurd_condition_wait + instead of condition_wait. + + * set-active.c (fshelp_set_active): Deal correctly with the case + where a passive translator is being started. + +Fri Jan 26 17:56:08 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): If io_reauthenticate returns + an error, just return MACH_PORT_NULL instead of aborting (the + server probably died; not a good sign for the health of the + translator, but it's better than dying ourselves...). + +Tue Jan 2 15:36:28 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * exec-reauth.c (fshelp_exec_reauth): Don't setgid the uids. + +Mon Jan 1 17:13:25 1996 Miles Bader <miles@gnu.ai.mit.edu> + + * exec-reauth.c (fshelp_exec_reauth): New function. + * fshelp.h (fshelp_exec_reauth): New declaration. + * Makefile (SRCS): Added exec-reauth.c + +Mon Nov 6 13:37:52 1995 Miles Bader <miles@gnu.ai.mit.edu> + + * start-translator-long.c (service_fsys_startup): Don't pass the + address of reply.realnodeType.msgt_name -- it's not really an int, + although the compiler pretends it is. + + * fetch-root.c (fshelp_fetch_root): When PORT_TYPE is + MACH_MSG_TYPE_MAKE_SEND, make the right *before* using it. + (fshelp_fetch_root): Don't bother reauthenticating the underlying + node returned by CALLBACK2 -- it already has the right ids. This + also gets rid of a problem with giving away our auth port prematurely. + +Wed Nov 1 16:14:08 1995 Miles Bader <miles@gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Uses two callbacks now. Pass + an appropiate function to fshelp_start_translator_long instead of + the actual underlying node. + * fshelp.h (fshelp_fetch_root_callback1_t, + fshelp_fetch_root_callback2_t): New types replacing fshelp_callback_t. + (fshelp_fetch_root): Takes two callback args now. + + * start-translator.c (fshelp_start_translator): Change to use a + callback function instead of passing the actual node. + * start-translator-long.c (fshelp_start_translator_long, + service_fsys_startup): Ditto. + (service_fsys_startup): Support the open flags coming from the + translator. + (struct fsys_startup_request): Add the flags field. + (flagsCheck): New variable. + * fshelp.h (fshelp_open_fn_t): New type. + (fshelp_start_translator, fshelp_start_translator_long): Now take + a function that opens the underlying node instead of the node itself. + +Fri Oct 13 16:52:43 1995 Miles Bader <miles@gnu.ai.mit.edu> + + * start-translator-long.c (fshelp_start_translator_long): Undo + last change to file_exec args. + +Sat Oct 7 20:20:26 1995 Miles Bader <miles@gnu.ai.mit.edu> + + * start-translator-long.c (fshelp_start_translator_long): Add + values for the dealloc parameters to file_exec (all false). + Give away our send right to TASK when we do file_exec. + Initialize BOOTSTRAP & TASK so the cleanup code doesn't get confused. + +Fri Sep 29 17:44:00 1995 Miles Bader <miles@gnu.ai.mit.edu> + + * transbox-init.c (fshelp_transbox_init): Initialize the flags field. + +Tue Sep 5 18:25:24 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> + + * fshelp.h (fshelp_delegate_translation): New declaration. + * delegate.c (fshelp_delegate_translation): New file, new function. + +Fri Sep 1 12:01:06 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> + + * Makefile (SRCS): Add delegate.c. + (REMHDRS): Removed. + +Tue Jul 11 14:11:24 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * start-translator-long.c (fshelp_start_translator_long): If + PORTS_TYPE is MACH_MSG_TYPE_COPY_SEND, then drop our right on + bootstrap after the call, because we are pretending we haven't + changed the calling user's state. For the same reason, save the + old BOOTSTRAP port value, and restore it after the call. + +Thu Jul 6 15:35:23 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * Makefile: Removed dependencies that are now automatically + generated. + +Mon Jun 26 15:36:21 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Wakeup other blocked calls + *before* returning errors provided by fshelp_start_translator_long + or CALLBACK. + +Fri Jun 23 14:25:52 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Parenthesize assert test + correctly. + * start-translator-long.c (service_fsys_startup): Parenthesize + construction of flags arg correctly. + +Thu Jun 22 17:06:51 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root) [reauth]: If PORT is null, then + just return it. + + * fetch-root.c (fshelp_fetch_root): Pass type and length + parameters in the right order in calls to auth_makeauth and + fshelp_start_translator_long. + +Wed Jun 21 13:19:44 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * fetch-root.c (fshelp_fetch_root): Pass new third arg to + fshelp_set_active. + +Mon Jun 19 16:41:51 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * fetch-control.c (fshelp_fetch_control): Only frob refs if + control is non-null. + + * fshelp.h (fshelp_set_active): New parm EXCL. + * set-active.c (fshelp_set_active): Implement new interface. + + * fetch-control.c (fshelp_fetch_control): Don't frob obsolete + innerlock. + * transbox-init.c (fshelp_transbox_init): Don't init obsolete + innerlock. Do init TRANSBOX->wakeup. + * set-active.c (fshelp_set_active): Don't frob obsolete innerlock. + * fetch-root.c (fshelp_fetch_root): Reduce levels of loops. Only + change ACTIVE when we are holding the lock. Use condition + mechanism to serialize attempts to start the passive translator. + * fshelp.h (struct transbox): Delete member `innerlock'. Add + members `flags' and `wakeup'; and define values for flags. + +Wed Jun 14 13:06:17 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + * fshelp.h (fshelp_fetch_root): New arg COOKIE. + (fshelp_callback_t): COOKIE->COOKIE1. New arg COOKIE2. + * fetch-root.c (fshelp_fetch_root): Take new arg COOKIE and pass + it to CALLBACK. Free ARGZ after we're done with them. Never + consume the right on DOTDOT. + * Makefile (LCLHDRS): Removed trans.h. + * handle-startup.c, init-trans.c, start-trans.c, + transboot-clean.c, kill-trans.c, trans-iter.c, trans-cntl.c, + trans-drop.c, trans.h: Deleted files. + + * Makefile (SRCS): Remove translated.c. + * fshelp.h (fshelp_fetch_root): Don't actually need ROOT_TYPE. + UIDS and GIDS should be arrays. + (fshelp_callback_t): Should be error_t. + +Tue Jun 13 15:59:08 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> + + Brand new translator support routines + * fshelp.h: Deleted `struct translink', fshelp_transboot_port_type, + fshelp_init_trans_link, fshelp_set_control, + fshelp_start_translator, fshelp_handle_fsys_startup, + fshelp_transboot_clean, fshelp_translator_iterate, + fshelp_translator_drop, fshelp_kill_translator. + * fshelp.h: Added fshelp_start_translator_long, + fshelp_start_translator, `struct transbox', fshelp_fetch_root, + fshelp_transbox_init, fshelp_callback_t, fshelp_translated, + fshelp_set_active, fshelp_fetch_control, fshelp_drop_transbox. + * Makefile (SRCS): Removed handle-startup.c, init-trans.c, + start-trans.c, transboot-clean.c, kill-trans.c, trans-iter.c, + trans-cntl.c, trans-drop.c. Added start-translator-long.c, + start-translator.c, fetch-root.c, transbox-init.c, translated.c, + set-active.c, fetch-control.c, and drop-transbox.c. + (OBJS): Replaced with computation from $(SRCS). + * start-translator.c, fetch-root.c, transbox-init.c, set-active.c, + fetch-control.c, drop-transbox.c: New files. + * start-translator-long.c: Adapted from ../lib/start-trans.c. + Include "fshelp.h" and <assert.h>. + (service_fsys_startup): Declare static. Only pass + MACH_RCV_TIMEOUT if TIMEOUT is nonzero. New parm `node_type'. + (fshelp_start_translator_long): Renamed from start_translator. + Lookup up executable at NAME instead of ARGZ. Delete vars + INIT_PORTS, FD_PORTS, INIT_INTS, I, and CHILD_PROC. Don't set any + of the ports, fds, or ints, with the exception of the bootstrap + port. Don't bother getting the child's proc server port. + Don't use __USEPORT. If we fail before calling file_exec, + then deallocate the ports ourselves, if they were MOVE_SEND. + +Fri Oct 28 18:37:56 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * start-trans.c: Change `assert (!err)' to `assert_perror (err)' + throughout. + (fshelp_start_translator): Add assert_perror for io_reauthenticate + return. + +Mon Sep 19 20:58:35 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> + + * trans-iter.c (fshelp_translator_iterate): Bother to attach + ITEM onto LIST as it's constructed. + +Sat Sep 10 08:42:00 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> + + * transboot-clean.c (fshelp_transboot_clean): Use EDIED, not EINVAL. + +Wed Sep 7 10:34:13 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> + + * start-trans.c (fshelp_start_translator): RETRY label belongs + *after* initial lock of LINK. Unlock LINK before returning. + +Tue Sep 6 14:52:49 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> + + * fshelp.h (struct trans_link): New member `lock'. + (fshelp_start_translator): Omit `lock' arg. + * trans.h (struct transboot): Omit member `lock'. + * init-trans.c (fshelp_init_trans_link): Initialize LINK->lock. + * start-trans.c (fshelp_start_translator): Don't set TB->lock. + Omit `lock' arg; use LINK->lock instead. + (fshelp_start_translator): Don't deallocate DIR. + * handle-startup.c (fshelp_handle_fsys_startup): Lock + TB->link->lock instead of TB->lock. + * transboot-clean.c (fshelp_transboot_clean): Likewise. + +Thu Sep 1 16:46:53 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * fshelp.h (fshelp_start_translator): Doc fix. + * start-trans.c (fshelp_start_translator): Don't reauthenticate + NODE argument; expect fully authenticated node. + +Wed Aug 31 14:28:25 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * start-trans.c (fshelp_start_translator): Before call to + proc_reauthenticate, CALL mach_reply_port, not just refer to + confusing CPP macro. + + * start-trans.c (fshelp_start_translator): Call proc_setowner + for new process. + +Tue Aug 30 16:19:45 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * start-trans.c: Include <string.h>. + + * start-trans.c (fshelp_start_translator): Use new + reauthentication protocol throughout. + + * start-trans.c (fshelp_start_translator): Use + hurd_file_name_lookup instead of hurd_path_lookup. + +Wed Aug 17 16:03:49 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * start-trans.c (fshelp_start_translator): Designate the new + process as our child; then make sure it's under its own + authentication. As long as we've gotten the proc port for + this operation, might as well pass it too. + (fshelp_start_translator): Zero init ints and init ports. + + * transboot-clean.c (fshelp_transboot_clean): Only set an error + if we haven't gotten fsys_startup yet. + +Mon Aug 15 12:24:47 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * start-trans.c (fshelp_start_translator): Set LINK->starting + before blocking. + * handle-startup.c (fshelp_handle_fsys_startup): Clear + LINK->starting before waking up blocks. + + * fshelp.h (struct trans_link): New member `error'. + * transboot-clean.c (fshelp_transboot_clean): Wakeup blocked + users with error. + * trans-cntl.c (fshelp_set_control): Clear LINK->error. + * init-trans.c (fshelp_init_trans_link): Likewise. + + * start-trans.c (fshelp_start_translator): Fix + auth_user_authenticate to use the correct rendezvous port in + producing realnode from node.. + +Fri Jul 22 12:03:14 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * Makefile: Rewritten in accord with new scheme. + +Wed Jul 20 13:31:39 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> + + * start-trans.c (fshelp_start_translator): Missing first arg + to mach_port_deallocate of `dir'. + +Tue Jul 19 18:44:53 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * fshelp.h (fshelp_start_translator): Doc fix. + (fshelp_handle_fsys_startup): Deleted dotdot args. + * trans.h (struct transboot): Removed member `dir'. + * start-trans.c (fshelp_start_translator): Don't initialize + TB->dir. + (fshelp_start_translator): Deallocate DIR arg when we're + done with it. + * handle-startup.c (fshelp_handle_fsys_startup): Deleted + dotdot args. + * transboot-clean.c (fshelp_transboot_clean): Don't free + no-longer-existent TB->dir. + +Fri Jul 8 12:58:54 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * trans-cntl.c: Include <assert.h>. + +Thu Jul 7 18:08:49 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * trans-drop.c: New file. + * fshelp.h (fshelp_translator_drop): New declaration. + * Makefile (OBJS): Added trans-drop.o. + (SRCS): ADded trans-drop.c. + +Tue Jul 5 14:14:53 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * Makefile (DIST_FILES): New variable. + +Thu Jun 16 16:27:39 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * fshelp.h (fshelp_get_node_port, fshelp_done_with_node): Deleted + prototypes. + (fshelp_start_translator): Changed types of DIR and NODE to be + file_t. + * trans.h (struct transboot): Deleted members UID and GID. + Changed types of DIR and NODE to be file_t. + * transboot-clean.c (fshelp_transboot_clean): Deallocate ports + TB->node and TB->dir instead of calling fshelp_done_with_node. + * start-trans.c (fshelp_start_translator): Changed types of + DIR and MODE to be file_t. Rewritten to behave correctly in + numerous ways. + * handle-startup.c (fshelp_handle_fsys_startup): Return REAL + and DIR from ports in TB instead of calling fshelp_get_node_port. + +Fri Jun 3 18:13:04 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * fshelp.h (fshelp_set_control): New declaration. + * trans-cntl.c: New file. + * Makefile (SRCS): Added trans-cntl.c. + (OBJS): Added trans-cntl.o. + trans-cntl.o: Depend on trans.h. + +Thu May 5 07:46:00 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile: Change uses of $(headers) to $(includedir). + +Mon Feb 14 11:32:59 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile (install): New target. diff --git a/libfshelp/Makefile b/libfshelp/Makefile new file mode 100644 index 00000000..6dc47da6 --- /dev/null +++ b/libfshelp/Makefile @@ -0,0 +1,38 @@ +# +# Copyright (C) 1994, 95, 96, 98, 1999 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +dir := libfshelp +makemode := library + +libname = libfshelp +SRCS = lock-acquire.c lock-init.c \ + start-translator-long.c start-translator.c \ + fetch-root.c transbox-init.c set-active.c fetch-control.c \ + drop-transbox.c translated.c \ + delegate.c \ + exec-reauth.c \ + set-options.c \ + get-identity.c \ + perms-isowner.c perms-access.c perms-checkdirmod.c \ + touch.c +LCLHDRS = fshelp.h locks.h trans.h +installhdrs = fshelp.h + +HURDLIBS=shouldbeinlibc threads +OBJS = $(subst .c,.o,$(SRCS)) + +include ../Makeconf diff --git a/libfshelp/delegate.c b/libfshelp/delegate.c new file mode 100644 index 00000000..b695a47d --- /dev/null +++ b/libfshelp/delegate.c @@ -0,0 +1,65 @@ +/* fshelp_delegate_translation + + Copyright (C) 1995,96,99 Free Software Foundation, Inc. + + Written by Miles Bader <miles@gnu.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <errno.h> +#include <string.h> +#include <argz.h> +#include <hurd.h> +#include <hurd/fsys.h> +#include <hurd/paths.h> + +/* Try to hand off responsibility from a translator to the server located on + the node SERVER_NAME. REQUESTOR is the translator's bootstrap port, and + ARGV is the command line. If SERVER_NAME is NULL, then a name is + concocted by appending ARGV[0] to _SERVERS. */ +error_t +fshelp_delegate_translation (char *server_name, + mach_port_t requestor, char **argv) +{ + error_t err; + file_t server; + + if (! server_name) + { + char *buf = alloca (strlen (argv[0]) + sizeof (_SERVERS)); + strcpy (buf, _SERVERS); + strcat (buf, argv[0]); + server_name = buf; + } + + server = file_name_lookup (server_name, 0, 0); + if (server != MACH_PORT_NULL) + { + char *argz; + int argz_len; + err = argz_create (argv, &argz, &argz_len); + if (!err) + { + err = fsys_forward (server, + requestor, MACH_MSG_TYPE_COPY_SEND, + argz, argz_len); + free (argz); + } + } + else + err = errno; + + return err; +} diff --git a/libfshelp/drop-transbox.c b/libfshelp/drop-transbox.c new file mode 100644 index 00000000..d9087488 --- /dev/null +++ b/libfshelp/drop-transbox.c @@ -0,0 +1,28 @@ +/* + Copyright (C) 1995 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "fshelp.h" + +void +fshelp_drop_transbox (struct transbox *box) +{ + if (box->active != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), box->active); +} diff --git a/libfshelp/exec-reauth.c b/libfshelp/exec-reauth.c new file mode 100644 index 00000000..f0600a1c --- /dev/null +++ b/libfshelp/exec-reauth.c @@ -0,0 +1,152 @@ +/* Setuid reauthentication for exec + + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + + Written by Miles Bader <miles@gnu.ai.mit.edu>, + from the original by Michael I. Bushnell p/BSG <mib@gnu.ai.mit.edu> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <hurd/io.h> +#include <hurd/process.h> +#include <hurd/auth.h> +#include <idvec.h> + +#include "fshelp.h" + +extern error_t +exec_reauth (auth_t auth, int secure, int must_reauth, + mach_port_t *ports, unsigned num_ports, + mach_port_t *fds, unsigned num_fds); + +/* If SUID or SGID is true, adds UID and/or GID respectively to the + authentication in PORTS[INIT_PORT_AUTH], and replaces it with the result. + All the other ports in PORTS and FDS are then reauthenticated, using any + privileges available through AUTH. If GET_FILE_IDS is non-NULL, and the + auth port in PORTS[INIT_PORT_AUTH] is bogus, it is called to get a list of + uids and gids from the file to use as a replacement. If SECURE is + non-NULL, whether not the added ids are new is returned in it. If either + the uid or gid case fails, then the other may still be applied. */ +error_t +fshelp_exec_reauth (int suid, uid_t uid, int sgid, gid_t gid, + auth_t auth, + error_t + (*get_file_ids)(struct idvec *uids, struct idvec *gids), + mach_port_t *ports, mach_msg_type_number_t num_ports, + mach_port_t *fds, mach_msg_type_number_t num_fds, + int *secure) +{ + error_t err = 0; + int _secure = 0; + + if (suid || sgid) + { + int already_root = 0; + auth_t newauth; + /* These variables describe the auth port that the user gave us. */ + struct idvec *eff_uids = make_idvec (), *avail_uids = make_idvec (); + struct idvec *eff_gids = make_idvec (), *avail_gids = make_idvec (); + + if (!eff_uids || !avail_uids || !eff_gids || !avail_gids) + goto abandon_suid; /* Allocation error; probably toast, but... */ + + /* STEP 0: Fetch the user's current id's. */ + err = idvec_merge_auth (eff_uids, avail_uids, eff_gids, avail_gids, + ports[INIT_PORT_AUTH]); + if (err) + goto abandon_suid; + + already_root = + idvec_contains (eff_uids, 0) || idvec_contains (avail_uids, 0); + + /* If the user's auth port is fraudulent, then these values will be + wrong. No matter; we will repeat these checks using secure id sets + later if the port turns out to be bogus. */ + if (suid) + err = idvec_setid (eff_uids, avail_uids, uid, &_secure); + if (sgid && !err) + err = idvec_setid (eff_gids, avail_gids, gid, &_secure); + if (err) + goto abandon_suid; + + /* STEP 3: Attempt to create this new auth handle. */ + err = auth_makeauth (auth, &ports[INIT_PORT_AUTH], + MACH_MSG_TYPE_COPY_SEND, 1, + eff_uids->ids, eff_uids->num, + avail_uids->ids, avail_uids->num, + eff_gids->ids, eff_gids->num, + avail_gids->ids, avail_gids->num, + &newauth); + if (err == EINVAL && get_file_ids) + /* The user's auth port was bogus. As we can't trust what the user + has told us about ids, we use the authentication on the file being + execed (which we know is good), as the effective ids, and assume + no aux ids. */ + { + /* Get rid of all ids from the bogus auth port. */ + idvec_clear (eff_uids); + idvec_clear (avail_uids); + idvec_clear (eff_gids); + idvec_clear (avail_gids); + + /* Now add some from a source we trust. */ + err = (*get_file_ids)(eff_uids, eff_gids); + + already_root = idvec_contains (eff_uids, 0); + if (suid && !err) + err = idvec_setid (eff_uids, avail_uids, uid, &_secure); + if (sgid && !err) + err = idvec_setid (eff_uids, avail_uids, gid, &_secure); + if (err) + goto abandon_suid; + + /* Trrrry again... */ + err = auth_makeauth (auth, 0, MACH_MSG_TYPE_COPY_SEND, 1, + eff_uids->ids, eff_uids->num, + avail_uids->ids, avail_uids->num, + eff_gids->ids, eff_gids->num, + avail_gids->ids, avail_gids->num, + &newauth); + } + + if (err) + goto abandon_suid; + + if (already_root) + _secure = 0; /* executive privilege */ + + /* Re-authenticate the exec parameters. */ + exec_reauth (newauth, _secure, 0, ports, num_ports, fds, num_fds); + + proc_setowner (ports[INIT_PORT_PROC], + eff_uids->num > 0 ? eff_uids->ids[0] : 0, + !eff_uids->num); + + abandon_suid: + if (eff_uids) + idvec_free (eff_uids); + if (avail_uids) + idvec_free (avail_uids); + if (eff_gids) + idvec_free (eff_gids); + if (avail_gids) + idvec_free (avail_gids); + } + + if (_secure && secure) + *secure = _secure; + + return err; +} diff --git a/libfshelp/fetch-control.c b/libfshelp/fetch-control.c new file mode 100644 index 00000000..26c12d88 --- /dev/null +++ b/libfshelp/fetch-control.c @@ -0,0 +1,31 @@ +/* + Copyright (C) 1995 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "fshelp.h" + +error_t +fshelp_fetch_control (struct transbox *box, + mach_port_t *control) +{ + *control = box->active; + if (*control != MACH_PORT_NULL) + mach_port_mod_refs (mach_task_self (), *control, MACH_PORT_RIGHT_SEND, 1); + return 0; +} diff --git a/libfshelp/fetch-root.c b/libfshelp/fetch-root.c new file mode 100644 index 00000000..c712286f --- /dev/null +++ b/libfshelp/fetch-root.c @@ -0,0 +1,193 @@ +/* + Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "trans.h" +#include <unistd.h> +#include <assert.h> +#include <string.h> +#include <hurd/fsys.h> + +error_t +fshelp_fetch_root (struct transbox *box, void *cookie, + file_t dotdot, + struct iouser *user, + int flags, + fshelp_fetch_root_callback1_t callback1, + fshelp_fetch_root_callback2_t callback2, + retry_type *retry, char *retryname, + file_t *root) +{ + error_t err; + mach_port_t control; + int cancel; + int i; + + start_over: + + if (box->active != MACH_PORT_NULL) + assert ((box->flags & TRANSBOX_STARTING) == 0); + else + { + uid_t uid, gid; + char *argz; + int argz_len; + error_t err; + mach_port_t ports[INIT_PORT_MAX]; + int ints[INIT_INT_MAX]; + mach_port_t fds[STDERR_FILENO + 1]; + auth_t ourauth, newauth; + + mach_port_t reauth (mach_port_t port) /* Consumes PORT. */ + { + mach_port_t rend, ret; + error_t err; + + if (port == MACH_PORT_NULL) + return port; + + if (ourauth == MACH_PORT_NULL) + /* We have no auth server, so we aren't doing reauthentications. + Just pass on our own ports directly. */ + return port; + + rend = mach_reply_port (); + + err = io_reauthenticate (port, rend, + MACH_MSG_TYPE_MAKE_SEND); + mach_port_deallocate (mach_task_self (), port); + if (! err) + err = auth_user_authenticate (newauth, rend, + MACH_MSG_TYPE_MAKE_SEND, &ret); + if (err) + ret = MACH_PORT_NULL; + + mach_port_destroy (mach_task_self (), rend); + + return ret; + } + error_t fetch_underlying (int flags, mach_port_t *underlying, + mach_msg_type_name_t *underlying_type) + { + return + (*callback2) (box->cookie, cookie, flags, + underlying, underlying_type); + } + + if (box->flags & TRANSBOX_STARTING) + { + box->flags |= TRANSBOX_WANTED; + cancel = hurd_condition_wait (&box->wakeup, box->lock); + if (cancel) + return EINTR; + goto start_over; + } + box->flags |= TRANSBOX_STARTING; + mutex_unlock (box->lock); + + err = (*callback1) (box->cookie, cookie, &uid, &gid, &argz, &argz_len); + if (err) + goto return_error; + + ourauth = getauth (); + if (ourauth == MACH_PORT_NULL) + newauth = ourauth; + else + { + uid_t uidarray[2] = { uid, uid }; + gid_t gidarray[2] = { gid, gid }; + err = auth_makeauth (ourauth, 0, MACH_MSG_TYPE_MAKE_SEND, 0, + uidarray, 1, uidarray, 2, + gidarray, 1, gidarray, 2, &newauth); + if (err) + goto return_error; + } + + bzero (ports, INIT_PORT_MAX * sizeof (mach_port_t)); + bzero (fds, (STDERR_FILENO + 1) * sizeof (mach_port_t)); + bzero (ints, INIT_INT_MAX * sizeof (int)); + + ports[INIT_PORT_CWDIR] = dotdot; + ports[INIT_PORT_CRDIR] = reauth (getcrdir ()); + ports[INIT_PORT_AUTH] = newauth; + + fds[STDERR_FILENO] = reauth (getdport (STDERR_FILENO)); + + err = fshelp_start_translator_long (fetch_underlying, + argz, argz, argz_len, + fds, MACH_MSG_TYPE_COPY_SEND, + STDERR_FILENO + 1, + ports, MACH_MSG_TYPE_COPY_SEND, + INIT_PORT_MAX, + ints, INIT_INT_MAX, + uid, + 0, &control); + for (i = 0; i <= STDERR_FILENO; i++) + mach_port_deallocate (mach_task_self (), fds[i]); + + for (i = 0; i < INIT_PORT_MAX; i++) + if (i != INIT_PORT_CWDIR) + mach_port_deallocate (mach_task_self (), ports[i]); + + mutex_lock (box->lock); + + free (argz); + + return_error: + + box->flags &= ~TRANSBOX_STARTING; + if (box->flags & TRANSBOX_WANTED) + { + box->flags &= ~TRANSBOX_WANTED; + condition_broadcast (&box->wakeup); + } + + if (err) + return err; + + if (! MACH_PORT_VALID (control)) + /* The start translator succeeded, but it returned a bogus port. */ + return EDIED; + + box->active = control; + } + + control = box->active; + mach_port_mod_refs (mach_task_self (), control, + MACH_PORT_RIGHT_SEND, 1); + mutex_unlock (box->lock); + + /* Cancellation point XXX */ + err = fsys_getroot (control, dotdot, MACH_MSG_TYPE_COPY_SEND, + user->uids->ids, user->uids->num, + user->gids->ids, user->gids->num, + flags, retry, retryname, root); + + mutex_lock (box->lock); + + if ((err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + && control == box->active) + fshelp_set_active (box, MACH_PORT_NULL, 0); + mach_port_deallocate (mach_task_self (), control); + + if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + goto start_over; + + return err; +} diff --git a/libfshelp/fshelp.h b/libfshelp/fshelp.h new file mode 100644 index 00000000..08622725 --- /dev/null +++ b/libfshelp/fshelp.h @@ -0,0 +1,263 @@ +/* FS helper library definitions + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _HURD_FSHELP_ +#define _HURD_FSHELP_ + +/* This library implements various things that are generic to + all or most implementors of the filesystem protocol. It + presumes that you are using the iohelp library as well. It + is divided into separate facilities which may be used independently. */ + +#include <errno.h> +#include <mach.h> +#include <hurd/hurd_types.h> +#include <cthreads.h> +#include <hurd/iohelp.h> +#include <sys/stat.h> +#include <maptime.h> + + +/* Passive translator linkage */ +/* These routines are self-contained and start passive translators, + returning the control port. They do not require multi threading + or the ports library. */ + +/* A callback used by the translator starting functions, which should be a + function that given some open flags, opens the appropiate file, and + returns the node port. */ +typedef error_t (*fshelp_open_fn_t) (int flags, + file_t *node, + mach_msg_type_name_t *node_type); + +/* Start a passive translator NAME with arguments ARGZ (length + ARGZ_LEN). Initialize the initports to PORTS (length PORTS_LEN), + the initints to INTS (length INTS_LEN), and the file descriptor + table to FDS (length FDS_LEN). Return the control port in + *CONTROL. If the translator doesn't respond or die in TIMEOUT + milliseconds (if TIMEOUT > 0), return an appropriate error. If the + translator dies before responding, return EDIED. Set the new + task's owner to OWNER_UID (or, if OWNER_UID is -1, then clear the + new task's owner. */ +error_t +fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn, + char *name, char *argz, int argz_len, + mach_port_t *fds, + mach_msg_type_name_t fds_type, int fds_len, + mach_port_t *ports, + mach_msg_type_name_t ports_type, int ports_len, + int *ints, int ints_len, + uid_t owner_uid, + int timeout, fsys_t *control); + + +/* Same as fshelp_start_translator_long, except the initports and ints + are copied from our own state, fd[2] is copied from our own stderr, + and the other fds are cleared. */ +error_t +fshelp_start_translator (fshelp_open_fn_t underlying_open_fn, + char *name, char *argz, int argz_len, + int timeout, fsys_t *control); + + +/* Active translator linkage */ + +/* These routines implement the linkage to active translators needed + by any filesystem which supports them. They require cthreads and + use the passive translator routines above, but they don't require + the ports library at all. */ + +struct transbox +{ + fsys_t active; + struct mutex *lock; + int flags; + struct condition wakeup; + void *cookie; +}; +#define TRANSBOX_STARTING 1 +#define TRANSBOX_WANTED 2 + +/* This interface is complex, because creating the ports and state + necessary for start_translator_long is expensive. The caller to + fshelp_fetch_root should not need to create them on every call, since + usually there will be an existing active translator. */ + +/* This routine is called by fshelp_fetch_root to fetch more information. + Return the owner and group of the underlying translated file in *UID and + *GID; point *ARGZ at the entire passive translator spec for the file + (setting *ARGZ_LEN to the length.) If there is no passive translator, + then return ENOENT. COOKIE1 is the cookie passed in fshelp_transbox_init. + COOKIE2 is the cookie passed in the call to fshelp_fetch_root. */ +typedef error_t (*fshelp_fetch_root_callback1_t) (void *cookie1, void *cookie2, + uid_t *uid, gid_t *gid, + char **argz, size_t *argz_len); + +/* This routine is called by fshelp_fetch_root to fetch more information. + Return an unauthenticated node for the file itself in *UNDERLYING and + *UNDERLYING_TYPE (opened with FLAGS). COOKIE1 is the cookie passed in + fshelp_transbox_init. COOKIE2 is the cookie passed in the call to + fshelp_fetch_root. */ +typedef error_t (*fshelp_fetch_root_callback2_t) (void *cookie1, void *cookie2, + int flags, + mach_port_t *underlying, + mach_msg_type_name_t + *underlying_type); + +/* Fetch the root from TRANSBOX. DOTDOT is an unauthenticated port + for the directory in which we are looking; USER specifies the ids + of the user responsible for the call. FLAGS are as for + dir_pathtrans (but O_CREAT and O_EXCL are not meaningful and are + ignored). The trasnbox lock (as set by fshelp_transbox_init) must + be held before the call, and will be held upon return, but may be + released during the operation of the call. */ +error_t +fshelp_fetch_root (struct transbox *transbox, void *cookie, + file_t dotdot, + struct iouser *user, + int flags, + fshelp_fetch_root_callback1_t callback1, + fshelp_fetch_root_callback2_t callback2, + retry_type *retry, char *retryname, mach_port_t *root); + +void +fshelp_transbox_init (struct transbox *transbox, + struct mutex *lock, + void *cookie); + +/* Return true iff there is an active translator on this box */ +int fshelp_translated (struct transbox *box); + +/* Atomically replace the existing active translator port for this box + with NEWACTIVE. If EXCL is non-zero then don't frob an existing + active; return EBUSY instead. */ +error_t fshelp_set_active (struct transbox *box, + fsys_t newactive, int excl); + +/* Fetch the control port to make a request on it. It's a bad idea + to do fsys_getroot with the result; use fetch_root instead. */ +error_t fshelp_fetch_control (struct transbox *box, + mach_port_t *control); + +/* A transbox is being deallocated, clean associated state. */ +void fshelp_drop_transbox (struct transbox *box); + + + +/* Flock handling. */ +struct lock_box +{ + int type; + struct condition wait; + int waiting; + int shcount; +}; + +/* Call when a user makes a request to acquire an lock via file_lock. + There should be one lock box per object and one int per open; these + are passed as arguments BOX and USER respectively. FLAGS are as + per file_lock. MUT is a mutex which will be held whenever this + routine is called, to lock BOX->wait. */ +error_t fshelp_acquire_lock (struct lock_box *box, int *user, + struct mutex *mut, int flags); + + +/* Initialize lock_box BOX. (The user int passed to fshelp_acquire_lock + should be initialized with LOCK_UN.). */ +void fshelp_lock_init (struct lock_box *box); + + + +struct port_bucket; /* shut up C compiler */ +/* Return an identity port in *PT for the node numbered FILENO, + suitable for returning from io_identity; exactly one send right + must be created from the returned value. FILENO should be the same + value returned as the `fileno' out-parameter in io_identity, and in + the enclosing directory (except for mount points), and in the + st_ino stat field. BUCKET should be a ports port bucket; fshelp + requires the caller to make sure port operations (for no-senders + notifications) are used. + */ +error_t fshelp_get_identity (struct port_bucket *bucket, + ino_t fileno, mach_port_t *pt); + + + +/* Try to hand off responsibility from a translator to the server located on + the node SERVER_NAME. REQUESTOR is the translator's bootstrap port, and + ARGV is the command line. If SERVER_NAME is NULL, then a name is + concocted by appending ARGV[0] to _SERVERS. */ +error_t fshelp_delegate_translation (char *server_name, + mach_port_t requestor, char **argv); + +struct idvec; /* Include <idvec.h> to get the real thing. */ + +/* If SUID or SGID is true, adds UID and/or GID respectively to the + authentication in PORTS[INIT_PORT_AUTH], and replaces it with the result. + All the other ports in PORTS and FDS are then reauthenticated, using any + privileges available through AUTH. If GET_FILE_IDS is non-NULL, and the + auth port in PORTS[INIT_PORT_AUTH] is bogus, it is called to get a list of + uids and gids from the file to use as a replacement. If SECURE is + non-NULL, whether not the added ids are new is returned in it. If either + the uid or gid case fails, then the other may still be applied. */ +error_t +fshelp_exec_reauth (int suid, uid_t uid, int sgid, gid_t gid, + auth_t auth, + error_t + (*get_file_ids)(struct idvec *uids, struct idvec *gids), + mach_port_t *ports, mach_msg_type_number_t num_ports, + mach_port_t *fds, mach_msg_type_number_t num_fds, + int *secure); + +struct argp; /* Include <argp.h> to get the real thing. */ + +/* Invoke ARGP with data from DATA & LEN, in the standard way. */ +error_t fshelp_set_options (struct argp *argp, int flags, + const char *argz, size_t argz_len, void *input); + + +/* Standardized filesystem permission checking */ + +/* Check to see whether USER should be considered the owner of the + file identified by ST. If so, return zero; otherwise return an + appropriate error code. */ +error_t fshelp_isowner (struct stat *st, struct iouser *user); + +/* Check to see whether the user USER can operate on a file identified + by ST. OP is one of S_IREAD, S_IWRITE, and S_IEXEC. If the access + is permitted, return zero; otherwise return an appropriate error + code. */ +error_t fshelp_access (struct stat *st, int op, struct iouser *user); + +/* Check to see whether USER is allowed to modify DIR with respect to + existing file ST. (If there is no existing file, pass 0 for ST.) + If the access is permissable return 0; otherwise return an + appropriate error code. */ +error_t fshelp_checkdirmod (struct stat *dir, struct stat *st, + struct iouser *user); + + +/* Timestamps to change. */ +#define TOUCH_ATIME 0x1 +#define TOUCH_MTIME 0x2 +#define TOUCH_CTIME 0x4 + +/* Change the stat times of NODE as indicated by WHAT (from the set TOUCH_*) + to the current time. */ +void fshelp_touch (struct stat *st, unsigned what, + volatile struct mapped_time_value *maptime); +#endif diff --git a/libfshelp/get-identity.c b/libfshelp/get-identity.c new file mode 100644 index 00000000..51c5fb29 --- /dev/null +++ b/libfshelp/get-identity.c @@ -0,0 +1,88 @@ +/* Helper function for io_identity + Copyright (C) 1996, 1999 Free Software Foundation, Inc. + Written by Michael I. Bushnell, p/BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + + +#include <fshelp.h> +#include <hurd/ports.h> +#include <assert.h> + +static struct port_class *idclass = 0; +static struct mutex idlock = MUTEX_INITIALIZER; + +struct idspec +{ + struct port_info pi; + ino_t fileno; +}; + +static void +id_initialize () +{ + assert (!idclass); + idclass = ports_create_class (0, 0); +} + +error_t +fshelp_get_identity (struct port_bucket *bucket, + ino_t fileno, + mach_port_t *pt) +{ + struct idspec *i; + error_t err = 0; + + error_t check_port (void *arg) + { + struct idspec *i = arg; + if (i->fileno == fileno) + { + *pt = ports_get_right (i); + return 1; + } + else + return 0; + } + + mutex_lock (&idlock); + if (!idclass) + id_initialize (); + + *pt = MACH_PORT_NULL; + + ports_class_iterate (idclass, check_port); + + if (*pt != MACH_PORT_NULL) + { + mutex_unlock (&idlock); + return 0; + } + + err = ports_create_port (idclass, bucket, sizeof (struct idspec), &i); + if (err) + { + mutex_unlock (&idlock); + return err; + } + i->fileno = fileno; + + *pt = ports_get_right (i); + ports_port_deref (i); + mutex_unlock (&idlock); + return 0; +} diff --git a/libfshelp/lock-acquire.c b/libfshelp/lock-acquire.c new file mode 100644 index 00000000..3d8df550 --- /dev/null +++ b/libfshelp/lock-acquire.c @@ -0,0 +1,134 @@ +/* + Copyright (C) 1993, 1994, 1996 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +#include "locks.h" + +#define EWOULDBLOCK EAGAIN /* XXX */ + +error_t +fshelp_acquire_lock (struct lock_box *box, int *user, struct mutex *mut, + int flags) +{ + if (!(flags & (LOCK_UN | LOCK_EX | LOCK_SH))) + return 0; + + if ((flags & LOCK_UN) + && (flags & (LOCK_SH | LOCK_EX))) + return EINVAL; + + if (flags & LOCK_EX) + flags &= ~LOCK_SH; + + /* flags now contains exactly one of LOCK_UN, LOCK_SH, or LOCK_EX. */ + + if (flags & LOCK_UN) + { + if (*user & LOCK_UN) + return 0; + + assert (*user == box->type); + assert (*user == LOCK_SH || *user == LOCK_EX); + + if (*user == LOCK_SH) + { + if (!--box->shcount) + box->type = LOCK_UN; + } + else if (*user == LOCK_EX) + box->type = LOCK_UN; + + if (box->type == LOCK_UN && box->waiting) + { + box->waiting = 0; + condition_broadcast (&box->wait); + } + *user = LOCK_UN; + } + else + { + /* If we have an exclusive lock, release it. */ + if (*user == LOCK_EX) + { + *user = LOCK_UN; + box->type = LOCK_UN; + if (box->waiting) + { + box->waiting = 0; + condition_broadcast (&box->wait); + } + } + + /* If there is an exclusive lock, wait for it to end. */ + while (box->type == LOCK_EX) + { + if (flags & LOCK_NB) + return EWOULDBLOCK; + box->waiting = 1; + if (hurd_condition_wait (&box->wait, mut)) + return EINTR; + } + + /* If we have a shared lock, release it. */ + if (*user == LOCK_SH) + { + *user = LOCK_UN; + if (!--box->shcount) + { + box->type = LOCK_UN; + if (box->waiting) + { + box->waiting = 0; + condition_broadcast (&box->wait); + } + } + } + + assert ((flags & LOCK_SH) || (flags & LOCK_EX)); + if (flags & LOCK_SH) + { + assert (box->type != LOCK_EX); + *user = LOCK_SH; + box->type = LOCK_SH; + box->shcount++; + } + else if (flags & LOCK_EX) + { + /* Wait for any shared locks to finish. */ + while (box->type == LOCK_SH) + { + if (flags & LOCK_NB) + return EWOULDBLOCK; + else + { + box->waiting = 1; + if (hurd_condition_wait (&box->wait, mut)) + return EINTR; + } + } + box->type = LOCK_EX; + *user = LOCK_EX; + } + } + return 0; +} + + + diff --git a/libfshelp/lock-init.c b/libfshelp/lock-init.c new file mode 100644 index 00000000..4b1da97e --- /dev/null +++ b/libfshelp/lock-init.c @@ -0,0 +1,32 @@ +/* + Copyright (C) 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +#include "locks.h" + +/* Initialize a lock box. */ +void +fshelp_lock_init (struct lock_box *box) +{ + box->type = LOCK_UN; + condition_init (&box->wait); + box->waiting = 0; + box->shcount = 0; +} diff --git a/libfshelp/locks.h b/libfshelp/locks.h new file mode 100644 index 00000000..dcecf5d9 --- /dev/null +++ b/libfshelp/locks.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +#include <mach.h> +#include <hurd.h> +#include <cthreads.h> +#include <hurd/ports.h> +#include "fshelp.h" +#include <sys/file.h> +#include <assert.h> diff --git a/libfshelp/perms-access.c b/libfshelp/perms-access.c new file mode 100644 index 00000000..91ad9da8 --- /dev/null +++ b/libfshelp/perms-access.c @@ -0,0 +1,43 @@ +/* + Copyright (C) 1999 Free Software Foundation, Inc. + Written by Thomas Bushnell, BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + + +#include "fshelp.h" + +/* Check to see whether the user USER can operate on a file identified + by ST. OP is one of S_IREAD, S_IWRITE, and S_IEXEC. If the access + is permitted, return zero; otherwise return an appropriate error + code. */ +error_t +fshelp_access (struct stat *st, int op, struct iouser *user) +{ + int gotit; + if (idvec_contains (user->uids, 0)) + gotit = 1; + else if (user->uids->num == 0 && (st->st_mode & S_IUSEUNK)) + gotit = st->st_mode & (op << S_IUNKSHIFT); + else if (!fshelp_isowner (st, user)) + gotit = st->st_mode & op; + else if (idvec_contains (user->gids, st->st_gid)) + gotit = st->st_mode & (op >> 3); + else + gotit = st->st_mode & (op >> 6); + return gotit ? 0 : EACCES; +} diff --git a/libfshelp/perms-checkdirmod.c b/libfshelp/perms-checkdirmod.c new file mode 100644 index 00000000..db4b2e43 --- /dev/null +++ b/libfshelp/perms-checkdirmod.c @@ -0,0 +1,44 @@ +/* + Copyright (C) 1999 Free Software Foundation, Inc. + Written by Thomas Bushnell, BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + + +#include "fshelp.h" + +/* Check to see whether USER is allowed to modify DIR with respect to + existing file ST. (If there is no existing file, pass 0 for ST.) + If the access is permissable return 0; otherwise return an + appropriate error code. */ +error_t +fshelp_checkdirmod (struct stat *dir, struct stat *st, struct iouser *user) +{ + error_t err; + + /* The user must be able to write the directory. */ + err = fshelp_access (dir, S_IWRITE, user); + if (err) + return err; + + /* If the directory is sticky, the user must own either it or the file. */ + if ((dir->st_mode & S_ISVTX) && st + && fshelp_isowner (dir, user) && fshelp_isowner (st, user)) + return EACCES; + + return 0; +} diff --git a/libfshelp/perms-isowner.c b/libfshelp/perms-isowner.c new file mode 100644 index 00000000..d1975993 --- /dev/null +++ b/libfshelp/perms-isowner.c @@ -0,0 +1,39 @@ +/* + Copyright (C) 1999 Free Software Foundation, Inc. + Written by Thomas Bushnell, BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "fshelp.h" + +/* Check to see whether USER should be considered the owner of the + file identified by ST. If so, return zero; otherwise return an + appropriate error code. */ +error_t +fshelp_isowner (struct stat *st, struct iouser *user) +{ + /* Permitted if the user has the owner UID, the superuser UID, or if + the user is in the group of the file and has the group ID as + their user ID. */ + if (idvec_contains (user->uids, st->st_uid) + || idvec_contains (user->uids, 0) + || (idvec_contains (user->gids, st->st_gid) + && idvec_contains (user->uids, st->st_gid))) + return 0; + else + return EPERM; +} diff --git a/libfshelp/set-active.c b/libfshelp/set-active.c new file mode 100644 index 00000000..4f25a50e --- /dev/null +++ b/libfshelp/set-active.c @@ -0,0 +1,63 @@ +/* + Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "fshelp.h" +#include <hurd/fsys.h> + +error_t +fshelp_set_active (struct transbox *box, + mach_port_t active, + int excl) +{ + int cancel; + + if (excl) + { + if (box->flags & TRANSBOX_STARTING) + return EBUSY; + if (box->active != MACH_PORT_NULL) + /* It looks like there's an existing translator, but make sure. */ + { + mach_port_urefs_t dead_refs; + error_t err = + mach_port_get_refs (mach_task_self (), + box->active, MACH_PORT_RIGHT_DEAD_NAME, + &dead_refs); + if (!err && dead_refs == 0) + /* Still active, we lose. */ + return EBUSY; + } + } + + while (box->flags & TRANSBOX_STARTING) + { + box->flags |= TRANSBOX_WANTED; + cancel = hurd_condition_wait (&box->wakeup, box->lock); + if (cancel) + return EINTR; + } + + if (box->active != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), box->active); + + box->active = active; + return 0; +} + diff --git a/libfshelp/set-options.c b/libfshelp/set-options.c new file mode 100644 index 00000000..13e4001f --- /dev/null +++ b/libfshelp/set-options.c @@ -0,0 +1,46 @@ +/* Standard filesystem runtime option parsing + + Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc. + + Written by Miles Bader <miles@gnu.ai.mit.edu> + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <argp.h> +#include <argz.h> + +#include "fshelp.h" + +/* XXX this is not currently so useful, but the new fsys_set_options will + have more commonly used code that can be put here. */ + +/* Invoke ARGP with data from DATA & LEN, in the standard way. */ +error_t +fshelp_set_options (struct argp *argp, int flags, + const char *argz, size_t argz_len, void *input) +{ + int argc = argz_count (argz, argz_len); + char **argv = alloca (sizeof (char *) * (argc + 1)); + + argz_extract ((char *) argz, argz_len, argv); + + return + argp_parse (argp, argc, argv, + flags | ARGP_NO_ERRS | ARGP_NO_HELP | ARGP_PARSE_ARGV0, + 0, input); +} diff --git a/libfshelp/start-translator-long.c b/libfshelp/start-translator-long.c new file mode 100644 index 00000000..bf576035 --- /dev/null +++ b/libfshelp/start-translator-long.c @@ -0,0 +1,296 @@ +/* + Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + Written by Miles Bader and Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <hurd.h> +#include <mach/notify.h> +#include <mach.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <assert.h> +#include "fshelp.h" + + +/* The data passed in the various messages we're interested in. */ +struct fsys_startup_request +{ + mach_msg_header_t head; + mach_msg_type_t flagsType; + int flags; + mach_msg_type_t control_portType; + mach_port_t control_port; +}; + +struct fsys_startup_reply +{ + mach_msg_header_t head; + mach_msg_type_t RetCodeType; + kern_return_t RetCode; + mach_msg_type_t realnodeType; + mach_port_t realnode; +}; + +static const mach_msg_type_t flagsCheck = { + MACH_MSG_TYPE_INTEGER_32, /* msgt_name = */ + 32, /* msgt_size = */ + 1, /* msgt_number = */ + TRUE, /* msgt_inline = */ + FALSE, /* msgt_longform = */ + FALSE, /* msgt_deallocate = */ + 0 /* msgt_unused = */ +}; + +static const mach_msg_type_t control_portCheck = +{ + 17, /* msgt_name = */ + 32, /* msgt_size = */ + 1, /* msgt_number = */ + TRUE, /* msgt_inline = */ + FALSE, /* msgt_longform = */ + FALSE, /* msgt_deallocate = */ + 0 /* msgt_unused = */ +}; + +static const mach_msg_type_t RetCodeType = { + MACH_MSG_TYPE_INTEGER_32, /* msgt_name = */ + 32, /* msgt_size = */ + 1, /* msgt_number = */ + TRUE, /* msgt_inline = */ + FALSE, /* msgt_longform = */ + FALSE, /* msgt_deallocate = */ + 0 /* msgt_unused = */ +}; + +static const mach_msg_type_t realnodeType = +{ + -1, /* msgt_name = */ + 32, /* msgt_size = */ + 1, /* msgt_number = */ + TRUE, /* msgt_inline = */ + FALSE, /* msgt_longform = */ + FALSE, /* msgt_deallocate = */ + 0 /* msgt_unused = */ +}; + + +/* Wait around for an fsys_startup message on the port PORT from the + translator on NODE (timing out after TIMEOUT milliseconds), and return a + send right for the resulting fsys control port in CONTROL. If a no-senders + notification is received on PORT, then it will be assumed that the + translator died, and EDIED will be returned. If an error occurs, the + error code is returned, otherwise 0. */ +static error_t +service_fsys_startup (fshelp_open_fn_t underlying_open_fn, + mach_port_t port, long timeout, + fsys_t *control) +{ + error_t err; + union + { + mach_msg_header_t head; + struct fsys_startup_request startup; + } + request; + struct fsys_startup_reply reply; + + /* Wait for the fsys_startup message... */ + err = mach_msg (&request.head, (MACH_RCV_MSG | MACH_RCV_INTERRUPT + | (timeout ? MACH_RCV_TIMEOUT : 0)), + 0, sizeof(request), port, timeout, MACH_PORT_NULL); + if (err) + return err; + + /* Check whether we actually got a no-senders notification instead. */ + if (request.head.msgh_id == MACH_NOTIFY_NO_SENDERS) + return EDIED; + + /* Construct our reply to the fsys_startup rpc. */ + reply.head.msgh_size = sizeof(reply); + reply.head.msgh_bits = + MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request.head.msgh_bits), 0); + reply.head.msgh_remote_port = request.head.msgh_remote_port; + reply.head.msgh_local_port = MACH_PORT_NULL; + reply.head.msgh_seqno = 0; + reply.head.msgh_id = request.head.msgh_id + 100; + reply.RetCodeType = RetCodeType; + + if (request.head.msgh_id != 22000) + reply.RetCode = MIG_BAD_ID; + else if ((*(int *)&request.startup.control_portType + != *(int *)&control_portCheck) + || (*(int *)&request.startup.flagsType != *(int *)&flagsCheck)) + reply.RetCode = MIG_BAD_ARGUMENTS; + else + { + mach_msg_type_name_t realnode_type; + + *control = request.startup.control_port; + + reply.RetCode = + (*underlying_open_fn) (request.startup.flags, + &reply.realnode, &realnode_type); + + reply.realnodeType = realnodeType; + reply.realnodeType.msgt_name = realnode_type; + + if (!reply.RetCode && reply.realnode != MACH_PORT_NULL) + /* The message can't be simple because of the port. */ + reply.head.msgh_bits |= MACH_MSGH_BITS_COMPLEX; + } + + err = mach_msg (&reply.head, MACH_SEND_MSG | MACH_SEND_INTERRUPT, + sizeof(reply), 0, + request.head.msgh_remote_port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + + if (reply.RetCode) + /* Make our error return be the earlier one. */ + err = reply.RetCode; + + return err; +} + + +error_t +fshelp_start_translator_long (fshelp_open_fn_t underlying_open_fn, + char *name, char *argz, int argz_len, + mach_port_t *fds, + mach_msg_type_name_t fds_type, int fds_len, + mach_port_t *ports, + mach_msg_type_name_t ports_type, int ports_len, + int *ints, int ints_len, + uid_t owner_uid, + int timeout, fsys_t *control) +{ + error_t err; + file_t executable; + mach_port_t bootstrap = MACH_PORT_NULL; + mach_port_t task = MACH_PORT_NULL; + mach_port_t prev_notify, proc, saveport, childproc; + int ports_moved = 0; + + /* Find the translator itself. Since argz has zero-separated elements, we + can use it as a normal string representing the first element. */ + executable = file_name_lookup(name, O_EXEC, 0); + if (executable == MACH_PORT_NULL) + return errno; + + /* Create a bootstrap port for the translator. */ + err = + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &bootstrap); + if (err) + goto lose; + + /* Create the task for the translator. */ + err = task_create (mach_task_self (), 0, &task); + if (err) + goto lose; + + /* Designate TASK as our child and set it's owner accordingly. */ + proc = getproc (); + proc_child (proc, task); + err = proc_task2proc (proc, task, &childproc); + mach_port_deallocate (mach_task_self (), proc); + if (err) + goto lose; + err = proc_setowner (childproc, owner_uid, owner_uid == (uid_t) -1); + mach_port_deallocate (mach_task_self (), childproc); + if (err) + goto lose; + + assert (ports_len > INIT_PORT_BOOTSTRAP); + switch (ports_type) + { + case MACH_MSG_TYPE_MAKE_SEND: + case MACH_MSG_TYPE_MAKE_SEND_ONCE: + break; + + case MACH_MSG_TYPE_MOVE_SEND: + if (ports[INIT_PORT_BOOTSTRAP] != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), ports[INIT_PORT_BOOTSTRAP]); + mach_port_insert_right (mach_task_self (), bootstrap, bootstrap, + MACH_MSG_TYPE_MAKE_SEND); + break; + + case MACH_MSG_TYPE_COPY_SEND: + mach_port_insert_right (mach_task_self (), bootstrap, bootstrap, + MACH_MSG_TYPE_MAKE_SEND); + break; + + default: + abort (); + } + + saveport = ports[INIT_PORT_BOOTSTRAP]; + ports[INIT_PORT_BOOTSTRAP] = bootstrap; + + /* Try and exec the translator in TASK... */ + err = file_exec (executable, task, EXEC_DEFAULTS, + argz, argz_len, 0, 0, + fds, fds_type, fds_len, + ports, ports_type, ports_len, + ints, ints_len, 0, 0, 0, 0); + ports_moved = 1; + + if (ports_type == MACH_MSG_TYPE_COPY_SEND) + mach_port_deallocate (mach_task_self (), bootstrap); + ports[INIT_PORT_BOOTSTRAP] = saveport; + + if (err) + { + task_terminate (task); + goto lose; + } + + /* Ask to be told if TASK dies. */ + err = + mach_port_request_notification(mach_task_self(), + bootstrap, MACH_NOTIFY_NO_SENDERS, 0, + bootstrap, MACH_MSG_TYPE_MAKE_SEND_ONCE, + &prev_notify); + if (err) + return err; + + /* Ok, cool, we've got a running(?) program, now rendezvous with it if + possible using the startup protocol on the bootstrap port... */ + err = service_fsys_startup(underlying_open_fn, bootstrap, timeout, control); + + lose: + if (!ports_moved) + { + int i; + + if (fds_type == MACH_MSG_TYPE_MOVE_SEND) + for (i = 0; i < fds_len; i++) + mach_port_deallocate (mach_task_self (), fds[i]); + if (ports_type == MACH_MSG_TYPE_MOVE_SEND) + for (i = 0; i < ports_len; i++) + mach_port_deallocate (mach_task_self (), ports[i]); + } + if (bootstrap != MACH_PORT_NULL) + mach_port_destroy(mach_task_self(), bootstrap); + if (executable != MACH_PORT_NULL) + mach_port_deallocate(mach_task_self(), executable); + if (task != MACH_PORT_NULL) + mach_port_deallocate(mach_task_self(), task); + + return err; +} diff --git a/libfshelp/start-translator.c b/libfshelp/start-translator.c new file mode 100644 index 00000000..5996ac74 --- /dev/null +++ b/libfshelp/start-translator.c @@ -0,0 +1,63 @@ +/* + Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "fshelp.h" +#include <unistd.h> +#include <string.h> +#include <hurd.h> + +error_t +fshelp_start_translator (fshelp_open_fn_t underlying_open_fn, + char *name, char *argz, int argz_len, + int timeout, fsys_t *control) +{ + mach_port_t ports[INIT_PORT_MAX]; + mach_port_t fds[STDERR_FILENO + 1]; + int ints[INIT_INT_MAX]; + int i; + error_t err; + + for (i = 0; i < INIT_PORT_MAX; i++) + ports[i] = MACH_PORT_NULL; + for (i = 0; i < STDERR_FILENO + 1; i++) + fds[i] = MACH_PORT_NULL; + bzero (ints, INIT_INT_MAX * sizeof (int)); + + ports[INIT_PORT_CWDIR] = getcwdir (); + ports[INIT_PORT_CRDIR] = getcrdir (); + ports[INIT_PORT_AUTH] = getauth (); + fds[STDERR_FILENO] = getdport (STDERR_FILENO); + + err = fshelp_start_translator_long (underlying_open_fn, + name, argz, argz_len, + fds, MACH_MSG_TYPE_COPY_SEND, + STDERR_FILENO + 1, + ports, MACH_MSG_TYPE_COPY_SEND, + INIT_PORT_MAX, + ints, INIT_INT_MAX, + geteuid (), + timeout, control); + for (i = 0; i < INIT_PORT_MAX; i++) + mach_port_deallocate (mach_task_self (), ports[i]); + for (i = 0; i <= STDERR_FILENO; i++) + mach_port_deallocate (mach_task_self (), fds[i]); + + return err; +} diff --git a/libfshelp/touch.c b/libfshelp/touch.c new file mode 100644 index 00000000..c254bfbf --- /dev/null +++ b/libfshelp/touch.c @@ -0,0 +1,48 @@ +/* + Copyright (C) 1999 Free Software Foundation, Inc. + Written by Thomas Bushnell, BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "fshelp.h" + +/* Change the stat times of NODE as indicated by WHAT (from the set TOUCH_*) + to the current time. */ +void +fshelp_touch (struct stat *st, unsigned what, + volatile struct mapped_time_value *maptime) +{ + struct timeval tv; + + maptime_read (maptime, &tv); + + if (what & TOUCH_ATIME) + { + st->st_atime = tv.tv_sec; + st->st_atime_usec = tv.tv_usec; + } + if (what & TOUCH_CTIME) + { + st->st_ctime = tv.tv_sec; + st->st_ctime_usec = tv.tv_usec; + } + if (what & TOUCH_MTIME) + { + st->st_mtime = tv.tv_sec; + st->st_mtime_usec = tv.tv_usec; + } +} diff --git a/libfshelp/trans.h b/libfshelp/trans.h new file mode 100644 index 00000000..b2416453 --- /dev/null +++ b/libfshelp/trans.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <hurd.h> +#include <cthreads.h> +#include <hurd/ports.h> +#include "fshelp.h" + +struct transboot +{ + struct port_info pi; + file_t node; + struct trans_link *link; +}; + +spin_lock_t _fshelp_translistlock; +struct trans_link *_fshelp_translist; diff --git a/libfshelp/transbox-init.c b/libfshelp/transbox-init.c new file mode 100644 index 00000000..1945a57d --- /dev/null +++ b/libfshelp/transbox-init.c @@ -0,0 +1,35 @@ +/* + Copyright (C) 1995 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "fshelp.h" +#include <cthreads.h> + +void +fshelp_transbox_init (struct transbox *transbox, + struct mutex *lock, + void *cookie) +{ + transbox->active = MACH_PORT_NULL; + transbox->flags = 0; + transbox->lock = lock; + condition_init (&transbox->wakeup); + transbox->cookie = cookie; +} + diff --git a/libfshelp/translated.c b/libfshelp/translated.c new file mode 100644 index 00000000..2dc724b6 --- /dev/null +++ b/libfshelp/translated.c @@ -0,0 +1,28 @@ +/* + Copyright (C) 1999 Free Software Foundation, Inc. + Written by Thomas Bushnell, BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include "fshelp.h" + +/* Return true iff there is an active translator on this box */ +int +fshelp_translated (struct transbox *box) +{ + return (box->active != MACH_PORT_NULL); +} |