[CalendarServer-changes] [914]
CalendarServer/branches/users/dreid/sudoers-2
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jan 4 08:39:23 PST 2007
Revision: 914
http://trac.macosforge.org/projects/calendarserver/changeset/914
Author: dreid at apple.com
Date: 2007-01-04 08:39:22 -0800 (Thu, 04 Jan 2007)
Log Message:
-----------
Merge forward to pick up fixes for launchd.plist and caldavd etc
Modified Paths:
--------------
CalendarServer/branches/users/dreid/sudoers-2/conf/accounts.xml
CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd-test.plist
CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd.plist
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/config.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/aggregate.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/principal.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/xmlaccountsparser.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/extensions.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/resource.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/tap.py
Added Paths:
-----------
CalendarServer/branches/users/dreid/sudoers-2/conf/sudoers.plist
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/sudo.py
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/sudoers.plist
CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/test_sudo.py
Modified: CalendarServer/branches/users/dreid/sudoers-2/conf/accounts.xml
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/conf/accounts.xml 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/conf/accounts.xml 2007-01-04 16:39:22 UTC (rev 914)
@@ -25,12 +25,6 @@
<name>Super User</name>
</user>
<user>
- <uid>proxy</uid>
- <password>proxy</password>
- <name>User who can authorize as someone else</name>
- <canproxy/> <!-- FIXME: Is the directory the right place to configure this bit? -->
- </user>
- <user>
<uid>test</uid>
<password>test</password>
<name>Test User</name>
Modified: CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd-test.plist
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd-test.plist 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd-test.plist 2007-01-04 16:39:22 UTC (rev 914)
@@ -183,5 +183,8 @@
<array>
<string>/principals/user/admin</string>
</array>
+
+ <key>SudoersFile</key>
+ <string>conf/sudoers.plist</string>
</dict>
</plist>
Modified: CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd.plist
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd.plist 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/conf/caldavd.plist 2007-01-04 16:39:22 UTC (rev 914)
@@ -129,5 +129,8 @@
<array>
<string>/principals/user/admin</string>
</array>
+
+ <key>SudoersFile</key>
+ <string>/etc/caldavd/sudoers.plist</string>
</dict>
</plist>
Copied: CalendarServer/branches/users/dreid/sudoers-2/conf/sudoers.plist (from rev 909, CalendarServer/branches/users/dreid/sudoers/conf/sudoers.plist)
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/conf/sudoers.plist (rev 0)
+++ CalendarServer/branches/users/dreid/sudoers-2/conf/sudoers.plist 2007-01-04 16:39:22 UTC (rev 914)
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+<key>users</key>
+<array>
+<!-- Sudo user definitions -->
+<!--
+ <dict>
+ <key>authorize-as</key>
+ <dict>
+ <key>allow</key>
+ <true/>
+ <key>principals</key>
+ <array>
+ <string>all</string>
+ <string>/principals/user/wsanchez</string>
+ </array>
+ </dict>
+ <key>authorize-from</key>
+ <array>
+ <string>127.0.0.1</string>
+ </array>
+
+ <key>username</key>
+ <string></string>
+
+ <key>password</key>
+ <string></string>
+ </dict>
+-->
+ <dict>
+ <key>username</key>
+ <string>superuser</string>
+ <key>password</key>
+ <string>superuser</string>
+ </dict>
+</array>
+</dict>
+</plist>
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/config.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/config.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/config.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -60,7 +60,8 @@
'ServicePrincipal': '',
},
},
- 'AdminPrincipals': ['/principals/user/admin']
+ 'AdminPrincipals': ['/principals/user/admin'],
+ 'SudoersFile': '/etc/caldavd/sudoers.plist',
}
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/aggregate.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/aggregate.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/aggregate.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -103,6 +103,21 @@
else:
return None
+ userRecordTypes = ['user', 'sudoer']
+
+ def requestAvatarId(self, credentials):
+ for type in self.userRecordTypes:
+ user = self.recordWithShortName(
+ type,
+ credentials.credentials.username)
+
+ if user:
+ return self.serviceForRecordType(
+ type).requestAvatarId(credentials)
+
+ raise UnauthorizedLogin("No such user: %s" % (
+ credentials.credentials.username,))
+
class DuplicateRecordTypeError(DirectoryError):
"""
Duplicate record type.
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/principal.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/principal.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -87,14 +87,17 @@
for recordType in self.directory.recordTypes():
self.putChild(recordType, DirectoryPrincipalTypeResource(self.fp.child(recordType).path, self, recordType))
+ def principalForShortName(self, type, name):
+ typeResource = self.getChild(type)
+ if typeResource is None:
+ return None
+ return typeResource.getChild(name)
+
def principalForUser(self, user):
- return self.getChild("user").getChild(user)
+ return self.principalForShortName('user', user)
def principalForRecord(self, record):
- typeResource = self.getChild(record.recordType)
- if typeResource is None:
- return None
- return typeResource.getChild(record.shortName)
+ return self.principalForShortName(record.recordType, record.shortName)
def _principalForURI(self, uri):
if uri.startswith(self._url):
Copied: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/sudo.py (from rev 909, CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/sudo.py)
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/sudo.py (rev 0)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/sudo.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -0,0 +1,141 @@
+##
+# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: David reid, dreid at apple.com
+##
+
+"""
+Directory service implementation for users who are allowed to authorize
+as other principals.
+"""
+
+__all__ = [
+ "SudoDirectoryService",
+]
+
+from twisted.python.filepath import FilePath
+
+from twisted.cred.credentials import (IUsernamePassword,
+ IUsernameHashedPassword)
+
+from twisted.cred.error import UnauthorizedLogin
+
+from twistedcaldav.py.plistlib import readPlist
+from twistedcaldav.directory.directory import (DirectoryService,
+ DirectoryRecord,
+ UnknownRecordTypeError)
+
+class SudoDirectoryService(DirectoryService):
+ """
+ L{IDirectoryService} implementation for Sudo users.
+ """
+ baseGUID = "1EE00E46-1885-4DBC-A001-590AFA76A8E3"
+
+ realmName = None
+
+ plistFile = None
+
+ recordType = "sudoer"
+
+ def __repr__(self):
+ return "<%s %r: %r>" % (self.__class__.__name__, self.realmName,
+ self.plistFile)
+
+ def __init__(self, plistFile):
+ super(SudoDirectoryService, self).__init__()
+
+ if isinstance(plistFile, (unicode, str)):
+ plistFile = FilePath(plistFile)
+
+ self.plistFile = plistFile
+ self._fileInfo = None
+ self._accounts()
+
+ def _accounts(self):
+ fileInfo = (self.plistFile.getmtime(), self.plistFile.getsize())
+ if fileInfo != self._fileInfo:
+ self._plist = readPlist(self.plistFile.path)
+
+ return self._plist
+
+ def recordTypes(self):
+ return (self.recordType,)
+
+ def _recordForEntry(self, entry):
+ return SudoDirectoryRecord(
+ service=self,
+ recordType=self.recordType,
+ shortName=entry['username'],
+ entry=entry)
+
+
+ def listRecords(self, recordType):
+ if recordType != self.recordType:
+ raise UnknownRecordTypeError(recordType)
+
+ for entry in self._accounts()['users']:
+ yield self._recordForEntry(entry)
+
+ def recordWithShortName(self, recordType, shortName):
+ if recordType != self.recordType:
+ raise UnknownRecordTypeError(recordType)
+
+ for entry in self._accounts()['users']:
+ if entry['username'] == shortName:
+ return self._recordForEntry(entry)
+
+ def requestAvatarId(self, credentials):
+ # FIXME: ?
+ # We were checking if principal is enabled; seems unnecessary in current
+ # implementation because you shouldn't have a principal object for a
+ # disabled directory principal.
+ sudouser = self.recordWithShortName("sudoer",
+ credentials.credentials.username)
+ if sudouser is None:
+ raise UnauthorizedLogin("No such user: %s" % (sudouser,))
+
+ if sudouser.verifyCredentials(credentials.credentials):
+ return (
+ credentials.authnPrincipal.principalURL(),
+ credentials.authzPrincipal.principalURL(),
+ )
+ else:
+ raise UnauthorizedLogin(
+ "Incorrect credentials for %s" % (sudouser,))
+
+
+class SudoDirectoryRecord(DirectoryRecord):
+ """
+ L{DirectoryRecord} implementation for Sudo users.
+ """
+
+ def __init__(self, service, recordType, shortName, entry):
+ super(SudoDirectoryRecord, self).__init__(
+ service=service,
+ recordType=recordType,
+ guid=None,
+ shortName=shortName,
+ fullName=shortName,
+ calendarUserAddresses=set())
+
+ self.password = entry['password']
+
+ def verifyCredentials(self, credentials):
+ if IUsernamePassword.providedBy(credentials):
+ return credentials.checkPassword(self.password)
+ elif IUsernameHashedPassword.providedBy(credentials):
+ return credentials.checkPassword(self.password)
+
+ return super(SudoDirectoryRecord, self).verifyCredentials(credentials)
Copied: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/sudoers.plist (from rev 909, CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/test/sudoers.plist)
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/sudoers.plist (rev 0)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/sudoers.plist 2007-01-04 16:39:22 UTC (rev 914)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>users</key>
+ <array>
+ <dict>
+ <key>authorize-as</key>
+ <dict>
+ <key>allow</key>
+ <true/>
+ <key>principals</key>
+ <array>
+ <string>all</string>
+ </array>
+ </dict>
+ <key>authorize-from</key>
+ <array>
+ <string>127.0.0.1</string>
+ </array>
+ <key>password</key>
+ <string>alice</string>
+ <key>username</key>
+ <string>alice</string>
+ </dict>
+ </array>
+</dict>
+</plist>
Copied: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/test_sudo.py (from rev 909, CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/test/test_sudo.py)
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/test_sudo.py (rev 0)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/test/test_sudo.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -0,0 +1,66 @@
+##
+# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# DRI: David Reid, dreid at apple.com
+##
+import os
+
+from twisted.python.filepath import FilePath
+
+import twistedcaldav.directory.test.util
+from twistedcaldav.directory.sudo import SudoDirectoryService
+from twistedcaldav.py.plistlib import writePlist
+
+plistFile = FilePath(os.path.join(os.path.dirname(__file__), "sudoers.plist"))
+
+class SudoTestCase(
+ twistedcaldav.directory.test.util.BasicTestCase,
+ twistedcaldav.directory.test.util.DigestTestCase
+):
+ """
+ Test the Sudo Directory Service
+ """
+
+ recordTypes = set(('sudoer',))
+ recordType = 'sudoer'
+
+ sudoers = {'alice': {'password': 'alice',},
+ }
+
+ def plistFile(self):
+ if not hasattr(self, "_plistFile"):
+ self._plistFile = FilePath(self.mktemp())
+ plistFile.copyTo(self._plistFile)
+ return self._plistFile
+
+ def service(self):
+ service = SudoDirectoryService(self.plistFile())
+ service.realmName = "test realm"
+ return service
+
+ def test_listRecords(self):
+ for record in self.service().listRecords(self.recordType):
+ self.failUnless(record.shortName in self.sudoers)
+ self.assertEqual(self.sudoers[record.shortName]['password'],
+ record.password)
+
+ def test_recordWithShortName(self):
+ service = self.service()
+
+ record = service.recordWithShortName('sudoer', 'alice')
+ self.assertEquals(record.password, 'alice')
+
+ record = service.recordWithShortName('sudoer', 'bob')
+ self.failIf(record)
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/xmlaccountsparser.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/xmlaccountsparser.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/directory/xmlaccountsparser.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -42,7 +42,7 @@
ELEMENT_MEMBERS = "members"
ELEMENT_MEMBER = "member"
ELEMENT_CUADDR = "cuaddr"
-ELEMENT_CANPROXY = "canproxy"
+# ELEMENT_CANPROXY = "canproxy"
ATTRIBUTE_REALM = "realm"
ATTRIBUTE_REPEAT = "repeat"
@@ -129,7 +129,7 @@
self.members = set()
self.groups = set()
self.calendarUserAddresses = set()
- self.canproxy = False
+# self.canproxy = False
def repeat(self, ctr):
"""
@@ -162,7 +162,7 @@
result.name = name
result.members = self.members
result.calendarUserAddresses = calendarUserAddresses
- result.canproxy = self.canproxy
+# result.canproxy = self.canproxy
return result
def parseXML(self, node):
@@ -181,9 +181,9 @@
elif child._get_localName() == ELEMENT_CUADDR:
if child.firstChild is not None:
self.calendarUserAddresses.add(child.firstChild.data.encode("utf-8"))
- elif child._get_localName() == ELEMENT_CANPROXY:
- CalDAVResource.proxyUsers.add(self.shortName)
- self.canproxy = True
+# elif child._get_localName() == ELEMENT_CANPROXY:
+# CalDAVResource.proxyUsers.add(self.shortName)
+# self.canproxy = True
def _parseMembers(self, node):
for child in node._get_childNodes():
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/extensions.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/extensions.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -46,6 +46,19 @@
Extended L{twisted.web2.dav.resource.DAVResource} implementation.
"""
+ def findPrincipalForAuthID(self, authid):
+ """
+ Return an authentication and authorization principal identifiers for
+ the authentication identifier passed in. Check for sudo users before
+ regular users.
+ """
+ for collection in self.principalCollections():
+ principal = collection.principalForShortName('sudoer', authid)
+ if principal is not None:
+ return principal
+
+ return super(DAVFile, self).findPrincipalForAuthID(authid)
+
class DAVFile (SuperDAVFile):
"""
Extended L{twisted.web2.dav.static.DAVFile} implementation.
@@ -213,6 +226,21 @@
response.headers.setHeader("content-type", MimeType("text", "html"))
return response
+ def findPrincipalForAuthID(self, authid):
+ """
+ Return an authentication and authorization principal identifiers for
+ the authentication identifier passed in. Check for sudo users before
+ regular users.
+ """
+
+ for collection in self.principalCollections():
+ principal = collection.principalForShortName('sudoer', authid)
+ if principal is not None:
+ return principal
+
+ return super(DAVFile, self).findPrincipalForAuthID(authid)
+
+
class ReadOnlyResourceMixIn (object):
"""
Read only resource.
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/resource.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/resource.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -74,10 +74,6 @@
# resources to that size, or C{None} for no limit.
sizeLimit = None
- # Set containing user ids of all the users who have been given
- # the right to authorize as someone else.
- proxyUsers = set()
-
##
# HTTP
##
@@ -258,10 +254,15 @@
# Substitute the authz value for principal look up
authz = authz[0]
- # See if authenticated uid is a proxy user
- if authid in CalDAVResource.proxyUsers:
+ def isSudoPrincipal(authid):
+ for collection in self.principalCollections():
+ if collection.principalForShortName('sudoer', authid):
+ return True
+ return False
+
+ if isSudoPrincipal(authid):
if authz:
- if authz in CalDAVResource.proxyUsers:
+ if isSudoPrincipal(authz):
log.msg("Cannot proxy as another proxy: user '%s' as user '%s'" % (authid, authz))
raise HTTPError(responsecode.UNAUTHORIZED)
else:
Modified: CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/tap.py
===================================================================
--- CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/tap.py 2007-01-04 16:38:32 UTC (rev 913)
+++ CalendarServer/branches/users/dreid/sudoers-2/twistedcaldav/tap.py 2007-01-04 16:39:22 UTC (rev 914)
@@ -45,7 +45,11 @@
from twistedcaldav.config import config, parseConfig, defaultConfig
from twistedcaldav.logging import RotatingFileAccessLoggingObserver
from twistedcaldav.root import RootResource
+from twistedcaldav.resource import CalDAVResource
from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
+from twistedcaldav.directory.aggregate import AggregateDirectoryService
+from twistedcaldav.directory.sudo import SudoDirectoryService
+
from twistedcaldav.static import CalendarHomeProvisioningFile
try:
@@ -131,8 +135,19 @@
# Setup the Directory
#
directoryClass = namedClass(config.DirectoryService['type'])
- directory = directoryClass(**config.DirectoryService['params'])
+ baseDirectory = directoryClass(**config.DirectoryService['params'])
+ sudoDirectory = None
+
+ if config.SudoersFile:
+ sudoDirectory = SudoDirectoryService(config.SudoersFile)
+ sudoDirectory.realmName = baseDirectory.realmName
+
+ CalDAVResource.sudoDirectory = sudoDirectory
+
+ directory = AggregateDirectoryService((baseDirectory,
+ sudoDirectory))
+
#
# Setup Resource hierarchy
#
@@ -190,6 +205,12 @@
portal.registerChecker(directory)
+ # FIXME: This is a hack, why doesn't aggregate directory service
+ # do the right thing.
+
+# if sudoDirectory:
+# portal.registerChecker(sudoDirectory)
+
realm = directory.realmName or ""
for scheme, schemeConfig in config.Authentication.iteritems():
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070104/4fe3c8fb/attachment.html
More information about the calendarserver-changes
mailing list