Revision: 1580 http://trac.macosforge.org/projects/calendarserver/changeset/1580 Author: cdaboo@apple.com Date: 2007-05-30 12:58:59 -0700 (Wed, 30 May 2007) Log Message: ----------- Fix for SACL check causing Kerberos auth to fail. Plus optimize SACL check so it only happens once in any one request. Modified Paths: -------------- CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py Modified: CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py =================================================================== --- CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py 2007-05-30 17:31:35 UTC (rev 1579) +++ CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py 2007-05-30 19:58:59 UTC (rev 1580) @@ -24,7 +24,7 @@ "DAVResource", "DAVFile", "ReadOnlyResourceMixIn", - "SudoAuthIDMixin", + "SudoSACLMixin", ] import cPickle as pickle @@ -49,12 +49,22 @@ from twistedcaldav.directory.sudo import SudoDirectoryService from twistedcaldav.directory.directory import DirectoryService -class SudoAuthIDMixin(object): +class SudoSACLMixin(object): """ Mixin class to let DAVResource, and DAVFile subclasses below know about sudoer principals and how to find their AuthID """ + def authenticate(self, request): + # Bypass normal authentication if its already been done (by SACL check) + if (hasattr(request, "authnUser") and + hasattr(request, "authzUser") and + request.authnUser is not None and + request.authzUser is not None): + return (request.authnUser, request.authzUser) + else: + return super(SudoSACLMixin, self).authenticate(request) + def findPrincipalForAuthID(self, authid): """ Return an authentication and authorization principal identifiers for @@ -68,7 +78,7 @@ if principal is not None: return principal - return super(SudoAuthIDMixin, self).findPrincipalForAuthID(authid) + return super(SudoSACLMixin, self).findPrincipalForAuthID(authid) def authorizationPrincipal(self, request, authid, authnPrincipal): """ @@ -131,7 +141,7 @@ raise HTTPError(responsecode.FORBIDDEN) else: # No proxy - do default behavior - d = waitForDeferred(super(SudoAuthIDMixin, self).authorizationPrincipal(request, authid, authnPrincipal)) + d = waitForDeferred(super(SudoSACLMixin, self).authorizationPrincipal(request, authid, authnPrincipal)) yield d yield d.getResult() return @@ -139,8 +149,7 @@ authorizationPrincipal = deferredGenerator(authorizationPrincipal) - -class DAVResource (SudoAuthIDMixin, SuperDAVResource): +class DAVResource (SudoSACLMixin, SuperDAVResource): """ Extended L{twisted.web2.dav.resource.DAVResource} implementation. """ @@ -335,7 +344,7 @@ return davxml.ResourceType(davxml.Principal()) -class DAVFile (SudoAuthIDMixin, SuperDAVFile): +class DAVFile (SudoSACLMixin, SuperDAVFile): """ Extended L{twisted.web2.dav.static.DAVFile} implementation. """ Modified: CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py =================================================================== --- CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py 2007-05-30 17:31:35 UTC (rev 1579) +++ CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py 2007-05-30 19:58:59 UTC (rev 1580) @@ -48,7 +48,7 @@ self.useSacls = True else: log.msg(("RootResource.CheckSACL is unset but " - "config.EnableSACLs is True, SACLs will not be" + "config.EnableSACLs is True, SACLs will not be " "turned on.")) self.contentFilters = [] @@ -83,6 +83,10 @@ request.remoteAddr))) def _checkSACLCb((authnUser, authzUser)): + # Cache the authentication details + request.authnUser = authnUser + request.authzUser = authzUser + # Figure out the "username" from the davxml.Principal object username = authzUser.children[0].children[0].data username = username.rstrip('/').split('/')[-1] @@ -91,6 +95,8 @@ log.msg("User '%s' is not enabled with the '%s' SACL" % (username, self.saclService,)) return Failure(HTTPError(403)) + # Mark SACL's as having been checked so we can avoid doing it multiple times + request.checkedSACL = True return True d = defer.maybeDeferred(self.authenticate, request) @@ -102,7 +108,7 @@ for filter in self.contentFilters: request.addResponseFilter(filter[0], atEnd=filter[1]) - if self.useSacls: + if self.useSacls and not hasattr(request, "checkedSACL"): d = self.checkSacl(request) d.addCallback(lambda _: super(RootResource, self ).locateChild(request, segments))