
Just a minor comment below: On 10/28/2014 11:37 AM, lvroyce0210@gmail.com wrote:
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 | 12 ++++++----- src/kimchi.conf.in | 3 +++ src/kimchi/auth.py | 48 +++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/contrib/DEBIAN/control.in b/contrib/DEBIAN/control.in index 7372a58..0721960 100644 --- a/contrib/DEBIAN/control.in +++ b/contrib/DEBIAN/control.in @@ -27,6 +27,7 @@ Depends: python-cherrypy3 (>= 3.2.0), firewalld, nginx, python-guestfs, + python-ldap, libguestfs-tools Build-Depends: libxslt, python-libxml2, diff --git a/contrib/kimchi.spec.fedora.in b/contrib/kimchi.spec.fedora.in index 2ca3076..fcb8c11 100644 --- a/contrib/kimchi.spec.fedora.in +++ b/contrib/kimchi.spec.fedora.in @@ -29,6 +29,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 9ea240c..b8f0531 100644 --- a/contrib/kimchi.spec.suse.in +++ b/contrib/kimchi.spec.suse.in @@ -23,6 +23,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 7703037..db219db 100644 --- a/docs/README.md +++ b/docs/README.md @@ -52,7 +52,7 @@ Install Dependencies libvirt libxml2-python python-imaging \ PyPAM m2crypto python-jsonschema rpm-build \ qemu-kvm python-psutil python-ethtool sos \ - python-ipaddr python-lxml nfs-utils \ + python-ipaddr python-ldap python-lxml nfs-utils \ iscsi-initiator-utils libxslt pyparted nginx \ policycoreutils-python python-libguestfs \ libguestfs-tools python-requests python-websockify \ @@ -77,8 +77,9 @@ for more information on how to configure your system to access this repository. libvirt-bin python-libxml2 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 \ + 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
@@ -93,8 +94,9 @@ for more information on how to configure your system to access this repository. libvirt python-libxml2 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-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
diff --git a/src/kimchi.conf.in b/src/kimchi.conf.in index 62eb40b..c83ba09 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 = "root, kimchi-admin"
Those example seems system users instead of LDAP. What about: # ldap_admin_id = "foo@foo.com, bar@bar.com"
diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py index ad3f3ac..214c320 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.