diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-03-21 21:23:07 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-03-21 21:23:07 +0000 |
commit | cc49768adfaf3bdbbbd204c3f91efe931b44360b (patch) | |
tree | 3ed28de61bec6d8d91a5518ba43987a1e2c6eec5 /libdiskfs/file-exec.c | |
parent | 7876f3b04c8272994af056e00f9e770053f37b8c (diff) |
Formerly file-exec.c.~2~
Diffstat (limited to 'libdiskfs/file-exec.c')
-rw-r--r-- | libdiskfs/file-exec.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/libdiskfs/file-exec.c b/libdiskfs/file-exec.c index d480d00f..0b566be7 100644 --- a/libdiskfs/file-exec.c +++ b/libdiskfs/file-exec.c @@ -21,6 +21,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "priv.h" #include "fs_S.h" +#include <sys/stat.h> +#include <fcntlbits.h> +#include <hurd/exec.h> error_t diskfs_S_file_exec (struct protid *cred, @@ -41,5 +44,41 @@ diskfs_S_file_exec (struct protid *cred, mach_port_t *destroynames, u_int destroynameslen) { - return EOPNOTSUPP; + struct node *np; + error_t err; + + if (!cred) + return EOPNOTSUPP; + + np = cred->po->np; + if (err = diskfs_access (np, S_IEXEC, cred)) + return err; + if (!((np->dn_stat.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) + || ((np->dn_stat.st_mode & S_IUSEUNK) + && (np->dn_stat.st_mode & (S_IEXEC << S_IUNKSHIFT))))) + return EACCES; + + /* Handle S_ISUID and S_ISGID uid substitution. */ + /* XXX We should change the auth handle here too. */ + if (((np->dn_stat.st_mode & S_ISUID) + && !diskfs_isuid (np->dn_stat.st_uid, cred)) + || ((np->dn_stat.st_mode & S_ISGID) + && !diskfs_groupmember (np->dn_stat.st_gid, cred))) + flags |= EXEC_SECURE|EXEC_NEWTASK; + + if (diskfs_access (np, S_IREAD, cred)) + flags |= EXEC_NEWTASK; + + err = exec_exec (diskfs_exec, + (ports_get_right + (diskfs_make_protid + (diskfs_make_peropen (np, O_READ), + cred->uids, cred->nuids, cred->gids, cred->ngids))), + task, flags, argv, argvlen, envp, envplen, + fds, MACH_MSG_TYPE_MOVE_SEND, fdslen, + portarray, MACH_MSG_TYPE_MOVE_SEND, portarraylen, + intarray, intarraylen, deallocnames, deallocnameslen, + destroynames, destroynameslen); + mach_port_deallocate (mach_task_self (), task); + return err; } |