summaryrefslogtreecommitdiff
path: root/libdiskfs/file-exec.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1994-03-21 21:23:07 +0000
committerMichael I. Bushnell <mib@gnu.org>1994-03-21 21:23:07 +0000
commitcc49768adfaf3bdbbbd204c3f91efe931b44360b (patch)
tree3ed28de61bec6d8d91a5518ba43987a1e2c6eec5 /libdiskfs/file-exec.c
parent7876f3b04c8272994af056e00f9e770053f37b8c (diff)
Formerly file-exec.c.~2~
Diffstat (limited to 'libdiskfs/file-exec.c')
-rw-r--r--libdiskfs/file-exec.c41
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;
}