Add a new objectclass, ipaObject, that will add a UUID to many IPA objects

ipaObject is defined as an auxiliary objectclass so it is up to the
plugin author to ensure that the objectclass is included an a UUID generated.
ipaUniqueId is a MUST attribute so if you include the objectclass you must
ensure that the uuid is generated.

This also fixes up some unrelated unit test failures.
This commit is contained in:
Rob Crittenden
2009-08-10 16:24:10 -04:00
committed by Jason Gerard DeRose
parent dbeb409ebd
commit c781e8a57d
16 changed files with 54 additions and 31 deletions

View File

@@ -5,6 +5,7 @@ attributeTypes: (2.16.840.1.113730.3.8.3.3 NAME 'enrolledBy' DESC 'DN of adminis
attributeTypes: (2.16.840.1.113730.3.8.3.4 NAME 'enrollmentPwd' DESC 'Password used to bulk enroll machines' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} X-ORIGIN 'IPA v2' ) attributeTypes: (2.16.840.1.113730.3.8.3.4 NAME 'enrollmentPwd' DESC 'Password used to bulk enroll machines' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} X-ORIGIN 'IPA v2' )
attributeTypes: (2.16.840.1.113730.3.8.3.43 NAME 'fqdn' DESC 'FQDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'IPA v2' ) attributeTypes: (2.16.840.1.113730.3.8.3.43 NAME 'fqdn' DESC 'FQDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.1 NAME 'ipaHost' AUXILIARY MUST ( fqdn ) MAY ( userPassword $ ipaClientVersion $ enrolledBy $ memberOf) X-ORIGIN 'IPA v2' ) objectClasses: (2.16.840.1.113730.3.8.4.1 NAME 'ipaHost' AUXILIARY MUST ( fqdn ) MAY ( userPassword $ ipaClientVersion $ enrolledBy $ memberOf) X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.44 NAME 'ipaObject' DESC 'IPA objectclass' AUXILIARY MUST ( ipaUniqueId ) X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.2 NAME 'ipaService' DESC 'IPA service objectclass' AUXILIARY MAY ( memberOf ) X-ORIGIN 'IPA v2' ) objectClasses: (2.16.840.1.113730.3.8.4.2 NAME 'ipaService' DESC 'IPA service objectclass' AUXILIARY MAY ( memberOf ) X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.3 NAME 'nestedGroup' DESC 'Group that supports nesting' SUP groupOfNames STRUCTURAL MAY memberOf X-ORIGIN 'IPA v2' ) objectClasses: (2.16.840.1.113730.3.8.4.3 NAME 'nestedGroup' DESC 'Group that supports nesting' SUP groupOfNames STRUCTURAL MAY memberOf X-ORIGIN 'IPA v2' )
objectClasses: (2.16.840.1.113730.3.8.4.4 NAME 'ipaUserGroup' DESC 'IPA user group object class' SUP nestedGroup STRUCTURAL X-ORIGIN 'IPA v2' ) objectClasses: (2.16.840.1.113730.3.8.4.4 NAME 'ipaUserGroup' DESC 'IPA user group object class' SUP nestedGroup STRUCTURAL X-ORIGIN 'IPA v2' )

View File

@@ -149,6 +149,7 @@ ipaGroupObjectClasses: top
ipaGroupObjectClasses: groupofnames ipaGroupObjectClasses: groupofnames
ipaGroupObjectClasses: nestedgroup ipaGroupObjectClasses: nestedgroup
ipaGroupObjectClasses: ipausergroup ipaGroupObjectClasses: ipausergroup
ipaGroupObjectClasses: ipaobject
ipaUserObjectClasses: top ipaUserObjectClasses: top
ipaUserObjectClasses: person ipaUserObjectClasses: person
ipaUserObjectClasses: organizationalperson ipaUserObjectClasses: organizationalperson
@@ -157,6 +158,7 @@ ipaUserObjectClasses: inetuser
ipaUserObjectClasses: posixaccount ipaUserObjectClasses: posixaccount
ipaUserObjectClasses: krbprincipalaux ipaUserObjectClasses: krbprincipalaux
ipaUserObjectClasses: radiusprofile ipaUserObjectClasses: radiusprofile
ipaUserObjectClasses: ipaobject
ipaDefaultEmailDomain: $DOMAIN ipaDefaultEmailDomain: $DOMAIN
dn: cn=account inactivation,cn=accounts,$SUFFIX dn: cn=account inactivation,cn=accounts,$SUFFIX

View File

@@ -25,6 +25,7 @@ Base plugin for groups.
from ipalib import api, crud, errors from ipalib import api, crud, errors
from ipalib import Command, Object from ipalib import Command, Object
from ipalib import Flag, Int, List, Str from ipalib import Flag, Int, List, Str
from ipalib import uuid
_default_attributes = ['cn', 'description', 'member', 'memberof'] _default_attributes = ['cn', 'description', 'member', 'memberof']
_default_class = 'groupofnames' _default_class = 'groupofnames'
@@ -137,7 +138,7 @@ class basegroup_add(crud.Create):
""" """
Create new group. Create new group.
""" """
base_classes = ('top', _default_class) base_classes = ('top', 'ipaobject', _default_class)
def execute(self, cn, **kw): def execute(self, cn, **kw):
""" """
@@ -162,6 +163,8 @@ class basegroup_add(crud.Create):
else: else:
entry_attrs['objectclass'] = self.base_classes entry_attrs['objectclass'] = self.base_classes
entry_attrs['ipauniqueid'] = str(uuid.uuid1())
ldap.add_entry(dn, entry_attrs) ldap.add_entry(dn, entry_attrs)
return ldap.get_entry(dn, entry_attrs.keys()) return ldap.get_entry(dn, entry_attrs.keys())

View File

@@ -29,6 +29,7 @@ from ipalib import api, crud, errors, util
from ipalib import Object from ipalib import Object
from ipalib import Str, Flag from ipalib import Str, Flag
from ipalib.plugins.service import split_principal from ipalib.plugins.service import split_principal
from ipalib import uuid
_container_dn = api.env.container_host _container_dn = api.env.container_host
_default_attributes = [ _default_attributes = [
@@ -166,7 +167,7 @@ class host_add(crud.Create):
# FIXME: add this attribute to cn=ipaconfig # FIXME: add this attribute to cn=ipaconfig
# config = ldap.get_ipa_config()[1] # config = ldap.get_ipa_config()[1]
# kw['objectclass'] = config.get('ipahostobjectclasses') # kw['objectclass'] = config.get('ipahostobjectclasses')
entry_attrs['objectclass'] = ['nshost', 'ipahost', 'pkiuser'] entry_attrs['objectclass'] = ['ipaobject', 'nshost', 'ipahost', 'pkiuser']
if 'userpassword' not in entry_attrs: if 'userpassword' not in entry_attrs:
entry_attrs['krbprincipalname'] = 'host/%s@%s' % ( entry_attrs['krbprincipalname'] = 'host/%s@%s' % (
@@ -178,6 +179,8 @@ class host_add(crud.Create):
elif 'krbprincipalaux' in entry_attrs['objectclass']: elif 'krbprincipalaux' in entry_attrs['objectclass']:
entry_attrs['objectclass'].remove('krbprincipalaux') entry_attrs['objectclass'].remove('krbprincipalaux')
entry_attrs['ipauniqueid'] = str(uuid.uuid1())
ldap.add_entry(dn, entry_attrs) ldap.add_entry(dn, entry_attrs)
return ldap.get_entry(dn, entry_attrs.keys()) return ldap.get_entry(dn, entry_attrs.keys())

View File

@@ -69,9 +69,9 @@ class netgroup_add(basegroup_add):
ldap = self.api.Backend.ldap2 ldap = self.api.Backend.ldap2
entry_attrs = self.args_options_2_entry(cn, **kw) entry_attrs = self.args_options_2_entry(cn, **kw)
entry_attrs['ipauniqueid'] = str(uuid.uuid1()) entry_attrs['objectclass'] = ['top', 'ipaobject', 'ipaassociation', _default_class]
entry_attrs['objectclass'] = ['top', 'ipaassociation', _default_class]
entry_attrs.setdefault('nisdomainname', self.api.env.domain) entry_attrs.setdefault('nisdomainname', self.api.env.domain)
entry_attrs['ipauniqueid'] = str(uuid.uuid1())
dn = ldap.make_dn(entry_attrs, 'ipauniqueid', _container_dn) dn = ldap.make_dn(entry_attrs, 'ipauniqueid', _container_dn)

View File

@@ -28,6 +28,7 @@ from OpenSSL import crypto
from ipalib import api, crud, errors from ipalib import api, crud, errors
from ipalib import Object from ipalib import Object
from ipalib import Str, Flag, Bytes from ipalib import Str, Flag, Bytes
from ipalib import uuid
_container_dn = api.env.container_service _container_dn = api.env.container_service
_default_attributes = ['krbprincipalname', 'usercertificate'] _default_attributes = ['krbprincipalname', 'usercertificate']
@@ -152,8 +153,9 @@ class service_add(crud.Create):
entry_attrs = self.args_options_2_entry(principal, **kw) entry_attrs = self.args_options_2_entry(principal, **kw)
entry_attrs['objectclass'] = [ entry_attrs['objectclass'] = [
'krbprincipal', 'krbprincipalaux', 'krbticketpolicyaux', 'krbprincipal', 'krbprincipalaux', 'krbticketpolicyaux',
'ipaservice', 'pkiuser' 'ipaobject', 'ipaservice', 'pkiuser'
] ]
entry_attrs['ipauniqueid'] = str(uuid.uuid1())
dn = ldap.make_dn(entry_attrs, 'krbprincipalname', _container_dn) dn = ldap.make_dn(entry_attrs, 'krbprincipalname', _container_dn)
ldap.add_entry(dn, entry_attrs) ldap.add_entry(dn, entry_attrs)

View File

@@ -24,6 +24,7 @@ Users (Identity)
from ipalib import api, crud, errors from ipalib import api, crud, errors
from ipalib import Command, Object from ipalib import Command, Object
from ipalib import Flag, Int, Password, Str from ipalib import Flag, Int, Password, Str
from ipalib import uuid
# parent DN # parent DN
_container_dn = api.env.container_user _container_dn = api.env.container_user
@@ -151,6 +152,8 @@ class user_add(crud.Create):
# fill default group's gidNumber # fill default group's gidNumber
entry_attrs['gidnumber'] = group_attrs['gidnumber'] entry_attrs['gidnumber'] = group_attrs['gidnumber']
entry_attrs['ipauniqueid'] = str(uuid.uuid1())
# create user entry # create user entry
ldap.add_entry(dn, entry_attrs) ldap.add_entry(dn, entry_attrs)

View File

@@ -45,6 +45,7 @@ class test_group(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'description', self.description) assert_attr_equal(res, 'description', self.description)
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_group_add(self): def test_2_group_add(self):
""" """
@@ -136,24 +137,24 @@ class test_group(XMLRPC_test):
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
assert res.get('gidnumber', '') assert res.get('gidnumber', '')
def test_9_group_del_member(self): def test_9_group_remove_member(self):
""" """
Test the `xmlrpc.group_del_member` method. Test the `xmlrpc.group_remove_member` method.
""" """
kw = {} kw = {}
kw['groups'] = self.cn2 kw['groups'] = self.cn2
(total, failed, res) = api.Command['group_del_member'](self.cn, **kw) (total, failed, res) = api.Command['group_remove_member'](self.cn, **kw)
assert res assert res
assert total == 1 assert total == 1
def test_a_group_del_member(self): def test_a_group_remove_member(self):
""" """
Test the `xmlrpc.group_del_member` method with non-member Test the `xmlrpc.group_remove_member` method with non-member
""" """
kw = {} kw = {}
kw['groups'] = u'notfound' kw['groups'] = u'notfound'
# an error isn't thrown, the list of failed members is returned # an error isn't thrown, the list of failed members is returned
(total, failed, res) = api.Command['group_del_member'](self.cn, **kw) (total, failed, res) = api.Command['group_remove_member'](self.cn, **kw)
assert total == 0 assert total == 0
assert 'notfound' in failed assert 'notfound' in failed

View File

@@ -45,6 +45,7 @@ class test_host(XMLRPC_test):
assert_attr_equal(res, 'description', self.description) assert_attr_equal(res, 'description', self.description)
assert_attr_equal(res, 'fqdn', self.fqdn) assert_attr_equal(res, 'fqdn', self.fqdn)
assert_attr_equal(res, 'localityname', self.localityname) assert_attr_equal(res, 'localityname', self.localityname)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_host_show(self): def test_2_host_show(self):
""" """

View File

@@ -47,6 +47,7 @@ class test_hostgroup(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'description', self.description) assert_attr_equal(res, 'description', self.description)
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_host_add(self): def test_2_host_add(self):
""" """
@@ -101,13 +102,13 @@ class test_hostgroup(XMLRPC_test):
assert_attr_equal(res, 'description', newdesc) assert_attr_equal(res, 'description', newdesc)
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
def test_7_hostgroup_del_member(self): def test_7_hostgroup_remove_member(self):
""" """
Test the `xmlrpc.hostgroup_del_member` method. Test the `xmlrpc.hostgroup_remove_member` method.
""" """
kw = {} kw = {}
kw['hosts'] = self.host_fqdn kw['hosts'] = self.host_fqdn
(total, failed, res) = api.Command['hostgroup_del_member'](self.cn, **kw) (total, failed, res) = api.Command['hostgroup_remove_member'](self.cn, **kw)
assert res assert res
assert res[1].get('member', []) == [] assert res[1].get('member', []) == []

View File

@@ -164,7 +164,7 @@ class test_netgroup(XMLRPC_test):
""" """
Test the `xmlrpc.netgroup_show` method. Test the `xmlrpc.netgroup_show` method.
""" """
(dn, res) = api.Command['netgroup_show'](self.ng_cn) (dn, res) = api.Command['netgroup_show'](self.ng_cn, all=True)
assert res assert res
assert_attr_equal(res, 'description', self.ng_description) assert_attr_equal(res, 'description', self.ng_description)
assert_attr_equal(res, 'cn', self.ng_cn) assert_attr_equal(res, 'cn', self.ng_cn)
@@ -172,6 +172,7 @@ class test_netgroup(XMLRPC_test):
assert_is_member(res, 'cn=%s' % self.hg_cn) assert_is_member(res, 'cn=%s' % self.hg_cn)
assert_is_member(res, 'uid=%s' % self.user_uid) assert_is_member(res, 'uid=%s' % self.user_uid)
assert_is_member(res, 'cn=%s' % self.group_cn) assert_is_member(res, 'cn=%s' % self.group_cn)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_7_netgroup_find(self): def test_7_netgroup_find(self):
""" """
@@ -198,56 +199,56 @@ class test_netgroup(XMLRPC_test):
assert_attr_equal(res, 'description', newdesc) assert_attr_equal(res, 'description', newdesc)
assert_attr_equal(res, 'cn', self.ng_cn) assert_attr_equal(res, 'cn', self.ng_cn)
def test_9_netgroup_del_member(self): def test_9_netgroup_remove_member(self):
""" """
Test the `xmlrpc.hostgroup_del_member` method. Test the `xmlrpc.hostgroup_remove_member` method.
""" """
kw = {} kw = {}
kw['hosts'] = self.host_fqdn kw['hosts'] = self.host_fqdn
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 1 assert total == 1
kw = {} kw = {}
kw['hostgroups'] = self.hg_cn kw['hostgroups'] = self.hg_cn
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 1 assert total == 1
kw = {} kw = {}
kw['users'] = self.user_uid kw['users'] = self.user_uid
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 1 assert total == 1
kw = {} kw = {}
kw['groups'] = self.group_cn kw['groups'] = self.group_cn
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 1 assert total == 1
def test_a_netgroup_del_member(self): def test_a_netgroup_remove_member(self):
""" """
Test the `xmlrpc.netgroup_del_member` method again to test not found. Test the `xmlrpc.netgroup_remove_member` method again to test not found.
""" """
kw = {} kw = {}
kw['hosts'] = self.host_fqdn kw['hosts'] = self.host_fqdn
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 0 assert total == 0
assert self.host_fqdn in failed assert self.host_fqdn in failed
kw = {} kw = {}
kw['hostgroups'] = self.hg_cn kw['hostgroups'] = self.hg_cn
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 0 assert total == 0
assert self.hg_cn in failed assert self.hg_cn in failed
kw = {} kw = {}
kw['users'] = self.user_uid kw['users'] = self.user_uid
(dn, res) = api.Command['netgroup_show'](self.ng_cn, all=True) (dn, res) = api.Command['netgroup_show'](self.ng_cn, all=True)
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 0 assert total == 0
assert self.user_uid in failed assert self.user_uid in failed
kw = {} kw = {}
kw['groups'] = self.group_cn kw['groups'] = self.group_cn
(total, failed, res) = api.Command['netgroup_del_member'](self.ng_cn, **kw) (total, failed, res) = api.Command['netgroup_remove_member'](self.ng_cn, **kw)
assert total == 0 assert total == 0
assert self.group_cn in failed assert self.group_cn in failed

View File

@@ -47,6 +47,7 @@ class test_passwd(XMLRPC_test):
assert_attr_equal(res, 'sn', self.sn) assert_attr_equal(res, 'sn', self.sn)
assert_attr_equal(res, 'uid', self.uid) assert_attr_equal(res, 'uid', self.uid)
assert_attr_equal(res, 'homedirectory', self.home) assert_attr_equal(res, 'homedirectory', self.home)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_set_passwd(self): def test_2_set_passwd(self):
""" """

View File

@@ -46,6 +46,7 @@ class test_rolegroup(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'description', self.description) assert_attr_equal(res, 'description', self.description)
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_add_group(self): def test_2_add_group(self):
""" """
@@ -102,13 +103,13 @@ class test_rolegroup(XMLRPC_test):
assert_attr_equal(res, 'description', newdesc) assert_attr_equal(res, 'description', newdesc)
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
def test_7_rolegroup_del_member(self): def test_7_rolegroup_remove_member(self):
""" """
Test the `xmlrpc.rolegroup_del_member` method. Test the `xmlrpc.rolegroup_remove_member` method.
""" """
kw = {} kw = {}
kw['groups'] = self.rolegroup_cn kw['groups'] = self.rolegroup_cn
(total, failed, res) = api.Command['rolegroup_del_member'](self.cn, **kw) (total, failed, res) = api.Command['rolegroup_remove_member'](self.cn, **kw)
assert total == 1 assert total == 1
def test_8_rolegroup_del(self): def test_8_rolegroup_del(self):

View File

@@ -42,6 +42,7 @@ class test_service(XMLRPC_test):
(dn, res) = api.Command['service_add'](**self.kw) (dn, res) = api.Command['service_add'](**self.kw)
assert res assert res
assert_attr_equal(res, 'krbprincipalname', self.principal) assert_attr_equal(res, 'krbprincipalname', self.principal)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_service_add(self): def test_2_service_add(self):
""" """

View File

@@ -49,6 +49,7 @@ class test_taskgroup(XMLRPC_test):
assert res assert res
assert_attr_equal(res, 'description', self.description) assert_attr_equal(res, 'description', self.description)
assert_attr_equal(res, 'cn', self.cn) assert_attr_equal(res, 'cn', self.cn)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_add_rolegroup(self): def test_2_add_rolegroup(self):
""" """
@@ -124,7 +125,7 @@ class test_taskgroup(XMLRPC_test):
""" """
kw = {} kw = {}
kw['groups'] = self.taskgroup_cn kw['groups'] = self.taskgroup_cn
(total, failed, res) = api.Command['taskgroup_del_member'](self.cn, **kw) (total, failed, res) = api.Command['taskgroup_remove_member'](self.cn, **kw)
assert total == 1 assert total == 1
def test_9_taskgroup_del(self): def test_9_taskgroup_del(self):

View File

@@ -48,6 +48,7 @@ class test_user(XMLRPC_test):
assert_attr_equal(res, 'sn', self.sn) assert_attr_equal(res, 'sn', self.sn)
assert_attr_equal(res, 'uid', self.uid) assert_attr_equal(res, 'uid', self.uid)
assert_attr_equal(res, 'homedirectory', self.home) assert_attr_equal(res, 'homedirectory', self.home)
assert_attr_equal(res, 'objectclass', 'ipaobject')
def test_2_user_add(self): def test_2_user_add(self):
""" """