[Freeipa-devel] [PATCH] Resolve SIDs in Web UI

Alexander Bokovoy abokovoy at redhat.com
Sat May 4 05:13:17 UTC 2013


On Fri, 03 May 2013, Sumit Bose wrote:
>On Fri, May 03, 2013 at 09:46:47PM +0300, Alexander Bokovoy wrote:
>> Hi!
>>
>> Attached are patches to allow resolving SIDs in Web UI in external
>> membership panel for groups. Please see more detailed description in the
>> main patch.
>>
>> I haven't rebased it yet on top of Petr's Web UI rework, hopefully it
>> should be simple.
>>
>> https://fedorahosted.org/freeipa/ticket/3302
>>
>> Since framework doesn't allow to hide commands from CLI, underlying
>> command is usable from CLI too:
>> # ipa trust-resolve --sids=S-1-5-21-3502988750-125904550-3683905862-{500,512,498}
>>  Name: enterprise read-only domain controllers at ad.lan
>>  SID: S-1-5-21-3502988750-125904550-3683905862-498
>>
>>  Name: administrator at ad.lan
>>  SID: S-1-5-21-3502988750-125904550-3683905862-500
>>
>>  Name: domain admins at ad.lan
>>  SID: S-1-5-21-3502988750-125904550-3683905862-512
>>
>> --
>> / Alexander Bokovoy
>> +        try:
>> +            sids = map(lambda x: str(x), options['sids'])
>> +            xlate = pysss_nss_idmap.getnamebysid(sids)
>
>The latest version, which is already committed to sssd, return a dict.
>The output of ipa trust-resolve now look like:
>
>[root at ipa18-devel ~]# ipa trust-resolve --sids=S-1-5-21-3090815309-2627318493-3395719201-{498,500,513}
>  Name: {'type': 3, 'name': u'administrator at ad18.ipa18.devel'}
>  SID: S-1-5-21-3090815309-2627318493-3395719201-500
>
>  Name: {'type': 2, 'name': u'enterprise read-only domain controllers at ad18.ipa18.devel'}
>  SID: S-1-5-21-3090815309-2627318493-3395719201-498
>
>  Name: {'type': 2, 'name': u'domain users at ad18.ipa18.devel'}
>  SID: S-1-5-21-3090815309-2627318493-3395719201-513
>
>> +            for sid in xlate:
>> +	       entry = dict()
>> +               entry['sid'] = [unicode(sid)]
>> +               entry['name'] = [unicode(xlate[sid])]
>
>I think you need  entry['name'] = [unicode(xlate[sid][pysss_nss_idmap.NAME_KEY])]
>here.
Fixed, thanks!
I also added type conversion to a text (user, group, both). The type is not shown by default
in CLI but is available through --all option. We might consider using it
in Web UI for visual hint about the name nature.

>I tried with firefox, but the SIDs of the external members are not
>resolved. Do I have to clean any firefox cache?
No, you do not. When picking up changes from my development VM, I
omitted one chunk in group.js where sid_facet was actually taken in use.
Without that one nothing is used.

Updated patch 0103 is attached, tested against sssd in ipa-devel repo
which already includes your patches.
-- 
/ Alexander Bokovoy
-------------- next part --------------
>From d2bab4c42487ca57557ce19d1b6b90a1fd220566 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Tue, 30 Apr 2013 13:13:25 +0300
Subject: [PATCH 3/3] Resolve SIDs in Web UI

Introduce new command, 'trust-resolve', to aid resolving SIDs to names
in the Web UI.

The command uses new SSSD interface, nss_idmap, to resolve actual SIDs.
SSSD caches resolved data so that future requests to resolve same SIDs
are returned from a memory cache.

Web UI code is using Dojo/Deferred to deliver result of SID resolution
out of band. Once resolved names are available, they replace SID values.

Since Web UI only shows ~20 records per page, up to 20 SIDs are resolved
at the same time. They all sent within the single request to the server.

https://fedorahosted.org/freeipa/ticket/3302
---
 API.txt                               |  7 +++++
 freeipa.spec.in                       |  4 +++
 install/ui/src/freeipa/association.js | 45 +++++++++++++++++++++++++++-
 install/ui/src/freeipa/entity.js      | 10 ++++++-
 install/ui/src/freeipa/facet.js       | 12 ++++++++
 install/ui/src/freeipa/group.js       |  4 +--
 ipalib/plugins/trust.py               | 56 +++++++++++++++++++++++++++++++++++
 7 files changed, 134 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index c2400e9..e5bb7be 100644
--- a/API.txt
+++ b/API.txt
@@ -3398,6 +3398,13 @@ option: Str('version?', exclude='webui')
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('value', <type 'unicode'>, None)
+command: trust_resolve
+args: 0,4,1
+option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
+option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
+option: Str('sids+', csv=True)
+option: Str('version?', exclude='webui')
+output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list of LDAP entries', domain='ipa', localedir=None))
 command: trust_show
 args: 1,4,3
 arg: Str('cn', attribute=True, cli_name='realm', multivalue=False, primary_key=True, query=True, required=True)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 36e2a61..1f97418 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -211,6 +211,7 @@ Requires: samba4
 Requires: samba4-winbind
 %endif
 Requires: libsss_idmap
+Requires: libsss_nss_idmap-python
 # We use alternatives to divert winbind_krb5_locator.so plugin to libkrb5
 # on the installes where server-trust-ad subpackage is installed because
 # IPA AD trusts cannot be used at the same time with the locator plugin
@@ -839,6 +840,9 @@ fi
 %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
 
 %changelog
+* Fri May 03 2013 Alexander Bokovoy <abokovoy at redhat.com> - 3.1.99-10
+- Add libsss_nss_idmap-python dependency for SID resolution
+
 * Tue Apr 30 2013 Rob Crittenden <rcritten at redhat.com> - 3.1.99-9
 - Add Conflicts on nss-pam-ldapd < 0.8.4. The mapping from uniqueMember to
   member is now done automatically and having it in the config file raises
diff --git a/install/ui/src/freeipa/association.js b/install/ui/src/freeipa/association.js
index c6b9e5a..dad138f 100644
--- a/install/ui/src/freeipa/association.js
+++ b/install/ui/src/freeipa/association.js
@@ -22,7 +22,7 @@
 /* CURRENTLY ALSO REQUIRES search.js, because it reuses it's code to create
  * the AssociationList elements; IT NEEDS IT'S OWN CODE! */
 
-define(['./ipa', './jquery', './search', './dialog'], function(IPA, $) {
+define(['dojo/Deferred','./ipa', './jquery', './search', './dialog'], function(Deferred, IPA, $) {
 
 IPA.associator = function (spec) {
 
@@ -1355,6 +1355,49 @@ IPA.attribute_facet = function(spec, no_init) {
     return that;
 };
 
+IPA.sid_facet = function(spec, no_init) {
+
+    spec.name = spec.name || 'sid_facet';
+
+    var that = IPA.attribute_facet(spec, no_init);
+
+    that.load_records = function(value) {
+        var xlate = {}
+        var sidxlate_command = IPA.command({
+            entity: 'trust',
+            method: 'resolve',
+            options: {
+                sids: '',
+            },
+        });
+        sidxlate_command.on_success = function(data, text_status, xhr) {
+            for(var i=0; i< data.result.result.length; i++) {
+                var entry = data.result.result[i]
+                if (entry.sid[0] in xlate) {
+                    xlate[entry.sid[0]].resolve(entry.name[0]);
+                }
+            }
+        };
+        that.table.empty();
+
+        var sids = new Array();
+        for(var i=0; i< value.length; i++) {
+            var sid = value[i][that.attribute];
+            var deferred = new Deferred();
+            deferred.temp = sid;
+            value[i][that.attribute] = deferred;
+            xlate[sid] = deferred;
+            sids.push(sid)
+            that.add_record(value[i]);
+        };
+        sidxlate_command.options.sids = sids;
+        sidxlate_command.execute();
+    };
+
+    return that;
+};
+
+
 IPA.attr_read_only_evaluator = function(spec) {
 
     spec.name = spec.name || 'attr_read_only_evaluator';
diff --git a/install/ui/src/freeipa/entity.js b/install/ui/src/freeipa/entity.js
index 08ba7e5..60fb45e 100644
--- a/install/ui/src/freeipa/entity.js
+++ b/install/ui/src/freeipa/entity.js
@@ -425,6 +425,14 @@ IPA.entity_builder = function() {
         return that;
     };
 
+    that.sid_facet = function(spec) {
+
+        spec.type = spec.type || 'sid';
+
+        that.facet(spec);
+
+        return that;
+    };
     that.standard_association_facets = function(spec) {
 
         spec = spec || {};
@@ -727,4 +735,4 @@ IPA.details_facet_update_policy = function(spec) {
 };
 
 return {};
-});
\ No newline at end of file
+});
diff --git a/install/ui/src/freeipa/facet.js b/install/ui/src/freeipa/facet.js
index 3ad868e..8517507 100644
--- a/install/ui/src/freeipa/facet.js
+++ b/install/ui/src/freeipa/facet.js
@@ -1131,6 +1131,7 @@ IPA.facet_builder = function(entity) {
         that.prepare_methods.details = that.prepare_details_spec;
         that.prepare_methods.association = that.prepare_association_spec;
         that.prepare_methods.attribute = that.prepare_attribute_spec;
+        that.prepare_methods.sid = that.prepare_sid_spec;
     }
 
     that.build_facets = function() {
@@ -1271,6 +1272,17 @@ IPA.facet_builder = function(entity) {
         return false;
     };
 
+    that.prepare_sid_spec = function(spec) {
+        spec.title = spec.title || entity.metadata.label_singular;
+        spec.label = spec.label || entity.metadata.label_singular;
+
+        var attr_metadata = IPA.get_entity_param(entity.name, spec.attribute);
+        spec.tab_label = spec.tab_label || attr_metadata.label;
+        spec.factory = spec.factory || IPA.sid_facet;
+
+        return spec;
+    };
+
     init();
 
     return that;
diff --git a/install/ui/src/freeipa/group.js b/install/ui/src/freeipa/group.js
index a84f49f..bb8baa0 100644
--- a/install/ui/src/freeipa/group.js
+++ b/install/ui/src/freeipa/group.js
@@ -101,7 +101,7 @@ IPA.group.entity = function(spec) {
         association_facet({
             name: 'member_group'
         }).
-        attribute_facet({
+        sid_facet({
             name: 'member_external',
             attribute: 'ipaexternalmember',
             tab_label: 'External',
@@ -257,4 +257,4 @@ IPA.group.make_external_action = function(spec) {
 IPA.register('group', IPA.group.entity);
 
 return {};
-});
\ No newline at end of file
+});
diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
index a252ad6..e70e424 100644
--- a/ipalib/plugins/trust.py
+++ b/ipalib/plugins/trust.py
@@ -21,6 +21,7 @@
 from ipalib.plugins.baseldap import *
 from ipalib.plugins.dns import dns_container_exists
 from ipalib import api, Str, StrEnum, Password, DefaultFrom, _, ngettext, Object
+from types import NoneType
 from ipalib.parameters import Enum
 from ipalib import Command
 from ipalib import errors
@@ -32,6 +33,12 @@ try:
 except Exception, e:
     _murmur_installed = False
 
+try:
+    import pysss_nss_idmap #pylint: disable=F0401
+    _nss_idmap_installed = True
+except Exception, e:
+    _nss_idmap_installed = False
+
 if api.env.in_server and api.env.context in ['lite', 'server']:
     try:
         import ipaserver.dcerpc #pylint: disable=F0401
@@ -687,3 +694,52 @@ class trustconfig_show(LDAPRetrieve):
         return dn
 
 api.register(trustconfig_show)
+
+if _nss_idmap_installed:
+    _idmap_type_dict = {
+        pysss_nss_idmap.ID_USER  : 'user',
+        pysss_nss_idmap.ID_GROUP : 'group',
+        pysss_nss_idmap.ID_BOTH  : 'both',
+    }
+    def idmap_type_string(level):
+        string = _idmap_type_dict.get(int(level), 'unknown')
+        return unicode(string)
+
+class trust_resolve(Command):
+    __doc__ = _('Resolve security identifiers of users and groups in trusted domains')
+
+    takes_options = (
+        Str('sids+',
+            label = _('Security Identifiers (SIDs)'),
+            csv = True,
+        ),
+    )
+
+    has_output_params = (
+        Str('name', label= _('Name')),
+        Str('sid', label= _('SID')),
+    )
+
+    has_output = (
+        output.ListOfEntries('result'),
+    )
+
+    def execute(self, *keys, **options):
+        result = list()
+        if not _nss_idmap_installed:
+            return dict(result=result)
+        try:
+            sids = map(lambda x: str(x), options['sids'])
+            xlate = pysss_nss_idmap.getnamebysid(sids)
+            for sid in xlate:
+	       entry = dict()
+               entry['sid'] = [unicode(sid)]
+               entry['name'] = [unicode(xlate[sid][pysss_nss_idmap.NAME_KEY])]
+               entry['type'] = [idmap_type_string(xlate[sid][pysss_nss_idmap.TYPE_KEY])]
+               result.append(entry)
+        except ValueError, e:
+            pass
+
+        return dict(result=result)
+
+api.register(trust_resolve)
-- 
1.8.1.4



More information about the Freeipa-devel mailing list