
From: Royce Lv <lvroyce@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@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@foo.com, bar@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