Implemented most ACLs and tests for Mozillians and Applicants

This commit is contained in:
Andrew Findlay 2011-06-23 13:56:13 +01:00
Родитель d35513eddc
Коммит 2e0bf0ae0e
4 изменённых файлов: 233 добавлений и 22 удалений

Просмотреть файл

@ -6,6 +6,41 @@
# andrew.findlay@skills-1st.co.uk
# 20 June 2011
# Enforce ACL rules on the content of entries that are about to be added
add_content_acl on
# DIT Content Rule for inetOrgPerson (2.16.840.1.113730.3.2.2)
#
# Prevent unwanted objectclasses on user entries
#
# This is a belt-and-braces protection as normally only the registration agent
# and LDAP admins can change the objectClass attribute
#
# We also make both uid and uniqueIdentifier mandatory:
# uid is the username, so it is essential
# uniqueIdentifier is the naming attribute
#
# Note that because this is part of the schema, even the rootDN cannot break the rules
ditcontentrule ( 2.16.840.1.113730.3.2.2
NAME 'dcrInetOrgPerson'
DESC 'Control content of inetOrgPerson entries'
AUX ( mozilliansObject $ mozilliansPerson )
MUST ( uid $ uniqueIdentifier )
)
# We define some attribute sets as objectclasses for convenience.
# Note that these are NOT intended to be used as objectclasses of actual entries.
# The base OID for these is 1.3.6.1.4.1.13769.3000.3
objectclass ( 1.3.6.1.4.1.13769.3000.3.1
NAME 'attrsetSelfModifiable'
DESC 'Attributes that a user can modify in their own entry'
AUXILIARY
MAY ( cn $ sn $ displayname $ mail $ uid $ telephoneNumber $ jpegPhoto $ description )
)
# Permit everyone to read the service entries
access to dn.exact=""
@ -29,26 +64,54 @@ access to attrs="userPassword"
by self =w
by * auth
# Anon may read and search just enough to find a DN given a uid
# We allow all authenticated users to view and modify the basic
# informational attributes in their entry
access to attrs="@attrsetSelfModifiable"
by self write
by * break
# Massive simplification for now:
# treat all authenticated users as Mozillians
# even if they have not been vouched for
# User may read their own voucher but not modify it
access to attrs="mozilliansVouchedBy"
by self read
by * break
# Mozillians may add their own DN to another user's voucher attribute
access to attrs="mozilliansVouchedBy" val.regex="^(.*)$"
by dn.exact,expand="${v1}" set="user/mozilliansVouchedBy" add
by * break
# Mozillians may read/search everyone's voucher attribute
access to attrs="mozilliansVouchedBy"
by set="user/mozilliansVouchedBy" read
by * break
# Mozillians may read/search everything that is not restricted above
access to *
by set="user/mozilliansVouchedBy" read
by * break
# Anon may read and search just enough to find a DN given a uid
# non-Mozillian users can do this too
access to attrs="entry"
by anonymous read
by users read
by * break
access to attrs="uid"
by anonymous search
by users search
by * break
access to attrs="uniqueIdentifier"
by anonymous read
by users search
by * break
# Massive simplification for now:
# all authenticated users can see everything else
access to *
by users read
# Default deny
access to *

Просмотреть файл

@ -1450,6 +1450,18 @@ mozilliansVouchedBy: uniqueIdentifier=1,ou=people,dc=mozillians,dc=org
sn: Wadensjöö
cn: Åke Wadensjöö
displayName: Åke Wadensjöö
userPassword: {SSHA}6v9NTMhqMFpUORpqpCynb5E05eme3UrJ
userPassword: secret
description: Ne révèle pas le dénouement SVP. $ Se upp för nationella tecken $ Uważaj na znaki narodowe $ احترس من الشخصيات الوطنية
uid: Åke
dn: uniqueIdentifier=7,ou=people,dc=mozillians,dc=org
objectClass: inetOrgPerson
objectClass: mozilliansPerson
uniqueIdentifier: 7
sn: Applicant
cn: An Applicant
displayName: An Applicant
userPassword: secret
description: An Applicant
uid: 7

Просмотреть файл

@ -9,6 +9,7 @@
#
# Object classes under: 1.3.6.1.4.1.13769.3000.1
# Attribute types under: 1.3.6.1.4.1.13769.3000.2
# Attribute sets under: 1.3.6.1.4.1.13769.3000.3
########################################################################
# Attribute types

Просмотреть файл

@ -224,6 +224,26 @@ class LdapAclTest(unittest.TestCase):
ldap_check.unbind()
# Changing own user attributes
def change_user_attributes(self, user, userDN, ldap_conn):
try:
ldap_conn.modify_s(
userDN,
[
(ldap.MOD_REPLACE,'cn','modified CN'),
(ldap.MOD_REPLACE,'sn','modified SN'),
(ldap.MOD_REPLACE,'displayName','modified displayName'),
(ldap.MOD_REPLACE,'mail',['new@mail.one','new@mail.two']),
(ldap.MOD_REPLACE,'uid','modified UID'),
(ldap.MOD_REPLACE,'telephoneNumber',['+1 234','+5-678-90']),
(ldap.MOD_REPLACE,'description','modified description'),
(ldap.MOD_REPLACE,'jpegPhoto','modified jpegPhoto'),
]
)
except ldap.LDAPError:
self.fail( user + " cannot modify their own user atttributes " + str(sys.exc_info()[0]) )
#######################################################################################
# Actual tests start here
@ -284,7 +304,7 @@ class LdapAclTest(unittest.TestCase):
except ldap.LDAPError:
self.fail( "Anon cannot search under "+people_node+" " + str(sys.exc_info()[0]) )
def test_T0020_applicant_search_person(self):
def test_T6040_applicant_search_person(self):
# Applicant trying to find a person entry that is not their own
# This should work, but not expose any data apart from the DN
try:
@ -305,19 +325,23 @@ class LdapAclTest(unittest.TestCase):
self.fail( "Applicant should not be able to read attributes from user entries. Got: " +
str(getAttrNames(res[0])) )
def test_T0030_applicant_search_multi(self):
# Applicant trying to find multiple entries
# The filter matches 3 in this case
# This should limit at 2 entries returned
try:
with self.assertRaises(ldap.SIZELIMIT_EXCEEDED):
res = self.ldap_applicant001.search_s(
people_node,
ldap.SCOPE_SUBTREE,
filterstr='(uid=test00*)' )
except ldap.LDAPError:
self.fail( "Applicant cannot search under "+people_node+" " + str(sys.exc_info()[0]) )
# It is not practical to enforce different limits on Applicants and Mozillians
# with the current implementation because the limits statement in OpenLDAP does not accept
# set specifications
#
# def test_T6050_applicant_search_multi(self):
# # Applicant trying to find multiple entries
# # The filter matches 3 in this case
# # This should limit at 2 entries returned
# try:
# with self.assertRaises(ldap.SIZELIMIT_EXCEEDED):
# res = self.ldap_applicant001.search_s(
# people_node,
# ldap.SCOPE_SUBTREE,
# filterstr='(uid=test00*)' )
#
# except ldap.LDAPError:
# self.fail( "Applicant cannot search under "+people_node+" " + str(sys.exc_info()[0]) )
def test_T6030_mozillian_search_person(self):
# Mozillian trying to find a person entry
@ -394,6 +418,117 @@ class LdapAclTest(unittest.TestCase):
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_applicant001.passwd_s(ldap_mozillian012DN, None, 'owned!')
def test_T6010_applicant_change_user_attributes(self):
self.change_user_attributes(
'Applicant',
ldap_applicant001DN,
self.ldap_applicant001 )
def test_T6010_mozillian_change_user_attributes(self):
self.change_user_attributes(
'Mozillian',
ldap_mozillian011DN,
self.ldap_mozillian011 )
def test_T6010_mozillian_delete_uid(self):
# Users should not be able to delete uid as then it will be
# impossible for them to log in again
# The error here is OBJECT_CLASS_VIOLATION because this is enforced
# by a DIT content rule rather than an ACL
with self.assertRaises(ldap.OBJECT_CLASS_VIOLATION):
self.ldap_mozillian011.modify_s(
ldap_mozillian011DN,
[
(ldap.MOD_DELETE,'uid',None),
]
)
def test_T6020_mozillian_read_obscure_attrs(self):
# Mozillian reading more obscure attributes in their own entry
try:
res = self.ldap_mozillian011.search_s(
ldap_mozillian011DN,
ldap.SCOPE_BASE,
filterstr='(objectclass=*)',
attrlist=['mozilliansVouchedBy','modifiersName','modifyTimestamp','userPassword'] )
except ldap.LDAPError:
self.fail( "Mozillian cannot search own entry " + str(sys.exc_info()[0]) )
if not getAttrValue(res[0],'modifiersName'):
self.fail( "Mozillian should see their own modifiersName value" )
if not getAttrValue(res[0],'modifyTimestamp'):
self.fail( "Mozillian should see their own modifyTimestamp value" )
if not getAttrValue(res[0],'mozilliansVouchedBy'):
self.fail( "Mozillian should see their own mozilliansVouchedBy value" )
# Should NOT see own password
if getAttrValue(res[0],'userPassword'):
self.fail( "Mozillian should not see their own userPassword value" )
def test_T5010_mozillian_vouch_for_applicant(self):
try:
self.ldap_mozillian011.modify_s(
ldap_applicant001DN,
[ (ldap.MOD_ADD,'mozilliansVouchedBy',ldap_mozillian011DN) ]
)
except ldap.LDAPError:
self.fail( "Mozillian cannot vouch for applicant " + str(sys.exc_info()[0]) )
def test_T5010_mozillian_fake_vouch_for_applicant(self):
# Mozillian should not be able to put someone else's DN into
# an applicant's mozilliansVouchedBy attribute
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_mozillian011.modify_s(
ldap_applicant001DN,
[ (ldap.MOD_ADD,'mozilliansVouchedBy',ldap_applicant001DN) ]
)
def test_T5010_mozillian_unvouch_applicant(self):
# Mozillian should not be able to remove any value from
# an applicant's mozilliansVouchedBy attribute
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_mozillian011.modify_s(
ldap_applicant001DN,
[ (ldap.MOD_DELETE,'mozilliansVouchedBy',None) ]
)
def test_T5020_mozillian_fake_vouch_for_self(self):
# Mozillian should not be able to modify
# their own mozilliansVouchedBy attribute
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_mozillian011.modify_s(
ldap_mozillian011DN,
[ (ldap.MOD_ADD,'mozilliansVouchedBy',ldap_applicant001DN) ]
)
def test_T5020_applicant_fake_vouch_for_self(self):
# Applicant should not be able to modify
# their own mozilliansVouchedBy attribute
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_applicant001.modify_s(
ldap_applicant001DN,
[ (ldap.MOD_ADD,'mozilliansVouchedBy',ldap_applicant001DN) ]
)
def test_T5020_mozillian_fake_unvouch_self(self):
# Mozillian should not be able to modify
# their own mozilliansVouchedBy attribute
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_mozillian011.modify_s(
ldap_mozillian011DN,
[ (ldap.MOD_DELETE,'mozilliansVouchedBy',None) ]
)
def test_T5030_applicant_fake_vouch_for_another(self):
# Applicant should not be able to modify
# another applicant's mozilliansVouchedBy attribute
with self.assertRaises(ldap.INSUFFICIENT_ACCESS):
self.ldap_applicant001.modify_s(
ldap_applicant002DN,
[ (ldap.MOD_ADD,'mozilliansVouchedBy',ldap_applicant001DN) ]
)
########################################################################
# Main program