diff -c --new-file -r --exclude=*\.pyc lib/python2.3/site-packages/MoinMoin/Page.py tmp/MoinMoin/Page.py
*** lib/python2.3/site-packages/MoinMoin/Page.py	Sat Jan 22 14:37:23 2005
--- tmp/MoinMoin/Page.py	Fri Feb 11 18:05:35 2005
***************
*** 13,18 ****
--- 13,19 ----
  from MoinMoin import config, caching, user, util, wikiutil
  from MoinMoin.logfile import eventlog
  from MoinMoin.util import filesys, web
+ from MoinMoin.access import access
  
  
  # There are many places accessing ACLs even without actually sending
***************
*** 424,430 ****
          @rtype: bool
          @return: true, if this page is writable or does not exist
          """
!         return os.access(self._text_filename(), os.W_OK) or not self.exists()
  
      def isUnderlayPage(self, includeDeleted=True):
          """ Does this page live in the underlay dir?
--- 425,431 ----
          @rtype: bool
          @return: true, if this page is writable or does not exist
          """
!         return access(self._text_filename(), os.W_OK) or not self.exists()
  
      def isUnderlayPage(self, includeDeleted=True):
          """ Does this page live in the underlay dir?
diff -c --new-file -r --exclude=*\.pyc lib/python2.3/site-packages/MoinMoin/access.py tmp/MoinMoin/access.py
*** lib/python2.3/site-packages/MoinMoin/access.py	Thu Jan  1 01:00:00 1970
--- tmp/MoinMoin/access.py	Fri Feb 11 18:23:02 2005
***************
*** 0 ****
--- 1,77 ----
+ # access.py -- functions for testing access to files
+ #
+ # Richard Brooksby, 2005-02-11
+ #
+ # This function supplement those in os.path with tests for readability and
+ # writeability of a filesystem object by the current _effective_ user and
+ # group.  Note that this is quite different to os.access, which checks the
+ # entire path using the _real_ user and group, and is intended as a utility
+ # for setuid/setgid programs.
+ #
+ # NOTES
+ #
+ # 1. This is prototype code and has not been tested in a production system.
+ #
+ # 2. Only looks at permissions bits and not whether the filesystem is
+ # read-only, for example.
+ #
+ # 3. Assumes root's uid is zero.
+ #
+ #
+ # 2005-02-11  RB  Created as a solution for
+ # <http://moinmoin.wikiwikiweb.de/FeatureRequests/UseSetgidWraper>.
+ 
+ import os
+ import stat
+ 
+ def access(path, mode):
+ 
+     try:
+         s = os.stat(path)
+     except OSError:
+         return False
+ 
+     euid = os.geteuid()
+     egid = os.getegid()
+     
+     mask = stat.S_IRWXO
+     
+     if s.st_gid == egid:
+         mask = mask | stat.S_IRWXG
+ 
+     if s.st_uid == euid:
+         mask = mask | stat.S_IRWXU
+ 
+     # If you're asking about readability
+     if mode & os.R_OK:
+         # If you're root, or any relevant readability bits are set, then
+         # you can read it.
+         if (euid == 0 or
+             (s.st_mode & mask & (stat.S_IROTH | stat.S_IRGRP | stat.S_IRUSR))):
+             pass
+         else:
+             return False
+ 
+     # See above for comments, but s/readable/writeable/.
+     if mode & os.W_OK:
+         if (euid == 0 or
+             (s.st_mode & mask & (stat.S_IWOTH | stat.S_IWGRP | stat.S_IWUSR))):
+             pass
+         else:
+             return False
+ 
+     if mode & os.X_OK:
+         # Root can't execute things that aren't executable.  That would be a
+         # very nasty security hole.  However, root _can_ execute things that
+         # _anyone_ can execute.
+         if euid == 0:
+             if s.st_mode & (stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR):
+                 pass
+             else:
+                 return False
+         elif s.st_mode & mask & (stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR):
+             pass
+         else:
+             return False
+ 
+     return True
diff -c --new-file -r --exclude=*\.pyc lib/python2.3/site-packages/MoinMoin/multiconfig.py tmp/MoinMoin/multiconfig.py
*** lib/python2.3/site-packages/MoinMoin/multiconfig.py	Sat Jan 22 14:37:20 2005
--- tmp/MoinMoin/multiconfig.py	Fri Feb 11 18:06:27 2005
***************
*** 10,15 ****
--- 10,16 ----
  
  import re, os, sys
  from MoinMoin import error
+ from MoinMoin.access import access
  
  
  _url_re = None
***************
*** 413,419 ****
                  continue
  
              path_pages = os.path.join(path, "pages")
!             if not (os.path.isdir(path_pages) and os.access(path_pages, mode)):
                  msg = '''
  "%(attr)s" does not exists at "%(path)s", or has incorrect ownership and
  permissions.
--- 414,420 ----
                  continue
  
              path_pages = os.path.join(path, "pages")
!             if not (os.path.isdir(path_pages) and access(path_pages, mode)):
                  msg = '''
  "%(attr)s" does not exists at "%(path)s", or has incorrect ownership and
  permissions.
diff -c --new-file -r --exclude=*\.pyc lib/python2.3/site-packages/MoinMoin/wikitest.py tmp/MoinMoin/wikitest.py
*** lib/python2.3/site-packages/MoinMoin/wikitest.py	Mon Jan 24 19:00:18 2005
--- tmp/MoinMoin/wikitest.py	Fri Feb 11 18:07:02 2005
***************
*** 19,24 ****
--- 19,25 ----
      import os, sys
      from MoinMoin import version
      from MoinMoin.logfile import editlog, eventlog
+     from MoinMoin.access import access
  
      request.write('Release %s\n' % version.release)
      request.write('Revision %s\n' % version.revision)
***************
*** 49,55 ****
      for name, path in dirs:
          if not os.path.isdir(path):
              request.write("*** %s directory NOT FOUND (set to '%s')\n" % (name, path))
!         elif not os.access(path, os.R_OK | os.W_OK | os.X_OK):
              request.write("*** %s directory NOT ACCESSIBLE (set to '%s')\n" % (name, path))
          else:
              path = os.path.abspath(path)
--- 50,56 ----
      for name, path in dirs:
          if not os.path.isdir(path):
              request.write("*** %s directory NOT FOUND (set to '%s')\n" % (name, path))
!         elif not access(path, os.R_OK | os.W_OK | os.X_OK):
              request.write("*** %s directory NOT ACCESSIBLE (set to '%s')\n" % (name, path))
          else:
              path = os.path.abspath(path)
