Files
freeipa/ipalib/plugins/netgroup.py
T

293 lines
9.6 KiB
Python
Raw Normal View History

# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
#
# Copyright (C) 2009 Red Hat
# see file 'COPYING' for use and warranty information
#
2010-12-09 13:59:11 +01:00
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
2010-12-09 13:59:11 +01:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipalib import api, errors
from ipalib import Str, StrEnum
from ipalib.plugins.baseldap import *
from ipalib import _, ngettext
from ipalib.plugins.hbacrule import is_all
__doc__ = _("""
Netgroups
2010-06-02 14:08:50 -04:00
A netgroup is a group used for permission checking. It can contain both
user and host values.
EXAMPLES:
Add a new netgroup:
ipa netgroup-add --desc="NFS admins" admins
2010-06-02 14:08:50 -04:00
Add members to the netgroup:
2010-06-02 14:08:50 -04:00
ipa netgroup-add-member --users=tuser1,tuser2 admins
Remove a member from the netgroup:
2010-06-02 14:08:50 -04:00
ipa netgroup-remove-member --users=tuser2 admins
2011-05-04 10:26:18 +02:00
Display information about a netgroup:
2010-06-02 14:08:50 -04:00
ipa netgroup-show admins
Delete a netgroup:
2010-06-02 14:08:50 -04:00
ipa netgroup-del admins
""")
2012-05-04 10:25:42 +02:00
NETGROUP_PATTERN='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*$'
NETGROUP_PATTERN_ERRMSG='may only include letters, numbers, _, -, and .'
2012-03-27 15:15:20 +02:00
# according to most common use cases the netgroup pattern should fit
# also the nisdomain pattern
NISDOMAIN_PATTERN=NETGROUP_PATTERN
NISDOMAIN_PATTERN_ERRMSG=NETGROUP_PATTERN_ERRMSG
output_params = (
Str('memberuser_user?',
label='Member User',
),
Str('memberuser_group?',
label='Member Group',
),
Str('memberhost_host?',
label=_('Member Host'),
),
Str('memberhost_hostgroup?',
label='Member Hostgroup',
),
)
class netgroup(LDAPObject):
"""
Netgroup object.
"""
container_dn = api.env.container_netgroup
object_name = _('netgroup')
object_name_plural = _('netgroups')
object_class = ['ipaobject', 'ipaassociation', 'ipanisnetgroup']
2010-02-23 15:26:07 +01:00
default_attributes = [
'cn', 'description', 'memberof', 'externalhost', 'nisdomainname',
'memberuser', 'memberhost', 'member', 'memberindirect',
'usercategory', 'hostcategory',
2010-02-23 15:26:07 +01:00
]
uuid_attribute = 'ipauniqueid'
rdn_attribute = 'ipauniqueid'
attribute_members = {
'member': ['netgroup'],
'memberof': ['netgroup'],
'memberindirect': ['netgroup'],
'memberuser': ['user', 'group'],
'memberhost': ['host', 'hostgroup'],
}
relationships = {
'member': ('Member', '', 'no_'),
2011-01-06 17:14:13 -05:00
'memberof': ('Member Of', 'in_', 'not_in_'),
'memberindirect': (
'Indirect Member', None, 'no_indirect_'
),
'memberuser': ('Member', '', 'no_'),
'memberhost': ('Member', '', 'no_'),
}
2011-02-22 11:35:25 -05:00
label = _('Netgroups')
2011-07-13 21:10:47 -05:00
label_singular = _('Netgroup')
takes_params = (
Str('cn',
pattern=NETGROUP_PATTERN,
pattern_errmsg=NETGROUP_PATTERN_ERRMSG,
cli_name='name',
2010-02-19 09:08:16 -07:00
label=_('Netgroup name'),
primary_key=True,
normalizer=lambda value: value.lower(),
),
Str('description',
cli_name='desc',
2010-02-19 09:08:16 -07:00
label=_('Description'),
doc=_('Netgroup description'),
),
Str('nisdomainname?',
2012-03-27 15:15:20 +02:00
pattern=NISDOMAIN_PATTERN,
pattern_errmsg=NISDOMAIN_PATTERN_ERRMSG,
cli_name='nisdomain',
2010-02-19 09:08:16 -07:00
label=_('NIS domain name'),
),
2010-02-23 15:26:07 +01:00
Str('ipauniqueid?',
cli_name='uuid',
label='IPA unique ID',
2010-03-05 16:11:21 -05:00
doc=_('IPA unique ID'),
2010-02-23 15:26:07 +01:00
flags=['no_create', 'no_update'],
),
StrEnum('usercategory?',
cli_name='usercat',
label=_('User category'),
doc=_('User category the rule applies to'),
values=(u'all', ),
),
StrEnum('hostcategory?',
cli_name='hostcat',
label=_('Host category'),
doc=_('Host category the rule applies to'),
values=(u'all', ),
),
external_host_param,
)
api.register(netgroup)
class netgroup_add(LDAPCreate):
__doc__ = _('Add a new netgroup.')
has_output_params = LDAPCreate.has_output_params + output_params
msg_summary = _('Added netgroup "%(value)s"')
2012-02-01 16:33:54 +01:00
msg_collision = _(u'hostgroup with name "%s" already exists. ' \
u'Hostgroups and netgroups share a common namespace')
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
2012-05-13 07:36:35 -04:00
assert isinstance(dn, DN)
entry_attrs.setdefault('nisdomainname', self.api.env.domain)
2011-10-17 14:26:13 +02:00
try:
2012-02-06 13:47:39 +01:00
test_dn = self.obj.get_dn(keys[-1])
(test_dn_, netgroup) = ldap.get_entry(test_dn, ['objectclass'])
2012-02-01 16:33:54 +01:00
if 'mepManagedEntry' in netgroup.get('objectclass', []):
raise errors.DuplicateEntry(message=unicode(self.msg_collision % keys[-1]))
else:
self.obj.handle_duplicate_entry(*keys)
2011-10-17 14:26:13 +02:00
except errors.NotFound:
pass
try:
# when enabled, a managed netgroup is created for every hostgroup
# make sure that we don't create a collision if the plugin is
# (temporarily) disabled
netgroup = api.Command['hostgroup_show'](keys[-1])
2012-02-01 16:33:54 +01:00
raise errors.DuplicateEntry(message=unicode(self.msg_collision % keys[-1]))
2011-10-17 14:26:13 +02:00
except errors.NotFound:
pass
return dn
api.register(netgroup_add)
class netgroup_del(LDAPDelete):
__doc__ = _('Delete a netgroup.')
msg_summary = _('Deleted netgroup "%(value)s"')
api.register(netgroup_del)
class netgroup_mod(LDAPUpdate):
__doc__ = _('Modify a netgroup.')
has_output_params = LDAPUpdate.has_output_params + output_params
msg_summary = _('Modified netgroup "%(value)s"')
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
2012-05-13 07:36:35 -04:00
assert isinstance(dn, DN)
2012-03-27 09:27:11 -04:00
try:
(dn, entry_attrs) = ldap.get_entry(dn, attrs_list)
except errors.NotFound:
self.obj.handle_not_found(*keys)
if is_all(options, 'usercategory') and 'memberuser' in entry_attrs:
2012-07-04 08:52:47 -04:00
raise errors.MutuallyExclusiveError(reason=_("user category cannot be set to 'all' while there are allowed users"))
if is_all(options, 'hostcategory') and 'memberhost' in entry_attrs:
2012-07-04 08:52:47 -04:00
raise errors.MutuallyExclusiveError(reason=_("host category cannot be set to 'all' while there are allowed hosts"))
return dn
2009-06-16 14:38:27 +02:00
api.register(netgroup_mod)
class netgroup_find(LDAPSearch):
__doc__ = _('Search for a netgroup.')
member_attributes = ['member', 'memberuser', 'memberhost', 'memberof']
has_output_params = LDAPSearch.has_output_params + output_params
msg_summary = ngettext(
2011-02-23 16:47:49 -05:00
'%(count)d netgroup matched', '%(count)d netgroups matched', 0
)
takes_options = LDAPSearch.takes_options + (
Flag('private',
exclude='webui',
flags=['no_option', 'no_output'],
),
Flag('managed',
cli_name='managed',
doc=_('search for managed groups'),
default_from=lambda private: private,
),
)
def pre_callback(self, ldap, filter, attrs_list, base_dn, scope, *args, **options):
2012-05-13 07:36:35 -04:00
assert isinstance(base_dn, DN)
# Do not display private mepManagedEntry netgroups by default
# If looking for managed groups, we need to omit the negation search filter
search_kw = {}
search_kw['objectclass'] = ['mepManagedEntry']
if not options['managed']:
local_filter = ldap.make_filter(search_kw, rules=ldap.MATCH_NONE)
else:
local_filter = ldap.make_filter(search_kw, rules=ldap.MATCH_ALL)
filter = ldap.combine_filters((local_filter, filter), rules=ldap.MATCH_ALL)
return (filter, base_dn, scope)
2009-06-16 14:38:27 +02:00
api.register(netgroup_find)
class netgroup_show(LDAPRetrieve):
__doc__ = _('Display information about a netgroup.')
has_output_params = LDAPRetrieve.has_output_params + output_params
2009-06-16 14:38:27 +02:00
api.register(netgroup_show)
class netgroup_add_member(LDAPAddMember):
__doc__ = _('Add members to a netgroup.')
member_attributes = ['memberuser', 'memberhost', 'member']
has_output_params = LDAPAddMember.has_output_params + output_params
2012-03-27 15:15:20 +02:00
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
2012-05-13 07:36:35 -04:00
assert isinstance(dn, DN)
2012-03-27 15:15:20 +02:00
return add_external_pre_callback('host', ldap, dn, keys, options)
2012-05-13 07:36:35 -04:00
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
2012-05-13 07:36:35 -04:00
assert isinstance(dn, DN)
return add_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
2009-06-16 14:38:27 +02:00
api.register(netgroup_add_member)
class netgroup_remove_member(LDAPRemoveMember):
__doc__ = _('Remove members from a netgroup.')
member_attributes = ['memberuser', 'memberhost', 'member']
has_output_params = LDAPRemoveMember.has_output_params + output_params
def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
2012-05-13 07:36:35 -04:00
assert isinstance(dn, DN)
return remove_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options)
api.register(netgroup_remove_member)