{"action":"created","comment":{"url":"https://api.github.com/repos/freeipa/freeipa/pulls/comments/103629428","pull_request_review_id":24420084,"id":103629428,"diff_hunk":"@@ -389,3 +393,115 @@ def execute(self, cn, **options):\n             result=True,\n             value=pkey_to_value(cn, options),\n         )\n+\n+\n+DBUS_SSSD_NAME = 'org.freedesktop.sssd.infopipe'\n+DBUS_PROPERTY_IF = 'org.freedesktop.DBus.Properties'\n+DBUS_SSSD_USERS_PATH = '/org/freedesktop/sssd/infopipe/Users'\n+DBUS_SSSD_USERS_IF = 'org.freedesktop.sssd.infopipe.Users'\n+DBUS_SSSD_USER_IF = 'org.freedesktop.sssd.infopipe.Users.User'\n+\n+\n+class _sssd(object):\n+    \"\"\"\n+    Auxiliary class for SSSD infopipe DBus.\n+    \"\"\"\n+    def __init__(self, log):\n+        \"\"\"\n+        Initialize the Users object and interface.\n+\n+       :raise RemoteRetrieveError: if DBus error occurs\n+        \"\"\"\n+        try:\n+            self.log = log\n+            self._bus = dbus.SystemBus()\n+            self._users_obj = self._bus.get_object(\n+                DBUS_SSSD_NAME, DBUS_SSSD_USERS_PATH)\n+            self._users_iface = dbus.Interface(\n+                self._users_obj, DBUS_SSSD_USERS_IF)\n+        except dbus.DBusException as e:\n+            self.log.error(\n+                'Failed to initialize DBus interface {iface}. DBus '\n+                'exception is {exc}.'.format(iface=DBUS_SSSD_USERS_IF, exc=e)\n+                )\n+            raise errors.RemoteRetrieveError(\n+                reason=_('Failed to connect to sssd over SystemBus. '\n+                         'See details in the error_log'))\n+\n+    def list_users_by_cert(self, cert):\n+        \"\"\"\n+        Look for users matching the cert.\n+\n+        Call Users.ListByCertificate interface and return a list of names\n+        corresponding to the users matching the provided cert\n+        :param cert: DER cert\n+        :raise RemoteRetrieveError: if DBus error occurs\n+        \"\"\"\n+        try:\n+            pem = x509.make_pem(base64.b64encode(cert))\n+            # bug 3306 in sssd returns 0 entry when max_entries = 0\n+            # Temp workaround is to use a non-null value, not too high\n+            # to avoid reserving unneeded memory\n+            max_entries = dbus.UInt32(100)\n+            user_paths = self._users_iface.ListByCertificate(pem, max_entries)\n+            users = list()\n+            for user_path in user_paths:\n+                user_obj = self._bus.get_object(DBUS_SSSD_NAME, user_path)\n+                user_iface = dbus.Interface(user_obj, DBUS_PROPERTY_IF)\n+                user_login = user_iface.Get(DBUS_SSSD_USER_IF, 'name')\n+                users.append(user_login)\n+            return users\n+        except dbus.DBusException as e:\n+            err_name = e.get_dbus_name()\n+            # If there is no matching user, do not consider this as an\n+            # exception and return an empty list\n+            if err_name == 'org.freedesktop.sssd.Error.NotFound':\n+                return list()\n+            self.log.error(\n+                'Failed to use interface {iface}. DBus '\n+                'exception is {exc}.'.format(iface=DBUS_SSSD_USERS_IF, exc=e))\n+            raise errors.RemoteRetrieveError(\n+                reason=_('Failed to find users over SystemBus. '\n+                         ' See details in the error_log'))\n+\n+\n+@register()\n+class certmap_match(Command):\n+    __doc__ = _('Search for users matching the provided certificate.')\n+\n+    has_output = (\n+        output.summary,\n+        output.Output('uids', (list, tuple, type(None)), _('Matched uid')),\n+        output.Output('count', int, _('Number of entries returned')),\n+        )\n+\n+    takes_options = (\n+        Bytes(\n+            'certificate', validate_certificate,\n+            cli_name='certificate',\n+            label=_('Certificate'),\n+            doc=_('Base-64 encoded user certificate')\n+        ),\n+    )\n+\n+    def execute(self, *args, **options):\n+        \"\"\"\n+        Search for users matching the provided certificate.\n+\n+        The search is performed using SSSD's DBus interface\n+        Users.ListByCertificate.\n+        SSSD does the lookup based on certificate mapping rules, using\n+        FreeIPA domain and trusted domains.\n+        :raise RemoteRetrieveError: if DBus returns an exception\n+        \"\"\"\n+        sssd = _sssd(self.log)\n+        result = dict()\n+\n+        cert = options['certificate']\n+        users = sssd.list_users_by_cert(cert)\n+        result['count'] = len(users)\n+        result['uids'] = users\n+        result['summary'] = u'{count} user{plural} matched'.format(\n+            count=len(users), plural='' if len(users) == 1 else 's')","path":"ipaserver/plugins/certmap.py","position":505,"original_position":135,"commit_id":"f07858477a7c7cf5fed3ac6383207add303c8404","original_commit_id":"f07858477a7c7cf5fed3ac6383207add303c8404","user":{"login":"HonzaCholasta","id":13571106,"avatar_url":"https://avatars2.githubusercontent.com/u/13571106?v=3","gravatar_id":"","url":"https://api.github.com/users/HonzaCholasta","html_url":"https://github.com/HonzaCholasta","followers_url":"https://api.github.com/users/HonzaCholasta/followers","following_url":"https://api.github.com/users/HonzaCholasta/following{/other_user}","gists_url":"https://api.github.com/users/HonzaCholasta/gists{/gist_id}","starred_url":"https://api.github.com/users/HonzaCholasta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HonzaCholasta/subscriptions","organizations_url":"https://api.github.com/users/HonzaCholasta/orgs","repos_url":"https://api.github.com/users/HonzaCholasta/repos","events_url":"https://api.github.com/users/HonzaCholasta/events{/privacy}","received_events_url":"https://api.github.com/users/HonzaCholasta/received_events","type":"User","site_admin":false},"body":"This is not translatable. Instead of filling in `summary` yourself, you should specify the `msg_summary` class attribute and have it filled automatically.","created_at":"2017-03-01T08:11:45Z","updated_at":"2017-03-01T08:29:58Z","html_url":"https://github.com/freeipa/freeipa/pull/516#discussion_r103629428","pull_request_url":"https://api.github.com/repos/freeipa/freeipa/pulls/516","_links":{"self":{"href":"https://api.github.com/repos/freeipa/freeipa/pulls/comments/103629428"},"html":{"href":"https://github.com/freeipa/freeipa/pull/516#discussion_r103629428"},"pull_request":{"href":"https://api.github.com/repos/freeipa/freeipa/pulls/516"}}},"pull_request":{"url":"https://api.github.com/repos/freeipa/freeipa/pulls/516","id":108293126,"html_url":"https://github.com/freeipa/freeipa/pull/516","diff_url":"https://github.com/freeipa/freeipa/pull/516.diff","patch_url":"https://github.com/freeipa/freeipa/pull/516.patch","issue_url":"https://api.github.com/repos/freeipa/freeipa/issues/516","number":516,"state":"open","locked":false,"title":"IdM Server: list all Employees with matching Smart Card","user":{"login":"flo-renaud","id":21310191,"avatar_url":"https://avatars0.githubusercontent.com/u/21310191?v=3","gravatar_id":"","url":"https://api.github.com/users/flo-renaud","html_url":"https://github.com/flo-renaud","followers_url":"https://api.github.com/users/flo-renaud/followers","following_url":"https://api.github.com/users/flo-renaud/following{/other_user}","gists_url":"https://api.github.com/users/flo-renaud/gists{/gist_id}","starred_url":"https://api.github.com/users/flo-renaud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flo-renaud/subscriptions","organizations_url":"https://api.github.com/users/flo-renaud/orgs","repos_url":"https://api.github.com/users/flo-renaud/repos","events_url":"https://api.github.com/users/flo-renaud/events{/privacy}","received_events_url":"https://api.github.com/users/flo-renaud/received_events","type":"User","site_admin":false},"body":"Implement a new IPA command allowing to retrieve the list of users matching the provided certificate.\r\nThe command is using SSSD Dbus interface, thus including users from IPA domain and from trusted domains. This requires sssd-dbus package to be installed on IPA server.\r\n\r\nhttps://fedorahosted.org/freeipa/ticket/6646","created_at":"2017-02-28T09:49:18Z","updated_at":"2017-03-01T08:29:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4a62ffd8a9cda0e3e2653a327e3803bfb9627715","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/freeipa/freeipa/pulls/516/commits","review_comments_url":"https://api.github.com/repos/freeipa/freeipa/pulls/516/comments","review_comment_url":"https://api.github.com/repos/freeipa/freeipa/pulls/comments{/number}","comments_url":"https://api.github.com/repos/freeipa/freeipa/issues/516/comments","statuses_url":"https://api.github.com/repos/freeipa/freeipa/statuses/f07858477a7c7cf5fed3ac6383207add303c8404","head":{"label":"flo-renaud:t6646","ref":"t6646","sha":"f07858477a7c7cf5fed3ac6383207add303c8404","user":{"login":"flo-renaud","id":21310191,"avatar_url":"https://avatars0.githubusercontent.com/u/21310191?v=3","gravatar_id":"","url":"https://api.github.com/users/flo-renaud","html_url":"https://github.com/flo-renaud","followers_url":"https://api.github.com/users/flo-renaud/followers","following_url":"https://api.github.com/users/flo-renaud/following{/other_user}","gists_url":"https://api.github.com/users/flo-renaud/gists{/gist_id}","starred_url":"https://api.github.com/users/flo-renaud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flo-renaud/subscriptions","organizations_url":"https://api.github.com/users/flo-renaud/orgs","repos_url":"https://api.github.com/users/flo-renaud/repos","events_url":"https://api.github.com/users/flo-renaud/events{/privacy}","received_events_url":"https://api.github.com/users/flo-renaud/received_events","type":"User","site_admin":false},"repo":{"id":67136615,"name":"freeipa","full_name":"flo-renaud/freeipa","owner":{"login":"flo-renaud","id":21310191,"avatar_url":"https://avatars0.githubusercontent.com/u/21310191?v=3","gravatar_id":"","url":"https://api.github.com/users/flo-renaud","html_url":"https://github.com/flo-renaud","followers_url":"https://api.github.com/users/flo-renaud/followers","following_url":"https://api.github.com/users/flo-renaud/following{/other_user}","gists_url":"https://api.github.com/users/flo-renaud/gists{/gist_id}","starred_url":"https://api.github.com/users/flo-renaud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flo-renaud/subscriptions","organizations_url":"https://api.github.com/users/flo-renaud/orgs","repos_url":"https://api.github.com/users/flo-renaud/repos","events_url":"https://api.github.com/users/flo-renaud/events{/privacy}","received_events_url":"https://api.github.com/users/flo-renaud/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/flo-renaud/freeipa","description":"Mirror of FreeIPA, an integrated security information management solution","fork":true,"url":"https://api.github.com/repos/flo-renaud/freeipa","forks_url":"https://api.github.com/repos/flo-renaud/freeipa/forks","keys_url":"https://api.github.com/repos/flo-renaud/freeipa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/flo-renaud/freeipa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/flo-renaud/freeipa/teams","hooks_url":"https://api.github.com/repos/flo-renaud/freeipa/hooks","issue_events_url":"https://api.github.com/repos/flo-renaud/freeipa/issues/events{/number}","events_url":"https://api.github.com/repos/flo-renaud/freeipa/events","assignees_url":"https://api.github.com/repos/flo-renaud/freeipa/assignees{/user}","branches_url":"https://api.github.com/repos/flo-renaud/freeipa/branches{/branch}","tags_url":"https://api.github.com/repos/flo-renaud/freeipa/tags","blobs_url":"https://api.github.com/repos/flo-renaud/freeipa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/flo-renaud/freeipa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/flo-renaud/freeipa/git/refs{/sha}","trees_url":"https://api.github.com/repos/flo-renaud/freeipa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/flo-renaud/freeipa/statuses/{sha}","languages_url":"https://api.github.com/repos/flo-renaud/freeipa/languages","stargazers_url":"https://api.github.com/repos/flo-renaud/freeipa/stargazers","contributors_url":"https://api.github.com/repos/flo-renaud/freeipa/contributors","subscribers_url":"https://api.github.com/repos/flo-renaud/freeipa/subscribers","subscription_url":"https://api.github.com/repos/flo-renaud/freeipa/subscription","commits_url":"https://api.github.com/repos/flo-renaud/freeipa/commits{/sha}","git_commits_url":"https://api.github.com/repos/flo-renaud/freeipa/git/commits{/sha}","comments_url":"https://api.github.com/repos/flo-renaud/freeipa/comments{/number}","issue_comment_url":"https://api.github.com/repos/flo-renaud/freeipa/issues/comments{/number}","contents_url":"https://api.github.com/repos/flo-renaud/freeipa/contents/{+path}","compare_url":"https://api.github.com/repos/flo-renaud/freeipa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/flo-renaud/freeipa/merges","archive_url":"https://api.github.com/repos/flo-renaud/freeipa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/flo-renaud/freeipa/downloads","issues_url":"https://api.github.com/repos/flo-renaud/freeipa/issues{/number}","pulls_url":"https://api.github.com/repos/flo-renaud/freeipa/pulls{/number}","milestones_url":"https://api.github.com/repos/flo-renaud/freeipa/milestones{/number}","notifications_url":"https://api.github.com/repos/flo-renaud/freeipa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/flo-renaud/freeipa/labels{/name}","releases_url":"https://api.github.com/repos/flo-renaud/freeipa/releases{/id}","deployments_url":"https://api.github.com/repos/flo-renaud/freeipa/deployments","created_at":"2016-09-01T14:06:10Z","updated_at":"2016-09-01T14:06:16Z","pushed_at":"2017-02-28T08:59:44Z","git_url":"git://github.com/flo-renaud/freeipa.git","ssh_url":"git@github.com:flo-renaud/freeipa.git","clone_url":"https://github.com/flo-renaud/freeipa.git","svn_url":"https://github.com/flo-renaud/freeipa","homepage":"http://www.freeipa.org","size":39594,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"freeipa:master","ref":"master","sha":"ada91c20588046bb147fc701718d3da4d2c080ca","user":{"login":"freeipa","id":10979201,"avatar_url":"https://avatars1.githubusercontent.com/u/10979201?v=3","gravatar_id":"","url":"https://api.github.com/users/freeipa","html_url":"https://github.com/freeipa","followers_url":"https://api.github.com/users/freeipa/followers","following_url":"https://api.github.com/users/freeipa/following{/other_user}","gists_url":"https://api.github.com/users/freeipa/gists{/gist_id}","starred_url":"https://api.github.com/users/freeipa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/freeipa/subscriptions","organizations_url":"https://api.github.com/users/freeipa/orgs","repos_url":"https://api.github.com/users/freeipa/repos","events_url":"https://api.github.com/users/freeipa/events{/privacy}","received_events_url":"https://api.github.com/users/freeipa/received_events","type":"Organization","site_admin":false},"repo":{"id":4340318,"name":"freeipa","full_name":"freeipa/freeipa","owner":{"login":"freeipa","id":10979201,"avatar_url":"https://avatars1.githubusercontent.com/u/10979201?v=3","gravatar_id":"","url":"https://api.github.com/users/freeipa","html_url":"https://github.com/freeipa","followers_url":"https://api.github.com/users/freeipa/followers","following_url":"https://api.github.com/users/freeipa/following{/other_user}","gists_url":"https://api.github.com/users/freeipa/gists{/gist_id}","starred_url":"https://api.github.com/users/freeipa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/freeipa/subscriptions","organizations_url":"https://api.github.com/users/freeipa/orgs","repos_url":"https://api.github.com/users/freeipa/repos","events_url":"https://api.github.com/users/freeipa/events{/privacy}","received_events_url":"https://api.github.com/users/freeipa/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/freeipa/freeipa","description":"Mirror of FreeIPA, an integrated security information management solution","fork":false,"url":"https://api.github.com/repos/freeipa/freeipa","forks_url":"https://api.github.com/repos/freeipa/freeipa/forks","keys_url":"https://api.github.com/repos/freeipa/freeipa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/freeipa/freeipa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/freeipa/freeipa/teams","hooks_url":"https://api.github.com/repos/freeipa/freeipa/hooks","issue_events_url":"https://api.github.com/repos/freeipa/freeipa/issues/events{/number}","events_url":"https://api.github.com/repos/freeipa/freeipa/events","assignees_url":"https://api.github.com/repos/freeipa/freeipa/assignees{/user}","branches_url":"https://api.github.com/repos/freeipa/freeipa/branches{/branch}","tags_url":"https://api.github.com/repos/freeipa/freeipa/tags","blobs_url":"https://api.github.com/repos/freeipa/freeipa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/freeipa/freeipa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/freeipa/freeipa/git/refs{/sha}","trees_url":"https://api.github.com/repos/freeipa/freeipa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/freeipa/freeipa/statuses/{sha}","languages_url":"https://api.github.com/repos/freeipa/freeipa/languages","stargazers_url":"https://api.github.com/repos/freeipa/freeipa/stargazers","contributors_url":"https://api.github.com/repos/freeipa/freeipa/contributors","subscribers_url":"https://api.github.com/repos/freeipa/freeipa/subscribers","subscription_url":"https://api.github.com/repos/freeipa/freeipa/subscription","commits_url":"https://api.github.com/repos/freeipa/freeipa/commits{/sha}","git_commits_url":"https://api.github.com/repos/freeipa/freeipa/git/commits{/sha}","comments_url":"https://api.github.com/repos/freeipa/freeipa/comments{/number}","issue_comment_url":"https://api.github.com/repos/freeipa/freeipa/issues/comments{/number}","contents_url":"https://api.github.com/repos/freeipa/freeipa/contents/{+path}","compare_url":"https://api.github.com/repos/freeipa/freeipa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/freeipa/freeipa/merges","archive_url":"https://api.github.com/repos/freeipa/freeipa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/freeipa/freeipa/downloads","issues_url":"https://api.github.com/repos/freeipa/freeipa/issues{/number}","pulls_url":"https://api.github.com/repos/freeipa/freeipa/pulls{/number}","milestones_url":"https://api.github.com/repos/freeipa/freeipa/milestones{/number}","notifications_url":"https://api.github.com/repos/freeipa/freeipa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/freeipa/freeipa/labels{/name}","releases_url":"https://api.github.com/repos/freeipa/freeipa/releases{/id}","deployments_url":"https://api.github.com/repos/freeipa/freeipa/deployments","created_at":"2012-05-15T20:34:40Z","updated_at":"2017-02-21T08:15:34Z","pushed_at":"2017-03-01T08:29:40Z","git_url":"git://github.com/freeipa/freeipa.git","ssh_url":"git@github.com:freeipa/freeipa.git","clone_url":"https://github.com/freeipa/freeipa.git","svn_url":"https://github.com/freeipa/freeipa","homepage":"http://www.freeipa.org","size":39585,"stargazers_count":60,"watchers_count":60,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":65,"mirror_url":null,"open_issues_count":54,"forks":65,"open_issues":54,"watchers":60,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/freeipa/freeipa/pulls/516"},"html":{"href":"https://github.com/freeipa/freeipa/pull/516"},"issue":{"href":"https://api.github.com/repos/freeipa/freeipa/issues/516"},"comments":{"href":"https://api.github.com/repos/freeipa/freeipa/issues/516/comments"},"review_comments":{"href":"https://api.github.com/repos/freeipa/freeipa/pulls/516/comments"},"review_comment":{"href":"https://api.github.com/repos/freeipa/freeipa/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/freeipa/freeipa/pulls/516/commits"},"statuses":{"href":"https://api.github.com/repos/freeipa/freeipa/statuses/f07858477a7c7cf5fed3ac6383207add303c8404"}}}}
{"actor":{"display_login":"HonzaCholasta"}}