[Kimchi-devel] [PATCHv3 3/8] Add LDAP authentication

lvroyce at linux.vnet.ibm.com lvroyce at linux.vnet.ibm.com
Mon Nov 10 07:09:47 UTC 2014


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

Add LDAP authentication, also deals with invalid user,
LDAP search base configure error and other LDAP errors.

Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
---
 contrib/DEBIAN/control.in     |  1 +
 contrib/kimchi.spec.fedora.in |  1 +
 contrib/kimchi.spec.suse.in   |  1 +
 docs/README.md                | 36 +++++++++++++++++---------------
 src/kimchi.conf.in            |  3 +++
 src/kimchi/auth.py            | 48 +++++++++++++++++++++++++++++++++++++++++--
 6 files changed, 72 insertions(+), 18 deletions(-)

diff --git a/contrib/DEBIAN/control.in b/contrib/DEBIAN/control.in
index ecddc71..7e0ed8d 100644
--- a/contrib/DEBIAN/control.in
+++ b/contrib/DEBIAN/control.in
@@ -26,6 +26,7 @@ Depends: python-cherrypy3 (>= 3.2.0),
          firewalld,
          nginx,
          python-guestfs,
+         python-ldap,
          libguestfs-tools,
          spice-html5
 Build-Depends: libxslt,
diff --git a/contrib/kimchi.spec.fedora.in b/contrib/kimchi.spec.fedora.in
index 236c862..c1929f8 100644
--- a/contrib/kimchi.spec.fedora.in
+++ b/contrib/kimchi.spec.fedora.in
@@ -28,6 +28,7 @@ Requires:	nfs-utils
 Requires:	nginx
 Requires:	iscsi-initiator-utils
 Requires:	policycoreutils-python
+Requires:	python-ldap
 Requires:	python-libguestfs
 Requires:	libguestfs-tools
 BuildRequires:	libxslt
diff --git a/contrib/kimchi.spec.suse.in b/contrib/kimchi.spec.suse.in
index 96d3b4c..be75590 100644
--- a/contrib/kimchi.spec.suse.in
+++ b/contrib/kimchi.spec.suse.in
@@ -22,6 +22,7 @@ Requires:	python-psutil >= 0.6.0
 Requires:	python-jsonschema >= 1.3.0
 Requires:	python-ethtool
 Requires:	python-ipaddr
+Requires:	python-ldap
 Requires:	python-lxml
 Requires:	python-xml
 Requires:	nfs-client
diff --git a/docs/README.md b/docs/README.md
index d18a946..de6db91 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -49,11 +49,12 @@ Install Dependencies
 
      $ sudo yum install gcc make autoconf automake gettext-devel git \
                         python-cherrypy python-cheetah libvirt-python \
-                        libvirt python-imaging PyPAM m2crypto \
-                        python-jsonschema rpm-build qemu-kvm python-psutil \
-                        python-ethtool sos python-ipaddr python-lxml \
-                        nfs-utils iscsi-initiator-utils libxslt pyparted \
-                        nginx policycoreutils-python python-libguestfs \
+                        libvirt python-imaging \
+                        PyPAM m2crypto python-jsonschema rpm-build \
+                        qemu-kvm python-psutil python-ethtool sos \
+                        python-ipaddr python-ldap python-lxml nfs-utils \
+                        iscsi-initiator-utils libxslt pyparted nginx \
+                        policycoreutils-python python-libguestfs \
                         libguestfs-tools python-requests python-websockify \
                         novnc
 
@@ -77,11 +78,12 @@ for more information on how to configure your system to access this repository.
 
     $ sudo apt-get install gcc make autoconf automake gettext git \
                            python-cherrypy3 python-cheetah python-libvirt \
-                           libvirt-bin python-imaging python-pam \
-                           python-m2crypto python-jsonschema qemu-kvm \
-                           libtool python-psutil python-ethtool \
-                           sosreport python-ipaddr python-lxml nfs-common \
-                           open-iscsi lvm2 xsltproc python-parted nginx \
+                           libvirt-bin python-imaging \
+                           python-pam python-m2crypto python-jsonschema \
+                           qemu-kvm libtool python-psutil python-ethtool \
+                           sosreport python-ipaddr python-ldap \
+                           python-lxml nfs-common open-iscsi lvm2 xsltproc \
+                           python-parted nginx \
                            firewalld python-guestfs libguestfs-tools \
                            python-requests websockify novnc spice-html5
 
@@ -93,12 +95,14 @@ for more information on how to configure your system to access this repository.
 
     $ sudo zypper install gcc make autoconf automake gettext-tools git \
                           python-CherryPy python-Cheetah libvirt-python \
-                          libvirt python-imaging python-pam python-M2Crypto \
-                          python-jsonschema rpm-build kvm python-psutil \
-                          python-ethtool python-ipaddr python-lxml \
-                          nfs-client open-iscsi libxslt-tools python-xml \
-                          python-parted nginx python-libguestfs \
-                          guestfs-tools python-requests python-websockify novnc
+                          libvirt python-imaging \
+                          python-pam python-M2Crypto python-jsonschema \
+                          rpm-build kvm python-psutil python-ethtool \
+                          python-ipaddr python-ldap python-lxml nfs-client \
+                          open-iscsi libxslt-tools python-xml \
+                          python-parted nginx \
+                          python-libguestfs guestfs-tools python-requests \
+                          python-websockify novnc
 
     Packages version requirement:
         python-psutil >= 0.6.0
diff --git a/src/kimchi.conf.in b/src/kimchi.conf.in
index 62eb40b..003ce4a 100644
--- a/src/kimchi.conf.in
+++ b/src/kimchi.conf.in
@@ -57,3 +57,6 @@
 
 # User id filter
 # ldap_search_filter = "uid=%(username)s"
+
+# User IDs regarded as kimchi admin
+# ldap_admin_id = "foo at foo.com, bar at bar.com"
diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 46593a4..bc9ce08 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -20,6 +20,7 @@
 import base64
 import cherrypy
 import fcntl
+import ldap
 import multiprocessing
 import os
 import PAM
@@ -178,17 +179,60 @@ class PAMUser(User):
 
 class LDAPUser(User):
     auth_type = "ldap"
+
     def __init__(self, username):
         self.user = {}
         self.user[USER_NAME] = username
-        self.user[USER_GROUPS] = None
+        self.user[USER_GROUPS] = list()
         # FIXME: user roles will be changed according roles assignment after
         # objstore is integrated
         self.user[USER_ROLES] = dict.fromkeys(tabs, 'user')
 
     @staticmethod
     def authenticate(username, password):
-        return False
+        ldap_server = config.get("authentication", "ldap_server").strip('"')
+        ldap_search_base = config.get(
+            "authentication", "ldap_search_base").strip('"')
+        ldap_search_filter = config.get(
+            "authentication", "ldap_search_filter",
+            vars={"username": username.encode("utf-8")}).strip('"')
+
+        connect = ldap.open(ldap_server)
+        try:
+            try:
+                result = connect.search_s(
+                    ldap_search_base, ldap.SCOPE_SUBTREE, ldap_search_filter)
+                if len(result) == 0:
+                    entity = ldap_search_filter % {'username': username}
+                    raise ldap.LDAPError("Invalid ldap entity:%s" % entity)
+            except ldap.NO_SUCH_OBJECT:
+                # ldap search base specified wrongly.
+                raise ldap.LDAPError(
+                    "invalid ldap search base %s" % ldap_search_base)
+
+            try:
+                connect.bind_s(result[0][0], password)
+            except ldap.INVALID_CREDENTIALS:
+                # invalid user password
+                raise ldap.LDAPError("invalid user/passwd")
+            connect.unbind_s()
+            return True
+        except ldap.LDAPError, e:
+            arg = {"username": username, "code": e.message}
+            raise OperationFailed("KCHAUTH0001E", arg)
+
+    def get_groups(self):
+        return self.user[USER_GROUPS]
+
+    def get_roles(self):
+        admin_id = config.get("authentication", "ldap_admin_id").strip('"')
+        if self.user[USER_NAME] in admin_id.split(','):
+            self.user[USER_ROLES] = dict.fromkeys(tabs, 'admin')
+        return self.user[USER_ROLES]
+
+    def get_user(self):
+        return self.user
+
 
 def from_browser():
     # Enable Basic Authentication for REST tools.
-- 
1.8.3.2




More information about the Kimchi-devel mailing list