From: Royce Lv <lvroyce(a)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(a)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 | 46 +++++++++++++++++++++++++++++++++++++++++--
src/kimchi/i18n.py | 1 +
7 files changed, 71 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(a)foo.com, bar(a)bar.com"
diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 5986094..5abfe18 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
@@ -177,17 +178,58 @@ 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:
+ 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)
+
+ connect.bind_s(result[0][0], password)
+ connect.unbind_s()
+ return True
+ except ldap.INVALID_CREDENTIALS:
+ # invalid user password
+ raise OperationFailed("KCHAUTH0002E")
+ except ldap.NO_SUCH_OBJECT:
+ # ldap search base specified wrongly.
+ raise OperationFailed("KCHAUTH0005E",
+ {"item": 'ldap_search_base',"value":
ldap_search_base})
+ 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.
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index e823f2b..9f4ae79 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -40,6 +40,7 @@ messages = {
"KCHAUTH0001E": _("Authentication failed for user
'%(username)s'. [Error code: %(code)s]"),
"KCHAUTH0002E": _("You are not authorized to access Kimchi"),
"KCHAUTH0003E": _("Specify %(item)s to login into Kimchi"),
+ "KCHAUTH0005E": _("Invalid LDAP configuration: %(item)s :
%(value)s"),
"KCHDEVS0001E": _('Unknown "_cap" specified'),
"KCHDEVS0002E": _('"_passthrough" should be "true"
or "false"'),
--
1.8.3.2