Fix access(X_OK) for super-user
authorDavid Bartley <dtbartle@maltodextrin.csclub.uwaterloo.ca>
Tue, 13 Jan 2009 05:48:04 +0000 (05:48 +0000)
committerDavid Bartley <dtbartle@maltodextrin.csclub.uwaterloo.ca>
Tue, 13 Jan 2009 05:48:04 +0000 (05:48 +0000)
sysdeps/unix/sysv/solaris2/kopensolaris-gnu/Makefile
sysdeps/unix/sysv/solaris2/kopensolaris-gnu/access.c [new file with mode: 0644]

index 0f012ca..c08f853 100644 (file)
@@ -10,7 +10,7 @@ ifeq ($(subdir),io)
 sysdep_routines += sys_open sys_open64 sys_openat sys_openat64 \
     sys_fstat sys_fstat64 sys_fstatat sys_fstatat64 sys_lstat \
     sys_lstat64 sys_stat sys_stat64 sys_sendfilev sys_sendfilev64 \
-    sys_getcwd sys_pipe sys_mknod
+    sys_getcwd sys_pipe sys_mknod sys_access
 headers := $(filter-out sys/vfs.h, $(headers))
 endif
 
diff --git a/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/access.c b/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/access.c
new file mode 100644 (file)
index 0000000..7bc4879
--- /dev/null
@@ -0,0 +1,77 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   OpenSolaris bits contributed by David Bartley
+    <dtbartle@csclub.uwaterloo.ca>, 2009.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <inline-syscall.h>
+
+DECLARE_INLINE_SYSCALL (int, access, const char *, int);
+
+/* Test for access to FILE.  */
+int
+__access (file, type)
+     const char *file;
+     int type;
+{
+  int res;
+
+  if (file == NULL || (type & ~(R_OK|W_OK|X_OK|F_OK|E_OK)) != 0)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  res = INLINE_SYSCALL (access, 2, file, type);
+
+  /* XXX: This should really be fixed in the kernel.  */
+  if (res == 0 && (type & X_OK))
+    {
+      uid_t uid;
+      gid_t gid;
+
+      uid = (type & E_OK) ? geteuid () : getuid ();
+      gid = (type & E_OK) ? getegid () : getgid ();
+      if (uid == 0 || gid == 0)
+        {
+          struct stat buf;
+
+          if (stat (file, &buf) != 0)
+            return -1;
+
+          /* Test user bit.  */
+          if (uid == buf.st_uid)
+            return (buf.st_mode & S_IXUSR) ? 0 : EACCES;
+
+          /* Test gid bit.  */
+          if (gid == buf.st_gid)
+            return (buf.st_mode & S_IXGRP) ? 0 : EACCES;
+
+          /* Test other bit.  */
+          return (buf.st_mode & S_IXOTH) ? 0 : EACCES;
+      }
+    }
+
+  return res;
+}
+
+weak_alias (__access, access)