diff options
-rw-r--r-- | freeipa.spec.in | 7 | ||||
-rw-r--r-- | install/html/Makefile.am | 1 | ||||
-rw-r--r-- | install/html/hbac-deny-remove.html | 82 | ||||
-rw-r--r-- | install/ui/hbac.js | 53 | ||||
-rw-r--r-- | install/ui/ipa.css | 5 | ||||
-rw-r--r-- | install/ui/ipa.js | 9 | ||||
-rwxr-xr-x | install/ui/test/bin/update_ipa_init.sh | 2 | ||||
-rw-r--r-- | install/ui/test/data/hbacrule_find.json | 58 | ||||
-rw-r--r-- | install/ui/test/data/ipa_init.json | 64 | ||||
-rw-r--r-- | install/ui/webui.js | 6 | ||||
-rw-r--r-- | install/ui/widget.js | 5 |
11 files changed, 261 insertions, 31 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in index 5ba38cb02..276001ae6 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -261,6 +261,8 @@ ln -s ../../../..%{_sysconfdir}/ipa/html/unauthorized.html \ %{buildroot}%{_usr}/share/ipa/html/unauthorized.html ln -s ../../../..%{_sysconfdir}/ipa/html/browserconfig.html \ %{buildroot}%{_usr}/share/ipa/html/browserconfig.html +ln -s ../../../..%{_sysconfdir}/ipa/html/hbac-deny-remove.html \ + %{buildroot}%{_usr}/share/ipa/html/hbac-deny-remove.html ln -s ../../../..%{_sysconfdir}/ipa/html/ipa_error.css \ %{buildroot}%{_usr}/share/ipa/html/ipa_error.css @@ -386,6 +388,7 @@ fi %{_usr}/share/ipa/html/ssbrowser.html %{_usr}/share/ipa/html/browserconfig.html %{_usr}/share/ipa/html/unauthorized.html +%{_usr}/share/ipa/html/hbac-deny-remove.html %{_usr}/share/ipa/html/ipa_error.css %dir %{_usr}/share/ipa/migration %{_usr}/share/ipa/migration/error.html @@ -412,6 +415,7 @@ fi %config(noreplace) %{_sysconfdir}/ipa/html/ipa_error.css %config(noreplace) %{_sysconfdir}/ipa/html/unauthorized.html %config(noreplace) %{_sysconfdir}/ipa/html/browserconfig.html +%config(noreplace) %{_sysconfdir}/ipa/html/hbac-deny-remove.html %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-rewrite.conf %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa.conf %{_usr}/share/ipa/ipa.conf @@ -500,6 +504,9 @@ fi %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf %changelog +* Wed Jul 6 2011 Adam Young <ayoung@redhat.com> - 2.0.90-5 +- Add HTML file describing issues with HBAC deny rules + * Fri Jun 17 2011 Rob Crittenden <rcritten@redhat.com> - 2.0.90-4 - Ship ipa-ca-install utility diff --git a/install/html/Makefile.am b/install/html/Makefile.am index 46e8683c8..c310be6d2 100644 --- a/install/html/Makefile.am +++ b/install/html/Makefile.am @@ -5,6 +5,7 @@ app_DATA = \ ssbrowser.html \ browserconfig.html \ unauthorized.html \ + hbac-deny-remove.html \ ipa_error.css \ $(NULL) diff --git a/install/html/hbac-deny-remove.html b/install/html/hbac-deny-remove.html new file mode 100644 index 000000000..987819cd2 --- /dev/null +++ b/install/html/hbac-deny-remove.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> + <title>IPA: Identity Policy Audit</title> + + <script type="text/javascript" src="../ui/jquery.js"></script> + + <link rel="stylesheet" type="text/css" href="../ui/jquery-ui.css" /> + <link rel="stylesheet" type="text/css" href="ipa_error.css" /> + + +</head> + +<body id="header-bg"> + + <div class="container_1"> + <div class="header-logo"> + <img src="../ui/ipalogo.png" /> + </div> + <div class="textblockkrb"> + <h1>Removal of HBAC Deny Rules.</h1> + <p>FreeIPA has dropped support for DENY rules from the HBAC + specification. </p> + <p>The former design of HBAC specifies that<p> + <ol> + <li> If no ALLOW rules match, access is denied</li> + <li> If one or more ALLOW rules match and no DENY rules match, + access is allowed</li> + <li>If one or more DENY rules match, access is denied</li> + </ol> + <p>Thus, DENY rules exist only to provide exceptions from the ALLOW + rules. There exists no ALLOW+DENY combination that cannot be + constructed from ALLOW rules only.[1]</P> + + <p>DENY rules introduce a lot of edge-cases for evaluation. The most + important of which is the availability of the group membership for + the user logging in. Depending on the mechanism used to log in (for + example, GSSAPI over SSH or cross-realm Kerberos trust where the + user is provided by the PAC), SSSD's cache may not have a complete + list of groups for this user. If the login is occurring during + offline mode (where SSSD cannot contact the LDAP server to refresh + the user's groups), SSSD cannot determine whether DENY rules would + match for the user. This therefore translates into a potential + security issue.</p> + + <p>We implemented a workaround in the SSSD evaluator to resolve this by + guaranteeing that we do a full lookup of all groups referenced by + rules while we are retrieving the rules from FreeIPA. However, this + requires at least one additional lookup against the LDAP server + (possibly many if there is need to resolve nestings). This results + in a significantly slower login while online.</p> + + <p>We also have issues related to source host evaluation. Some + applications will provide an IP address instead of a hostname in the + pam_rhost attribute. Our only recourse here is to perform a + reverse-DNS lookup to try and identify the real hostname(s) of the + server. However, in many real-world environments, reverse DNS is + unavailable or misconfigured. In the case of ALLOW rules, this would + lead to a match failure and an implicit denial. However, a failure + to properly match a DENY rule can result in unexpected access being + granted. This is a potentially serious security issue.</p> + + <p>Given these edge cases (and performance issues of the noted + workaround), The FreeIPA team decided to drop DENY rules from the + HBAC specification and limit HBAC only to ALLOW rules (which are + much safer). Beyond the obvious advantages for our implementation, + this should make it less complex for users to write their rules.</p> + + <p>[1] Some rules are complex to simulate, such as "Allow access from + all PAM services EXCEPT telnet". But a safer and clearer + implementation approach does all access via whitelist. If a FreeIPA + implementation is using an exception rule, the administrators + should re-evaluate the justification. + </p> + </div> + + </div> + +</body> + +</html> diff --git a/install/ui/hbac.js b/install/ui/hbac.js index c082056bb..dc85d572b 100644 --- a/install/ui/hbac.js +++ b/install/ui/hbac.js @@ -26,7 +26,21 @@ IPA.entity_factories.hbacrule = function () { return IPA.entity_builder(). entity('hbacrule'). search_facet({ - columns:['cn','usercategory','hostcategory','ipaenabledflag', + columns:['cn', + { + factory: IPA.column, + name:'accessruletype', + setup : function(container,record){ + container.empty(); + var value = record[this.name]; + value = value ? value.toString() : ''; + if (value === 'deny'){ + container.addClass('hbac-deny-rule'); + } + container.append(value); + } + }, + 'usercategory','hostcategory','ipaenabledflag', 'servicecategory','sourcehostcategory'] }). details_facet({ @@ -996,3 +1010,40 @@ IPA.hbacrule_accesstime_widget = function (spec) { return that; }; + +IPA.hbac_deny_warning_dialog = function (container) { + var dialog = IPA.dialog({ + 'title': 'HBAC Deny Rules found' + }); + + var link_path = "config"; + if (IPA.use_static_files){ + link_path = "html"; + } + + dialog.create = function() { + dialog.container.append( + "HBAC rules with type deny have been found."+ + " These rules have been deprecated." + + " Please remove them, and restructure the HBAC rules." ); + $('<p/>').append($('<a/>',{ + text: 'Click here for more information', + href: '../' +link_path +'/hbac-deny-remove.html', + target: "_blank", + style: 'target: tab; color: blue; ' + })).appendTo(dialog.container); + }; + + dialog.add_button('Edit HBAC Rules', function() { + dialog.close(); + IPA.nav.show_page('hbacrule', 'search'); + }); + + dialog.add_button('Ignore for now', function() { + dialog.close(); + }); + + dialog.init(); + + dialog.open(); +}; diff --git a/install/ui/ipa.css b/install/ui/ipa.css index 38b5a9118..c3215ef35 100644 --- a/install/ui/ipa.css +++ b/install/ui/ipa.css @@ -645,6 +645,11 @@ div.tabs { padding-left: 0.5em; } +.hbac-deny-rule { + color: red; +} + + .search-table tfoot td { padding: 0.5em 0 0 1em; border-top: 1px solid #dfdfdf; diff --git a/install/ui/ipa.js b/install/ui/ipa.js index 4f194739b..4b505235b 100644 --- a/install/ui/ipa.js +++ b/install/ui/ipa.js @@ -123,6 +123,15 @@ var IPA = ( function () { } })); + batch.add_command(IPA.command({ + entity: 'hbacrule', + method: 'find', + options:{"accessruletype":"deny"}, + on_success: function(data, text_status, xhr) { + that.hbac_deny_rules = data; + } + })); + batch.execute(); }; diff --git a/install/ui/test/bin/update_ipa_init.sh b/install/ui/test/bin/update_ipa_init.sh index 5cdeacaa4..23852a269 100755 --- a/install/ui/test/bin/update_ipa_init.sh +++ b/install/ui/test/bin/update_ipa_init.sh @@ -17,4 +17,4 @@ fi -curl -v -H "Content-Type:application/json" -H "Accept:applicaton/json" --negotiate -u : --cacert /etc/ipa/ca.crt -d '{"method":"batch","params":[[ {"method":"json_metadata","params":[[],{}]}, {"method":"i18n_messages","params":[[],{}]}, {"method":"user_find","params":[[],{"whoami":"true","all":"true"}]}, {"method":"env","params":[[],{}]}, {"method":"dns_is_enabled","params":[[],{}]} ],{}],"id":1}' -X POST https://`hostname`/ipa/json | sed 's/[ \t]*$//' > $INIT_FILE +curl -v -H "Content-Type:application/json" -H "Accept:applicaton/json" --negotiate -u : --cacert /etc/ipa/ca.crt -d '{"method":"batch","params":[[{"method":"json_metadata","params":[[],{}]},{"method":"i18n_messages","params":[[],{}]},{"method":"user_find","params":[[],{"whoami":true,"all":true}]},{"method":"env","params":[[],{}]},{"method":"dns_is_enabled","params":[[],{}]},{"method":"hbacrule_find","params":[[],{"accessruletype":"deny"}]}],{}]}' -X POST https://`hostname`/ipa/json | sed 's/[ \t]*$//' > $INIT_FILE diff --git a/install/ui/test/data/hbacrule_find.json b/install/ui/test/data/hbacrule_find.json index fd95d9f57..3801a7d44 100644 --- a/install/ui/test/data/hbacrule_find.json +++ b/install/ui/test/data/hbacrule_find.json @@ -1,54 +1,74 @@ { - "error": null, - "id": 0, + "error": null, + "id": null, "result": { - "count": 2, + "count": 4, "result": [ { "accessruletype": [ "allow" - ], + ], "cn": [ "allow_all" - ], + ], "description": [ "Allow all users to access any host from any host" - ], - "dn": "ipauniqueid=b7567b5a-e39311df-bfde9b13-2b28c216,cn=hbac,dc=dev,dc=example,dc=com", + ], + "dn": "ipauniqueid=ca842a42-a445-11e0-87ff-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", "hostcategory": [ "all" - ], + ], "ipaenabledflag": [ "TRUE" - ], + ], "servicecategory": [ "all" - ], + ], "sourcehostcategory": [ "all" - ], + ], "usercategory": [ "all" ] }, { "accessruletype": [ - "allow" + "deny" + ], + "cn": [ + "deny1" ], - "accesstime": [ - "periodic daily 0800-1400", - "absolute 201012161032 ~ 201012161033" + "dn": "ipauniqueid=8af3e23c-a7e2-11e0-b394-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", + "ipaenabledflag": [ + "TRUE" + ] + }, + { + "accessruletype": [ + "deny" + ], + "cn": [ + "deny2" + ], + "dn": "ipauniqueid=8f05d042-a7e2-11e0-b394-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", + "ipaenabledflag": [ + "TRUE" + ] + }, + { + "accessruletype": [ + "deny" ], "cn": [ - "test" + "deny3" ], - "dn": "ipauniqueid=3b6d2a82-e3b511df-bfde9b13-2b28c216,cn=hbac,dc=dev,dc=example,dc=com", + "dn": "ipauniqueid=92dcf9fc-a7e2-11e0-8dac-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", "ipaenabledflag": [ "TRUE" ] } - ], - "summary": null, + ], + "summary": "4 HBAC rules matched", "truncated": false } } diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json index 5b4dadfca..a67002105 100644 --- a/install/ui/test/data/ipa_init.json +++ b/install/ui/test/data/ipa_init.json @@ -1,8 +1,8 @@ { "error": null, - "id": 1, + "id": null, "result": { - "count": 5, + "count": 6, "results": [ { "error": null, @@ -8266,7 +8266,8 @@ "ipausersearchfields", "ipagroupsearchfields", "ipamigrationenabled", - "ipacertificatesubjectbase" + "ipacertificatesubjectbase", + "ipapwdexpadvnotify" ], "hidden_attributes": [ "objectclass", @@ -12117,7 +12118,7 @@ "aciattrs": [], "attribute_members": {}, "bindable": false, - "container_dn": "cn=IDM.LAB.BOS.REDHAT.COM,cn=kerberos", + "container_dn": "cn=SERVER15.AYOUNG.BOSTON.DEVEL.REDHAT.COM,cn=kerberos", "default_attributes": [ "krbmaxticketlife", "krbmaxrenewableage" @@ -12962,7 +12963,7 @@ ], "attribute_members": {}, "bindable": false, - "container_dn": "cn=IDM.LAB.BOS.REDHAT.COM,cn=kerberos", + "container_dn": "cn=SERVER15.AYOUNG.BOSTON.DEVEL.REDHAT.COM,cn=kerberos", "default_attributes": [ "cn", "cospriority", @@ -15887,17 +15888,17 @@ ], "krbextradata": [ { - "__base64__": "AAL2bA5Ocm9vdC9hZG1pbkBTRVJWRVIxNS5BWU9VTkcuQk9TVE9OLkRFVkVMLlJFREhBVC5DT00A" + "__base64__": "AAgBAA==" }, { - "__base64__": "AAgBAA==" + "__base64__": "AAL2bA5Ocm9vdC9hZG1pbkBTRVJWRVIxNS5BWU9VTkcuQk9TVE9OLkRFVkVMLlJFREhBVC5DT00A" } ], "krblastpwdchange": [ "20110702005726Z" ], "krblastsuccessfulauth": [ - "20110705172822Z" + "20110705180548Z" ], "krbpasswordexpiration": [ "20110930005726Z" @@ -16017,6 +16018,53 @@ "result": true, "summary": null, "value": "" + }, + { + "count": 3, + "error": null, + "result": [ + { + "accessruletype": [ + "deny" + ], + "cn": [ + "deny1" + ], + "dn": "ipauniqueid=8af3e23c-a7e2-11e0-b394-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", + "ipaenabledflag": [ + "TRUE" + ], + "memberuser_user": [ + "abrown" + ] + }, + { + "accessruletype": [ + "deny" + ], + "cn": [ + "deny2" + ], + "dn": "ipauniqueid=8f05d042-a7e2-11e0-b394-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", + "ipaenabledflag": [ + "TRUE" + ] + }, + { + "accessruletype": [ + "deny" + ], + "cn": [ + "deny3" + ], + "dn": "ipauniqueid=92dcf9fc-a7e2-11e0-8dac-525400b55a47,cn=hbac,dc=server15,dc=ayoung,dc=boston,dc=devel,dc=redhat,dc=com", + "ipaenabledflag": [ + "TRUE" + ] + } + ], + "summary": "3 HBAC rules matched", + "truncated": false } ] } diff --git a/install/ui/webui.js b/install/ui/webui.js index 2c4451489..01d060fcf 100644 --- a/install/ui/webui.js +++ b/install/ui/webui.js @@ -158,6 +158,12 @@ $(function() { IPA.nav.update(); $('#login_header').html(IPA.messages.login.header); + + if (IPA.hbac_deny_rules && IPA.hbac_deny_rules.count > 0){ + if (IPA.nav.name === 'admin'){ + IPA.hbac_deny_warning_dialog(); + } + } } diff --git a/install/ui/widget.js b/install/ui/widget.js index cd3a5c60e..9142a26a9 100644 --- a/install/ui/widget.js +++ b/install/ui/widget.js @@ -1156,7 +1156,7 @@ IPA.column = function (spec) { } }; - that.setup = function(container, record) { + function setup(container, record) { container.empty(); var value = record[that.name]; @@ -1177,8 +1177,9 @@ IPA.column = function (spec) { } else { container.append(value); } + } - }; + that.setup = spec.setup || setup; that.link_handler = function(value) { return false; |