summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Babej <tbabej@redhat.com>2014-05-14 13:09:28 +0200
committerPetr Viktorin <pviktori@redhat.com>2014-06-25 20:14:49 +0200
commit9304b649a32c57e80f53913d7fbdee92fd76a251 (patch)
tree7d87ea988f69bd644d7dd839ea7087f74e3dde32
parenta228d7a3cb32b14ff24b47adb14d896d317f6312 (diff)
downloadfreeipa-9304b649a32c57e80f53913d7fbdee92fd76a251.tar.gz
freeipa-9304b649a32c57e80f53913d7fbdee92fd76a251.tar.xz
freeipa-9304b649a32c57e80f53913d7fbdee92fd76a251.zip
sudorule: Allow using external groups as groups of runAsUsers
Adds a new attribute ipaSudoRunAsExtUserGroup and corresponding hooks sudorule plugin. https://fedorahosted.org/freeipa/ticket/4263 Reviewed-By: Petr Viktorin <pviktori@redhat.com>
-rw-r--r--ACI.txt4
-rw-r--r--install/share/65ipasudo.ldif4
-rw-r--r--install/share/schema_compat.uldif1
-rw-r--r--install/updates/10-schema_compat.update1
-rw-r--r--ipalib/plugins/sudorule.py54
5 files changed, 57 insertions, 7 deletions
diff --git a/ACI.txt b/ACI.txt
index f61c0f18c..22b10e3dd 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -207,9 +207,9 @@ aci: (targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:Sy
dn: cn=System: Delete Sudo rule,cn=permissions,cn=pbac,dc=ipa,dc=example
aci: (targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:System: Delete Sudo rule";allow (delete) groupdn = "ldap:///cn=System: Delete Sudo rule,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=System: Modify Sudo rule,cn=permissions,cn=pbac,dc=ipa,dc=example
-aci: (targetattr = "cmdcategory || description || externalhost || externaluser || hostcategory || hostmask || ipaenabledflag || ipasudoopt || ipasudorunas || ipasudorunasextgroup || ipasudorunasextuser || ipasudorunasgroup || ipasudorunasgroupcategory || ipasudorunasusercategory || memberallowcmd || memberdenycmd || memberhost || memberuser || sudonotafter || sudonotbefore || sudoorder || usercategory")(targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:System: Modify Sudo rule";allow (write) groupdn = "ldap:///cn=System: Modify Sudo rule,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetattr = "cmdcategory || description || externalhost || externaluser || hostcategory || hostmask || ipaenabledflag || ipasudoopt || ipasudorunas || ipasudorunasextgroup || ipasudorunasextuser || ipasudorunasextusergroup || ipasudorunasgroup || ipasudorunasgroupcategory || ipasudorunasusercategory || memberallowcmd || memberdenycmd || memberhost || memberuser || sudonotafter || sudonotbefore || sudoorder || usercategory")(targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:System: Modify Sudo rule";allow (write) groupdn = "ldap:///cn=System: Modify Sudo rule,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=System: Read Sudo Rules,cn=permissions,cn=pbac,dc=ipa,dc=example
-aci: (targetattr = "cmdcategory || cn || description || externalhost || externaluser || hostcategory || hostmask || ipaenabledflag || ipasudoopt || ipasudorunas || ipasudorunasextgroup || ipasudorunasextuser || ipasudorunasgroup || ipasudorunasgroupcategory || ipasudorunasusercategory || ipauniqueid || member || memberallowcmd || memberdenycmd || memberhost || memberuser || objectclass || sudonotafter || sudonotbefore || sudoorder || usercategory")(targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:System: Read Sudo Rules";allow (compare,read,search) userdn = "ldap:///all";)
+aci: (targetattr = "cmdcategory || cn || description || externalhost || externaluser || hostcategory || hostmask || ipaenabledflag || ipasudoopt || ipasudorunas || ipasudorunasextgroup || ipasudorunasextuser || ipasudorunasextusergroup || ipasudorunasgroup || ipasudorunasgroupcategory || ipasudorunasusercategory || ipauniqueid || member || memberallowcmd || memberdenycmd || memberhost || memberuser || objectclass || sudonotafter || sudonotbefore || sudoorder || usercategory")(targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:System: Read Sudo Rules";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=System: Read Sudoers compat tree,cn=permissions,cn=pbac,dc=ipa,dc=example
aci: (targetattr = "cn || description || objectclass || ou || sudocommand || sudohost || sudonotafter || sudonotbefore || sudooption || sudoorder || sudorunas || sudorunasgroup || sudorunasuser || sudouser")(target = "ldap:///ou=sudoers,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read Sudoers compat tree";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=System: Read Trust Information,cn=permissions,cn=pbac,dc=ipa,dc=example
diff --git a/install/share/65ipasudo.ldif b/install/share/65ipasudo.ldif
index 3ad103f8a..8895b0dd7 100644
--- a/install/share/65ipasudo.ldif
+++ b/install/share/65ipasudo.ldif
@@ -31,8 +31,10 @@ attributeTypes: (2.16.840.1.113730.3.8.7.11 NAME 'ipaSudoRunAsGroupCategory' DES
attributeTypes: (2.16.840.1.113730.3.8.7.12 NAME 'hostMask' DESC 'IP mask to identify a subnet.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v2' )
## Attribute to store sudo command
attributeTypes: (2.16.840.1.113730.3.8.7.13 NAME 'sudoCmd' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactMatch ORDERING caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v2' )
+## Attribute to store a name of the user not managed by IPA. Command witll be executed under his identity.
+attributeTypes: (2.16.840.1.113730.3.8.7.14 NAME 'ipaSudoRunAsExtUserGroup' DESC 'Multivalue string attribute that allows storing groups of users that are not managed by IPA the command can be run as' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v4' )
## Object class for SUDO rules
-objectClasses: (2.16.840.1.113730.3.8.8.1 NAME 'ipaSudoRule' SUP ipaAssociation STRUCTURAL MAY ( externalUser $ externalHost $ hostMask $ memberAllowCmd $ memberDenyCmd $ cmdCategory $ ipaSudoOpt $ ipaSudoRunAs $ ipaSudoRunAsExtUser $ ipaSudoRunAsUserCategory $ ipaSudoRunAsGroup $ ipaSudoRunAsExtGroup $ ipaSudoRunAsGroupCategory $ sudoNotBefore $ sudoNotAfter $ sudoOrder ) X-ORIGIN 'IPA v2' )
+objectClasses: (2.16.840.1.113730.3.8.8.1 NAME 'ipaSudoRule' SUP ipaAssociation STRUCTURAL MAY ( externalUser $ externalHost $ hostMask $ memberAllowCmd $ memberDenyCmd $ cmdCategory $ ipaSudoOpt $ ipaSudoRunAs $ ipaSudoRunAsExtUser $ ipaSudoRunAsUserCategory $ ipaSudoRunAsGroup $ ipaSudoRunAsExtGroup $ ipaSudoRunAsGroupCategory $ sudoNotBefore $ sudoNotAfter $ sudoOrder $ ipaSudoRunAsExtUserGroup ) X-ORIGIN 'IPA v2' )
## Object class for SUDO commands
objectClasses: (2.16.840.1.113730.3.8.8.2 NAME 'ipaSudoCmd' DESC 'IPA object class for SUDO command' STRUCTURAL MUST ( ipaUniqueID $ sudoCmd ) MAY ( memberOf $ description ) X-ORIGIN 'IPA v2' )
## Object class for groups of the SUDO commands
diff --git a/install/share/schema_compat.uldif b/install/share/schema_compat.uldif
index 3d2681d64..79fce21b0 100644
--- a/install/share/schema_compat.uldif
+++ b/install/share/schema_compat.uldif
@@ -92,6 +92,7 @@ add:schema-compat-entry-attribute: 'sudoCommand=%ifeq("cmdCategory","all","ALL",
add:schema-compat-entry-attribute: 'sudoCommand=!%deref("memberDenyCmd","sudoCmd")'
add:schema-compat-entry-attribute: 'sudoCommand=!%deref_r("memberDenyCmd","member","sudoCmd")'
add:schema-compat-entry-attribute: 'sudoRunAsUser=%{ipaSudoRunAsExtUser}'
+add:schema-compat-entry-attribute: 'sudoRunAsUser=%%%{ipaSudoRunAsExtUserGroup}'
add:schema-compat-entry-attribute: 'sudoRunAsUser=%deref("ipaSudoRunAs","uid")'
add:schema-compat-entry-attribute: 'sudoRunAsUser=%ifeq("ipaSudoRunAsUserCategory","all","ALL","%%%deref_f(\"ipaSudoRunAs\",\"(objectclass=posixGroup)\",\"cn\")")'
add:schema-compat-entry-attribute: 'sudoRunAsGroup=%{ipaSudoRunAsExtGroup}'
diff --git a/install/updates/10-schema_compat.update b/install/updates/10-schema_compat.update
index c45734c55..6f0ed9080 100644
--- a/install/updates/10-schema_compat.update
+++ b/install/updates/10-schema_compat.update
@@ -4,6 +4,7 @@ replace: schema-compat-entry-attribute:'sudoRunAsGroup=%deref("ipaSudoRunAs","cn
dn: cn=sudoers,cn=Schema Compatibility,cn=plugins,cn=config
add:schema-compat-entry-attribute: 'sudoHost=%ifeq("hostCategory","all","ALL","%{hostMask}")'
+add:schema-compat-entry-attribute: 'sudoRunAsUser=%%%{ipaSudoRunAsExtUserGroup}'
# Change padding for host and userCategory so the pad returns the same value
# as the original, '' or -.
diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py
index a304373b3..935ffded7 100644
--- a/ipalib/plugins/sudorule.py
+++ b/ipalib/plugins/sudorule.py
@@ -132,7 +132,7 @@ class sudorule(LDAPObject):
'memberallowcmd', 'memberdenycmd', 'ipasudoopt',
'ipasudorunas', 'ipasudorunasgroup',
'ipasudorunasusercategory', 'ipasudorunasgroupcategory',
- 'sudoorder', 'hostmask',
+ 'sudoorder', 'hostmask', 'ipasudorunasextusergroup',
]
uuid_attribute = 'ipauniqueid'
rdn_attribute = 'ipauniqueid'
@@ -153,7 +153,8 @@ class sudorule(LDAPObject):
'cmdcategory', 'cn', 'description', 'externalhost',
'externaluser', 'hostcategory', 'hostmask', 'ipaenabledflag',
'ipasudoopt', 'ipasudorunas', 'ipasudorunasextgroup',
- 'ipasudorunasextuser', 'ipasudorunasgroup',
+ 'ipasudorunasextuser', 'ipasudorunasextusergroup',
+ 'ipasudorunasgroup',
'ipasudorunasgroupcategory', 'ipasudorunasusercategory',
'ipauniqueid', 'memberallowcmd', 'memberdenycmd',
'memberhost', 'memberuser', 'sudonotafter', 'sudonotbefore',
@@ -193,6 +194,7 @@ class sudorule(LDAPObject):
'description', 'ipaenabledflag', 'usercategory',
'hostcategory', 'cmdcategory', 'ipasudorunasusercategory',
'ipasudorunasgroupcategory', 'externaluser',
+ 'ipasudorunasextusergroup',
'ipasudorunasextuser', 'ipasudorunasextgroup', 'memberdenycmd',
'memberallowcmd', 'memberuser', 'memberhost', 'externalhost',
'sudonotafter', 'hostmask', 'sudoorder', 'sudonotbefore',
@@ -318,6 +320,12 @@ class sudorule(LDAPObject):
label=_('RunAs External User'),
doc=_('External User the commands can run as (sudorule-find only)'),
),
+ Str('ipasudorunasextusergroup?',
+ cli_name='runasexternalusergroup',
+ label=_('External Groups of RunAs Users'),
+ doc=_('External Groups of users that the command can run as'),
+ flags=['no_create', 'no_update', 'no_search'],
+ ),
Str('ipasudorunasextgroup?', validate_runasextgroup,
cli_name='runasexternalgroup',
label=_('RunAs External Group'),
@@ -731,7 +739,26 @@ class sudorule_add_runasuser(LDAPAddMember):
def post_callback(self, ldap, completed, failed, dn, entry_attrs,
*keys, **options):
assert isinstance(dn, DN)
- return add_external_post_callback('ipasudorunas', 'user', 'ipasudorunasextuser', ldap, completed, failed, dn, entry_attrs, keys, options)
+
+ # Since external_post_callback returns the total number of completed
+ # entries yet (that is, any external users it added plus the value of
+ # passed variable 'completed', we need to pass 0 as completed,
+ # so that the entries added by the framework are not counted twice
+ # (once in each call of add_external_post_callback)
+
+ (completed_ex_users, dn) = add_external_post_callback(
+ 'ipasudorunas', 'user',
+ 'ipasudorunasextuser',
+ ldap, 0, failed, dn, entry_attrs,
+ keys, options)
+
+ (completed_ex_groups, dn) = add_external_post_callback(
+ 'ipasudorunas', 'group',
+ 'ipasudorunasextusergroup',
+ ldap, 0, failed, dn, entry_attrs,
+ keys, options)
+
+ return (completed + completed_ex_users + completed_ex_groups, dn)
@register()
@@ -744,7 +771,26 @@ class sudorule_remove_runasuser(LDAPRemoveMember):
def post_callback(self, ldap, completed, failed, dn, entry_attrs,
*keys, **options):
assert isinstance(dn, DN)
- return remove_external_post_callback('ipasudorunas', 'user', 'ipasudorunasextuser', ldap, completed, failed, dn, entry_attrs, keys, options)
+
+ # Since external_post_callback returns the total number of completed
+ # entries yet (that is, any external users it added plus the value of
+ # passed variable 'completed', we need to pass 0 as completed,
+ # so that the entries added by the framework are not counted twice
+ # (once in each call of remove_external_post_callback)
+
+ (completed_ex_users, dn) = remove_external_post_callback(
+ 'ipasudorunas', 'user',
+ 'ipasudorunasextuser',
+ ldap, 0, failed, dn, entry_attrs,
+ keys, options)
+
+ (completed_ex_groups, dn) = remove_external_post_callback(
+ 'ipasudorunas', 'group',
+ 'ipasudorunasextusergroup',
+ ldap, 0, failed, dn, entry_attrs,
+ keys, options)
+
+ return (completed + completed_ex_users + completed_ex_groups, dn)
@register()