diff -r fc11712e0df0 MoinMoin/auth/pam_login.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/auth/pam_login.py	Sun Aug 05 19:39:47 2012 +1000
@@ -0,0 +1,69 @@
+"""
+   MoinMoin PAM-based authentication
+
+   Allows to authenticate against an underlying system's PAM
+   authentication system (ie login using the credentials of any user
+   on your machine.)
+
+   Requires Chris AtLee's Python PAM module, egg can be downloaded
+   from http://atlee.ca/software/pam/
+
+   If you're using pam_unix with shadow passwords (ie a default Linux
+   system's authentication system) then MoinMoin has to be running as
+   the 'shadow' group who can access the /etc/shadow file. Otherwise
+   you'll only be able to login as the user that MoinMoin is running
+   as.
+
+   For Apache, this means a line in apache config like:
+   WSGIDaemonProcess moindaemon user=www-data group=shadow processes=10 maximum-requests=1000 umask=0007
+
+   If you choose to do that, remember "you are deliberately weakening
+   your system security, albeit only a little" -- as per
+   http://pam.sourceforge.net/mod_auth_pam/shadow.html
+
+   @copyright: 2012 by Angus Gratton <gus@projectgus.com>
+   @license: GNU GPL, see COPYING for details.
+"""
+import pam
+from MoinMoin.auth import *
+
+class PAMAuth(BaseAuth):
+    """ handle a login form login via PAM """
+    def __init__(self, autocreate=False):
+        BaseAuth.__init__(self)
+        self.autocreate = autocreate
+
+    login_inputs = ['username', 'password']
+    name = 'PAM'
+    logout_possible = True
+
+    def login(self, request, user_obj, username=None, password=None, **kw):
+        # simply continue if something else already logged in successfully
+        if user_obj and user_obj.valid:
+            return ContinueLogin(user_obj)
+
+        if not username and not password:
+            return ContinueLogin(user_obj)
+
+        _ = request.getText
+
+        logging.debug("%s: performing login action" % self.name)
+
+        if username and not password:
+            return ContinueLogin(user_obj, _('Missing password. Please enter user name and password.'))
+
+        if pam.authenticate(username, password):
+            u = user.User(request, auth_username=username, auth_method=self.name,
+                          auth_attribs=('name', 'password'))
+            logging.debug("%s: successfully authenticated user %r (%s)" % (self.name, u.name, "valid" if u.valid else "invalid"))
+            if self.autocreate:
+                logging.debug("calling create_or_update to autocreate user %r" % u.name)
+                u.create_or_update(True)
+            return ContinueLogin(u)
+        else:
+            logging.debug("%s: could not authenticate user %r (not valid)" % (self.name, username))
+            return ContinueLogin(user_obj, _("Invalid username or password."))
+
+    def login_hint(self, request):
+        _ = request.getText
+        return _('Log in using the same username and password that you use to login to your account on this computer')
diff -r fc11712e0df0 docs/REQUIREMENTS
--- a/docs/REQUIREMENTS	Sun Jul 22 20:59:35 2012 +0200
+++ b/docs/REQUIREMENTS	Sun Aug 05 19:39:47 2012 +1000
@@ -63,6 +63,8 @@
 
 openidrp auth: openid python module
 
+pam_login auth: python pam module, from http://atlee.ca/software/pam/
+
 stats charts: gdchart python module
 
 jabberbot: pyxmpp SVN revision 665 or release >= 1.0.1
