Enable transactions by default, make password and modrdn TXN-aware

The password and modrdn plugins needed to be made transaction aware
for the pre and post operations.

Remove the reverse member hoop jumping. Just fetch the entry once
and all the memberof data is there (plus objectclass).

Fix some unit tests that are failing because we actually get the data
now due to transactions.

Add small bit of code in user plugin to retrieve the user again
ala wait_for_attr but in the case of transactions we need do it only
once.

Deprecate wait_for_attr code.

Add a memberof fixup task for roles.

https://fedorahosted.org/freeipa/ticket/1263
https://fedorahosted.org/freeipa/ticket/1891
https://fedorahosted.org/freeipa/ticket/2056
https://fedorahosted.org/freeipa/ticket/3043
https://fedorahosted.org/freeipa/ticket/3191
https://fedorahosted.org/freeipa/ticket/3046
This commit is contained in:
Rob Crittenden 2012-11-15 21:38:26 -05:00 committed by Martin Kosek
parent 2093007d4d
commit f1f1b4e7f2
27 changed files with 186 additions and 116 deletions

View File

@ -201,6 +201,12 @@ ipamodrdn_init(Slapi_PBlock *pb)
{
int status = EOK;
char *plugin_identity = NULL;
Slapi_Entry *plugin_entry = NULL;
char *plugin_type = NULL;
int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
int modfn = SLAPI_PLUGIN_POST_MODIFY_FN;
int addfn = SLAPI_PLUGIN_POST_ADD_FN;
LOG_TRACE("--in-->\n");
@ -213,6 +219,18 @@ ipamodrdn_init(Slapi_PBlock *pb)
PR_ASSERT(plugin_identity);
setPluginID(plugin_identity);
if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
plugin_entry &&
(plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) &&
plugin_type && strstr(plugin_type, "betxn"))
{
addfn = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN;
mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
modfn = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
}
slapi_ch_free_string(&plugin_type);
if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
SLAPI_PLUGIN_VERSION_01) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
@ -221,13 +239,13 @@ ipamodrdn_init(Slapi_PBlock *pb)
(void *) ipamodrdn_start) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
(void *) ipamodrdn_close) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
slapi_pblock_set(pb, addfn,
(void *) ipamodrdn_config_check_post_op) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
slapi_pblock_set(pb, mdnfn,
(void *) ipamodrdn_post_op) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
slapi_pblock_set(pb, delfn,
(void *) ipamodrdn_config_check_post_op) != 0 ||
slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
slapi_pblock_set(pb, modfn,
(void *) ipamodrdn_config_check_post_op) != 0) {
LOG_FATAL("failed to register plugin\n");
status = EFAIL;

View File

@ -6,7 +6,7 @@ objectclass: extensibleObject
cn: IPA MODRDN
nsslapd-pluginpath: libipa_modrdn
nsslapd-plugininitfunc: ipamodrdn_init
nsslapd-plugintype: postoperation
nsslapd-plugintype: betxnpostoperation
nsslapd-pluginenabled: on
nsslapd-pluginid: ipamodrdn_version
nsslapd-pluginversion: 1.0

View File

@ -1270,6 +1270,15 @@ static char *ipapwd_name_list[] = {
int ipapwd_init( Slapi_PBlock *pb )
{
int ret;
Slapi_Entry *plugin_entry = NULL;
int is_betxn = 0;
/* get args */
if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
plugin_entry) {
is_betxn = slapi_entry_attr_get_bool(plugin_entry,
"nsslapd-pluginbetxn");
}
/* Get the arguments appended to the plugin extendedop directive. The first argument
* (after the standard arguments for the directive) should contain the OID of the
@ -1301,6 +1310,18 @@ int ipapwd_init( Slapi_PBlock *pb )
return -1;
}
if (is_betxn) {
slapi_register_plugin("betxnpreoperation", 1,
"ipapwd_pre_init_betxn", ipapwd_pre_init_betxn,
"IPA pwd pre ops betxn", NULL,
ipapwd_plugin_id);
slapi_register_plugin("betxnpostoperation", 1,
"ipapwd_post_init_betxn", ipapwd_post_init_betxn,
"IPA pwd post ops betxn", NULL,
ipapwd_plugin_id);
}
slapi_register_plugin("preoperation", 1,
"ipapwd_pre_init", ipapwd_pre_init,
"IPA pwd pre ops", NULL,

View File

@ -152,4 +152,6 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
int ipapwd_ext_init(void);
int ipapwd_pre_init(Slapi_PBlock *pb);
int ipapwd_post_init(Slapi_PBlock *pb);
int ipapwd_pre_init_betxn(Slapi_PBlock *pb);
int ipapwd_post_init_betxn(Slapi_PBlock *pb);

View File

@ -1307,6 +1307,19 @@ int ipapwd_pre_init(Slapi_PBlock *pb)
return ret;
}
int ipapwd_pre_init_betxn(Slapi_PBlock *pb)
{
int ret;
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN, (void *)ipapwd_pre_bind);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN, (void *)ipapwd_pre_add);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN, (void *)ipapwd_pre_mod);
return ret;
}
/* Init post ops */
int ipapwd_post_init(Slapi_PBlock *pb)
{
@ -1320,3 +1333,14 @@ int ipapwd_post_init(Slapi_PBlock *pb)
return ret;
}
int ipapwd_post_init_betxn(Slapi_PBlock *pb)
{
int ret;
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_POST_ADD_FN, (void *)ipapwd_post_op);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN, (void *)ipapwd_post_op);
return ret;
}

View File

@ -7,6 +7,7 @@ cn: ipa_pwd_extop
nsslapd-pluginpath: libipa_pwd_extop
nsslapd-plugininitfunc: ipapwd_init
nsslapd-plugintype: extendedop
nsslapd-pluginbetxn: on
nsslapd-pluginenabled: on
nsslapd-pluginid: ipa_pwd_extop
nsslapd-pluginversion: 1.0

View File

@ -113,7 +113,7 @@ Requires(pre): systemd-units
Requires(post): systemd-units
Requires: selinux-policy >= 3.10.0-110
Requires(post): selinux-policy-base
Requires: slapi-nis >= 0.40
Requires: slapi-nis >= 0.44
%if 0%{?fedora} >= 18
Requires: pki-ca >= 10.0.0-0.52.b3
Requires: dogtag-pki-server-theme
@ -733,6 +733,9 @@ fi
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
%changelog
* Fri Nov 16 2012 Rob Crittenden <rcritten@redhat.com> - 3.0.99-5
- Bump minimum version of slapi-nis to 0.44
* Wed Nov 14 2012 Martin Kosek <mkosek@redhat.com> - 3.0.99-4
- Remove compatibility definitions for unsupported Fedora versions (Fedora 16 and lower)
- Do not require specific package version when the package was available in Fedora 17

View File

@ -6,6 +6,7 @@ default:cn: NIS Server
default:nsslapd-pluginpath: /usr/lib$LIBARCH/dirsrv/plugins/nisserver-plugin.so
default:nsslapd-plugininitfunc: nis_plugin_init
default:nsslapd-plugintype: object
default:nsslapd-pluginbetxn: on
default:nsslapd-pluginenabled: on
default:nsslapd-pluginid: nis-server
default:nsslapd-pluginversion: 0.10

View File

@ -14,6 +14,7 @@ default:nsslapd-plugintype: object
default:nsslapd-pluginenabled: on
default:nsslapd-pluginid: schema-compat-plugin
default:nsslapd-pluginversion: 0.8
default:nsslapd-pluginbetxn: on
default:nsslapd-pluginvendor: redhat.com
default:nsslapd-plugindescription: Schema Compatibility Plugin

View File

@ -37,6 +37,7 @@ There are 7 keywords:
* add: add a value (or values) to an attribute
* remove: remove a value (or values) from an attribute
* only: set an attribute to this
* onlyifexist: set an attribute to this only if the entry exists
* deleteentry: remove the entry
* replace: replace an existing value, format is old: new
* addifnew: add a new attribute and value only if the attribute doesn't already exist. Only works with single\-value attributes.

View File

@ -738,7 +738,6 @@
"startup_traceback": false,
"validate_api": false,
"verbose": 0,
"wait_for_attr": false,
"webui_assets_dir": null,
"webui_prod": true,
"xmlrpc_uri": "https://dev.example.com/ipa/xml"

View File

@ -1,37 +0,0 @@
# Disable transactions in 389-ds-base
dn: cn=7-bit check,cn=plugins,cn=config
only: nsslapd-pluginType: preoperation
dn: cn=attribute uniqueness,cn=plugins,cn=config
only: nsslapd-pluginType: preoperation
dn: cn=Auto Membership Plugin,cn=plugins,cn=config
only: nsslapd-pluginType: preoperation
dn: cn=Linked Attributes,cn=plugins,cn=config
only: nsslapd-pluginType: preoperation
dn: cn=Managed Entries,cn=plugins,cn=config
only: nsslapd-pluginType: preoperation
dn: cn=MemberOf Plugin,cn=plugins,cn=config
only: nsslapd-pluginType: postoperation
dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config
only: nsslapd-pluginbetxn: off
dn: cn=PAM Pass Through Auth,cn=plugins,cn=config
only: nsslapd-pluginType: preoperation
dn: cn=referential integrity postoperation,cn=plugins,cn=config
only: nsslapd-pluginType: postoperation
dn: cn=Roles Plugin,cn=plugins,cn=config
only: nsslapd-pluginbetxn: off
dn: cn=State Change Plugin,cn=plugins,cn=config
only: nsslapd-pluginType: postoperation
dn: cn=USN,cn=plugins,cn=config
only: nsslapd-pluginbetxn: off

View File

@ -0,0 +1,49 @@
# Enable transactions in 389-ds-base
dn: cn=7-bit check,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpreoperation
dn: cn=attribute uniqueness,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpreoperation
dn: cn=Auto Membership Plugin,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpreoperation
dn: cn=Linked Attributes,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpreoperation
dn: cn=Managed Entries,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpreoperation
dn: cn=MemberOf Plugin,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpostoperation
dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config
only: nsslapd-pluginbetxn: on
dn: cn=PAM Pass Through Auth,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpreoperation
dn: cn=referential integrity postoperation,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpostoperation
dn: cn=Roles Plugin,cn=plugins,cn=config
only: nsslapd-pluginbetxn: on
dn: cn=State Change Plugin,cn=plugins,cn=config
only: nsslapd-pluginType: betxnpostoperation
dn: cn=USN,cn=plugins,cn=config
only: nsslapd-pluginbetxn: on
dn: cn=IPA MODRDN,cn=plugins,cn=config
only: nsslapd-plugintype: betxnpostoperation
dn: cn=ipa_pwd_extop,cn=plugins,cn=config
only: nsslapd-pluginbetxn: on
dn: cn=Schema Compatibility, cn=plugins, cn=config
onlyifexist: nsslapd-pluginbetxn: on
dn: cn=NIS Server, cn=plugins, cn=config
onlyifexist: nsslapd-pluginbetxn: on

View File

@ -8,3 +8,11 @@ add: cn: IPA PBAC memberOf $TIME
add: basedn: 'cn=privileges,cn=pbac,$SUFFIX'
add: filter: (objectclass=*)
add: ttl: 10
dn: cn=Update Role memberOf $TIME, cn=memberof task, cn=tasks, cn=config
add: objectClass: top
add: objectClass: extensibleObject
add: cn: Update Role memberOf $TIME
add: basedn: 'cn=roles,cn=accounts,$SUFFIX'
add: filter: (objectclass=*)
add: ttl: 10

View File

@ -7,7 +7,7 @@ app_DATA = \
10-RFC2307bis.update \
10-RFC4876.update \
10-config.update \
10-disable-betxn.update \
10-enable-betxn.update \
10-selinuxusermap.update \
10-sudo.update \
10-ssh.update \

View File

@ -178,9 +178,6 @@ Used internally in the IPA source package to verify that the API has not changed
.B verbose <boolean>
When True provides more information. Specifically this sets the global log level to "info".
.TP
.B wait_for_attr <boolean>
Debug option. Waits for asynchronous execution of 389-ds postoperation plugins before returning data to the client, therefore data added by postoperation plugins is included in the result. Increases execution time.
.TP
.B xmlrpc_uri <URI>
Specifies the URI of the XML\-RPC server for a client. This is used by IPA and some external tools as well, such as ipa\-getcert. e.g. https://ipa.example.com/ipa/xml
.TP

View File

@ -157,7 +157,6 @@ DEFAULT_CONFIG = (
# Enable certain optional plugins:
('enable_ra', False),
('ra_plugin', 'selfsign'),
('wait_for_attr', False),
('dogtag_version', 9),
# Used when verifying that the API hasn't changed. Not for production.

View File

@ -231,50 +231,6 @@ def entry_from_entry(entry, newentry):
for e in newentry:
entry[e] = newentry[e]
def wait_for_memberof(keys, entry_start, completed, show_command, adding=True):
"""
When adding or removing reverse members we are faking an update to
object A by updating the member attribute in object B. The memberof
plugin makes this work by adding or removing the memberof attribute
to/from object A, it just takes a little bit of time.
This will loop for 6+ seconds, retrieving object A so we can see
if all the memberof attributes have been updated.
"""
if completed == 0:
# nothing to do
return api.Command[show_command](keys[-1])['result']
if 'memberof' in entry_start:
starting_memberof = len(entry_start['memberof'])
else:
starting_memberof = 0
# Loop a few times to give the memberof plugin a chance to add the
# entries. Don't sleep for more than 6 seconds.
memberof = 0
x = 0
while x < 20:
# sleep first because the first search, even on a quiet system,
# almost always fails to have memberof set.
time.sleep(.3)
x = x + 1
# FIXME: put a try/except around here? I think it is probably better
# to just let the exception filter up to the caller.
entry_attrs = api.Command[show_command](keys[-1])['result']
if 'memberof' in entry_attrs:
memberof = len(entry_attrs['memberof'])
if adding:
if starting_memberof + completed >= memberof:
break
else:
if starting_memberof + completed <= memberof:
break
return entry_attrs
def wait_for_value(ldap, dn, attr, value):
"""
389-ds postoperation plugins are executed after the data has been
@ -2029,11 +1985,9 @@ class LDAPAddReverseMember(LDAPModReverseMember):
except errors.PublicError, e:
failed['member'][self.reverse_attr].append((attr, unicode(msg)))
# Wait for the memberof plugin to update the entry
try:
entry_attrs = wait_for_memberof(keys, entry_start, completed, self.show_command, adding=True)
except Exception, e:
raise errors.ReverseMemberError(verb=_('added'), exc=str(e))
# Update the member data.
(dn, entry_attrs) = ldap.get_entry(dn, ['*'])
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
for callback in self.get_callbacks('post'):
(completed, dn) = callback(
@ -2131,11 +2085,9 @@ class LDAPRemoveReverseMember(LDAPModReverseMember):
except errors.PublicError, e:
failed['member'][self.reverse_attr].append((attr, unicode(msg)))
# Wait for the memberof plugin to update the entry
try:
entry_attrs = wait_for_memberof(keys, entry_start, completed, self.show_command, adding=False)
except Exception, e:
raise errors.ReverseMemberError(verb=_('removed'), exc=str(e))
# Update the member data.
(dn, entry_attrs) = ldap.get_entry(dn, ['*'])
self.obj.convert_attribute_members(entry_attrs, *keys, **options)
for callback in self.get_callbacks('post'):
(completed, dn) = callback(

View File

@ -115,6 +115,7 @@ class permission(LDAPObject):
]
attribute_members = {
'member': ['privilege'],
'memberindirect': ['role'],
}
rdn_is_primary_key = True

View File

@ -547,9 +547,6 @@ class user_add(LDAPCreate):
except errors.AlreadyGroupMember:
pass
if self.api.env.wait_for_attr:
newentry = wait_for_value(ldap, dn, 'memberOf', def_primary_group)
entry_from_entry(entry_attrs, newentry)
self.obj._convert_manager(entry_attrs, **options)
# delete description attribute NO_UPG_MAGIC if present
if options.get('noprivate', False):
@ -563,10 +560,11 @@ class user_add(LDAPCreate):
self.api.Command['user_mod'](keys[-1], **kw)
except (errors.EmptyModlist, errors.NotFound):
pass
else:
if self.api.env.wait_for_attr:
newentry = wait_for_value(ldap, dn, 'objectclass', 'mepOriginEntry')
entry_from_entry(entry_attrs, newentry)
# Fetch the entry again to update memberof, mep data, etc updated
# at the end of the transaction.
(newdn, newentry) = ldap.get_entry(dn, ['*'])
entry_attrs.update(newentry)
if options.get('random', False):
try:

View File

@ -202,7 +202,6 @@ class DsInstance(service.Service):
self.step("configuring replication version plugin", self.__config_version_module)
self.step("enabling IPA enrollment plugin", self.__add_enrollment_module)
self.step("enabling ldapi", self.__enable_ldapi)
self.step("disabling betxn plugins", self.__disable_betxn)
self.step("configuring uniqueness plugin", self.__set_unique_attrs)
self.step("configuring uuid plugin", self.__config_uuid_module)
self.step("configuring modrdn plugin", self.__config_modrdn_module)
@ -476,9 +475,6 @@ class DsInstance(service.Service):
def __add_referint_module(self):
self._ldap_mod("referint-conf.ldif")
def __disable_betxn(self):
self._ldap_mod("disable-betxn.ldif", self.sub_dict)
def __set_unique_attrs(self):
self._ldap_mod("unique-attributes.ldif", self.sub_dict)

View File

@ -59,7 +59,7 @@ class BadSyntax(installutils.ScriptError):
return repr(self.value)
class LDAPUpdate:
action_keywords = ["default", "add", "remove", "only", "deleteentry", "replace", "addifnew", "addifexist"]
action_keywords = ["default", "add", "remove", "only", "onlyifexist", "deleteentry", "replace", "addifnew", "addifexist"]
def __init__(self, dm_password, sub_dict={}, live_run=True,
online=True, ldapi=False, plugins=False):
@ -623,6 +623,18 @@ class LDAPUpdate:
only[attr] = True
entry.setValues(attr, entry_values)
self.debug('only: updated value %s', entry_values)
elif action == 'onlyifexist':
self.debug("onlyifexist: '%s' to %s, current value %s", update_value, attr, entry_values)
# Only set the attribute if the entry exist's. We
# determine this based on whether it has an objectclass
if entry.getValues('objectclass'):
if only.get(attr):
entry_values.append(update_value)
else:
entry_values = [update_value]
only[attr] = True
self.debug('onlyifexist: set %s to %s', attr, entry_values)
entry.setValues(attr, entry_values)
elif action == 'deleteentry':
# skip this update type, it occurs in __delete_entries()
return None

View File

@ -886,6 +886,8 @@ class test_automember(Declarative):
objectclass=objectclasses.host,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn1],
memberof_hostgroup=[hostgroup1],
memberofindirect_netgroup=[hostgroup1],
),
),
),
@ -914,6 +916,8 @@ class test_automember(Declarative):
objectclass=objectclasses.host,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn2],
memberof_hostgroup=[defaulthostgroup1],
memberofindirect_netgroup=[defaulthostgroup1],
),
),
),
@ -942,6 +946,8 @@ class test_automember(Declarative):
objectclass=objectclasses.host,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn3],
memberof_hostgroup=[hostgroup2],
memberofindirect_netgroup=[hostgroup2],
),
),
),
@ -970,6 +976,8 @@ class test_automember(Declarative):
objectclass=objectclasses.host,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn4],
memberof_hostgroup=[hostgroup3],
memberofindirect_netgroup=[hostgroup3],
),
),
),
@ -998,6 +1006,8 @@ class test_automember(Declarative):
objectclass=objectclasses.host,
ipauniqueid=[fuzzy_uuid],
managedby_host=[fqdn5],
memberof_hostgroup=[hostgroup4],
memberofindirect_netgroup=[hostgroup4],
),
),
),

View File

@ -750,6 +750,7 @@ class test_nesting(Declarative):
'cn': [hostgroup1],
'description': [u'Test hostgroup 1'],
'member_hostgroup': [hostgroup2],
'memberindirect_host': [fqdn1],
},
),
),

View File

@ -194,6 +194,7 @@ class test_permission(Declarative):
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
'objectclass': objectclasses.privilege,
}
),
),
@ -501,10 +502,10 @@ class test_permission(Declarative):
api.env.container_permission, api.env.basedn),
'cn': [u'Modify HBAC rule'],
'member_privilege': [u'HBAC Administrator'],
'memberindirect_role': [u'IT Security Specialist'],
'permissions' : [u'write'],
'attrs': [u'servicecategory', u'sourcehostcategory', u'cn', u'description', u'ipaenabledflag', u'accesstime', u'usercategory', u'hostcategory', u'accessruletype', u'sourcehost'],
'subtree' : u'ldap:///%s' % DN(('ipauniqueid', '*'), ('cn', 'hbac'), api.env.basedn),
'memberindirect': [DN(('cn', 'it security specialist'), ('cn', 'roles'), ('cn', 'accounts'), api.env.basedn)],
},
],
),

View File

@ -142,6 +142,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1],
'objectclass': objectclasses.privilege,
}
),
),
@ -240,6 +241,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1, permission2],
'objectclass': objectclasses.privilege,
}
),
),
@ -262,6 +264,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'privilege desc. 1'],
'memberof_permission': [permission1, permission2],
'objectclass': objectclasses.privilege,
}
),
),
@ -320,6 +323,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'New desc 1'],
'memberof_permission': [permission2],
'objectclass': objectclasses.privilege,
}
),
),
@ -342,6 +346,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'New desc 1'],
'memberof_permission': [permission2],
'objectclass': objectclasses.privilege,
}
),
),
@ -364,6 +369,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'New desc 1'],
'memberof_permission': [permission2],
'objectclass': objectclasses.privilege,
}
),
),
@ -386,6 +392,7 @@ class test_privilege(Declarative):
'cn': [privilege1],
'description': [u'New desc 1'],
'memberof_permission': [permission2],
'objectclass': objectclasses.privilege,
}
),
),

View File

@ -196,6 +196,7 @@ class test_role(Declarative):
'cn': [role1],
'description': [u'role desc 1'],
'memberof_privilege': [privilege1],
'objectclass': objectclasses.role,
}
),
),
@ -217,6 +218,7 @@ class test_role(Declarative):
'cn': [role1],
'description': [u'role desc 1'],
'memberof_privilege': [privilege1],
'objectclass': objectclasses.role,
}
),
),
@ -238,6 +240,7 @@ class test_role(Declarative):
'cn': [role1],
'description': [u'role desc 1'],
'memberof_privilege': [privilege1],
'objectclass': objectclasses.role,
}
),
),
@ -518,6 +521,7 @@ class test_role(Declarative):
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'objectclass': objectclasses.role,
}
),
),
@ -539,6 +543,7 @@ class test_role(Declarative):
'dn': role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'objectclass': objectclasses.role,
}
),
),