summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorJr Aquino <jr.aquino@citrix.com>2010-12-17 08:29:33 -0800
committerRob Crittenden <rcritten@redhat.com>2010-12-21 12:29:46 -0500
commitfc8f7f9da837605d2d83e99783fcbc74e1306dfe (patch)
tree562054fa5e21c76bf2864aef7bd5d1b24c711621 /ipalib
parentdd9615d18938cf30a5cc328c80386baea0c78234 (diff)
downloadfreeipa-fc8f7f9da837605d2d83e99783fcbc74e1306dfe.tar.gz
freeipa-fc8f7f9da837605d2d83e99783fcbc74e1306dfe.tar.xz
freeipa-fc8f7f9da837605d2d83e99783fcbc74e1306dfe.zip
SUDO plugin support for external hosts and users https://fedorahosted.org/freeipa/ticket/570
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugins/sudorule.py195
1 files changed, 191 insertions, 4 deletions
diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index 3fabdfefa..a5aaa5730 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -25,6 +25,7 @@ from ipalib import Str, StrEnum
from ipalib.plugins.baseldap import *
from ipalib import _, ngettext
+
class sudorule(LDAPObject):
"""
Sudo Rule.
@@ -96,7 +97,7 @@ class sudorule(LDAPObject):
doc=_('Run As Group category the rule applies to'),
values=(u'all', ),
),
- Str('memberuser_user?',
+ Str('memberuser_user?',
label=_('Users'),
flags=['no_create', 'no_update', 'no_search'],
),
@@ -124,15 +125,19 @@ class sudorule(LDAPObject):
label=_('Sudo Command Groups'),
flags=['no_create', 'no_update', 'no_search'],
),
- Str('ipasudorunas_user?',
+ Str('ipasudorunas_user?',
label=_('Run As User'),
flags=['no_create', 'no_update', 'no_search'],
),
- Str('ipasudorunasgroup_group?',
+ Str('ipasudorunasgroup_group?',
label=_('Run As Group'),
flags=['no_create', 'no_update', 'no_search'],
),
-
+ Str('externaluser?',
+ cli_name='externaluser',
+ label=_('External User'),
+ doc=_('External User the rule applies to'),
+ ),
)
api.register(sudorule)
@@ -283,6 +288,32 @@ class sudorule_add_user(LDAPAddMember):
member_attributes = ['memberuser']
member_count_out = ('%i object added.', '%i objects added.')
+ def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
+ completed_external = 0
+ # Sift through the user failures. We assume that these are all
+ # users that aren't stored in IPA, aka external users.
+ if 'memberuser' in failed and 'user' in failed['memberuser']:
+ (dn, entry_attrs_) = ldap.get_entry(dn, ['externaluser'])
+ members = entry_attrs.get('memberuser', [])
+ external_users = entry_attrs_.get('externaluser', [])
+ failed_users = []
+ for user in failed['memberuser']['user']:
+ username = user[0].lower()
+ user_dn = self.api.Object['user'].get_dn(username)
+ if username not in external_users and user_dn not in members:
+ external_users.append(username)
+ completed_external += 1
+ else:
+ failed_users.append(username)
+ if completed_external:
+ try:
+ ldap.update_entry(dn, {'externaluser': external_users})
+ except errors.EmptyModlist:
+ pass
+ failed['memberuser']['user'] = failed_users
+ entry_attrs['externaluser'] = external_users
+ return (completed + completed_external, dn)
+
api.register(sudorule_add_user)
@@ -293,6 +324,30 @@ class sudorule_remove_user(LDAPRemoveMember):
member_attributes = ['memberuser']
member_count_out = ('%i object removed.', '%i objects removed.')
+ def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
+ # Run through the user failures and gracefully remove any defined as
+ # as an externaluser.
+ if 'memberuser' in failed and 'user' in failed['memberuser']:
+ (dn, entry_attrs) = ldap.get_entry(dn, ['externaluser'])
+ external_users = entry_attrs.get('externaluser', [])
+ failed_users = []
+ completed_external = 0
+ for user in failed['memberuser']['user']:
+ username = user[0].lower()
+ if username in external_users:
+ external_users.remove(username)
+ completed_external += 1
+ else:
+ failed_users.append(username)
+ if completed_external:
+ try:
+ ldap.update_entry(dn, {'externaluser': external_users})
+ except errors.EmptyModlist:
+ pass
+ failed['memberuser']['user'] = failed_users
+ entry_attrs['externaluser'] = external_users
+ return (completed + completed_external, dn)
+
api.register(sudorule_remove_user)
@@ -303,6 +358,32 @@ class sudorule_add_host(LDAPAddMember):
member_attributes = ['memberhost']
member_count_out = ('%i object added.', '%i objects added.')
+ def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
+ completed_external = 0
+ # Sift through the host failures. We assume that these are all
+ # hosts that aren't stored in IPA, aka external hosts.
+ if 'memberhost' in failed and 'host' in failed['memberhost']:
+ (dn, entry_attrs_) = ldap.get_entry(dn, ['externalhost'])
+ members = entry_attrs.get('memberhost', [])
+ external_hosts = entry_attrs_.get('externalhost', [])
+ failed_hosts = []
+ for host in failed['memberhost']['host']:
+ hostname = host[0].lower()
+ host_dn = self.api.Object['host'].get_dn(hostname)
+ if hostname not in external_hosts and host_dn not in members:
+ external_hosts.append(hostname)
+ completed_external += 1
+ else:
+ failed_hosts.append(hostname)
+ if completed_external:
+ try:
+ ldap.update_entry(dn, {'externalhost': external_hosts})
+ except errors.EmptyModlist:
+ pass
+ failed['memberhost']['host'] = failed_hosts
+ entry_attrs['externalhost'] = external_hosts
+ return (completed + completed_external, dn)
+
api.register(sudorule_add_host)
@@ -313,6 +394,30 @@ class sudorule_remove_host(LDAPRemoveMember):
member_attributes = ['memberhost']
member_count_out = ('%i object removed.', '%i objects removed.')
+ def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options):
+ # Run through the host failures and gracefully remove any defined as
+ # as an externalhost.
+ if 'memberhost' in failed and 'host' in failed['memberhost']:
+ (dn, entry_attrs) = ldap.get_entry(dn, ['externalhost'])
+ external_hosts = entry_attrs.get('externalhost', [])
+ failed_hosts = []
+ completed_external = 0
+ for host in failed['memberhost']['host']:
+ hostname = host[0].lower()
+ if hostname in external_hosts:
+ external_hosts.remove(hostname)
+ completed_external += 1
+ else:
+ failed_hosts.append(hostname)
+ if completed_external:
+ try:
+ ldap.update_entry(dn, {'externalhost': external_hosts})
+ except errors.EmptyModlist:
+ pass
+ failed['memberhost']['host'] = failed_hosts
+ entry_attrs['externalhost'] = external_hosts
+ return (completed + completed_external, dn)
+
api.register(sudorule_remove_host)
@@ -354,3 +459,85 @@ class sudorule_remove_runasgroup(LDAPRemoveMember):
member_count_out = ('%i object removed.', '%i objects removed.')
api.register(sudorule_remove_runasgroup)
+
+
+class sudorule_add_option(LDAPQuery):
+ """
+ Add an option to the Sudo rule.
+ """
+
+ takes_options = (
+ Str('ipasudoopt',
+ cli_name='sudooption',
+ label=_('Sudo Option'),
+ ),
+ )
+
+ def execute(self, cn, **options):
+ ldap = self.obj.backend
+
+ dn = self.obj.get_dn(cn)
+
+ (dn, entry_attrs) = ldap.get_entry(dn, ['ipasudoopt'])
+
+ entry_attrs.setdefault('ipasudoopt', []).append(
+ options['ipasudoopt']
+ )
+ try:
+ ldap.update_entry(dn, entry_attrs)
+ except errors.EmptyModlist:
+ pass
+ except errors.NotFound:
+ self.obj.handle_not_found(cn)
+
+ return dict(result=entry_attrs)
+
+ def output_for_cli(self, textui, result, cn, **options):
+ textui.print_name(self.name)
+ textui.print_dashed(
+ 'Added option "%s" to Sudo rule "%s"' % (
+ options['ipasudoopt'], cn
+ )
+ )
+
+api.register(sudorule_add_option)
+
+
+class sudorule_remove_option(LDAPQuery):
+ """
+ Remove an option from Sudo rule.
+ """
+ takes_options = (
+ Str('ipasudoopt?',
+ cli_name='sudooption',
+ label=_('Sudo Option'),
+ ),
+ )
+
+ def execute(self, cn, **options):
+ ldap = self.obj.backend
+
+ dn = self.obj.get_dn(cn)
+
+ (dn, entry_attrs) = ldap.get_entry(dn, ['ipasudoopt'])
+ try:
+ entry_attrs.setdefault('ipasudoopt', []).remove(
+ options['ipasudoopt']
+ )
+ ldap.update_entry(dn, entry_attrs)
+ except (ValueError, errors.EmptyModlist):
+ pass
+ except errors.NotFound:
+ self.obj.handle_not_found(cn)
+
+ return dict(result=True)
+
+ def output_for_cli(self, textui, result, cn, **options):
+ textui.print_name(self.name)
+ textui.print_dashed(
+ 'Removed option "%s" from Sudo rule "%s"' % (
+ options['ipasudoopt'], cn
+ )
+ )
+
+api.register(sudorule_remove_option)