diff options
Diffstat (limited to 'libnetfs/file-exec.c')
-rw-r--r-- | libnetfs/file-exec.c | 92 |
1 files changed, 51 insertions, 41 deletions
diff --git a/libnetfs/file-exec.c b/libnetfs/file-exec.c index 7268e7c7..73c125ba 100644 --- a/libnetfs/file-exec.c +++ b/libnetfs/file-exec.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. +/* + Copyright (C) 1996,97,2000,01,02 Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -24,30 +24,30 @@ #include "execserver.h" #include "fs_S.h" #include <sys/stat.h> -#include <fcntlbits.h> +#include <fcntl.h> #include <hurd/exec.h> #include <hurd/paths.h> #include <string.h> #include <idvec.h> -kern_return_t +kern_return_t netfs_S_file_exec (struct protid *cred, task_t task, int flags, char *argv, - u_int argvlen, + size_t argvlen, char *envp, - u_int envplen, + size_t envplen, mach_port_t *fds, - u_int fdslen, + size_t fdslen, mach_port_t *portarray, - u_int portarraylen, + size_t portarraylen, int *intarray, - u_int intarraylen, + size_t intarraylen, mach_port_t *deallocnames, - u_int deallocnameslen, + size_t deallocnameslen, mach_port_t *destroynames, - u_int destroynameslen) + size_t destroynameslen) { struct node *np; error_t err; @@ -55,7 +55,8 @@ netfs_S_file_exec (struct protid *cred, gid_t gid; mode_t mode; int suid, sgid; - + mach_port_t right; + if (!cred) return EOPNOTSUPP; @@ -66,23 +67,23 @@ netfs_S_file_exec (struct protid *cred, if ((cred->po->openstat & O_EXEC) == 0) return EBADF; - + np = cred->po->np; mutex_lock (&np->lock); mode = np->nn_stat.st_mode; uid = np->nn_stat.st_uid; gid = np->nn_stat.st_gid; - err = netfs_validate_stat (np, cred->credential); + err = netfs_validate_stat (np, cred->user); mutex_unlock (&np->lock); if (err) return err; - + if (!((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) || ((mode & S_IUSEUNK) && (mode & (S_IEXEC << S_IUNKSHIFT))))) return EACCES; - + if ((mode & S_IFMT) == S_IFDIR) return EACCES; @@ -94,20 +95,14 @@ netfs_S_file_exec (struct protid *cred, error_t get_file_ids (struct idvec *uidsvec, struct idvec *gidsvec) { error_t err; - uid_t *uids, *gids; - int nuids, ngids; - netfs_interpret_credential (cred->credential, &uids, &nuids, - &gids, &ngids); - - err = idvec_merge_ids (uidsvec, uids, nuids); + err = idvec_merge (uidsvec, cred->user->uids); if (! err) - err = idvec_merge_ids (gidsvec, gids, ngids); - free (uids); - free (gids); + err = idvec_merge (gidsvec, cred->user->gids); + return err; } - err = + err = fshelp_exec_reauth (suid, uid, sgid, gid, netfs_auth_server_port, get_file_ids, portarray, portarraylen, fds, fdslen, &secure); @@ -127,25 +122,40 @@ netfs_S_file_exec (struct protid *cred, if (! err) { - struct protid *newpi = - netfs_make_protid (netfs_make_peropen (np, O_READ, - cred->po->dotdotport), - netfs_copy_credential (cred->credential)); - err = exec_exec (_netfs_exec, - ports_get_right (newpi), - MACH_MSG_TYPE_MAKE_SEND, - task, flags, argv, argvlen, envp, envplen, - fds, MACH_MSG_TYPE_COPY_SEND, fdslen, - portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen, - intarray, intarraylen, deallocnames, deallocnameslen, - destroynames, destroynameslen); - ports_port_deref (newpi); + struct iouser *user; + struct protid *newpi; + + err = iohelp_dup_iouser (&user, cred->user); + if (! err) + { + newpi = netfs_make_protid (netfs_make_peropen (np, O_READ, cred->po), + user); + if (newpi) + { + right = ports_get_send_right (newpi); + err = exec_exec (_netfs_exec, + right, MACH_MSG_TYPE_COPY_SEND, + task, flags, argv, argvlen, envp, envplen, + fds, MACH_MSG_TYPE_COPY_SEND, fdslen, + portarray, MACH_MSG_TYPE_COPY_SEND, portarraylen, + intarray, intarraylen, + deallocnames, deallocnameslen, + destroynames, destroynameslen); + mach_port_deallocate (mach_task_self (), right); + ports_port_deref (newpi); + } + else + { + err = errno; + iohelp_free_iouser (user); + } + } } if (! err) { unsigned int i; - + mach_port_deallocate (mach_task_self (), task); for (i = 0; i < fdslen; i++) mach_port_deallocate (mach_task_self (), fds[i]); @@ -153,5 +163,5 @@ netfs_S_file_exec (struct protid *cred, mach_port_deallocate (mach_task_self (), portarray[i]); } - return err; + return err; } |