-#!/usr/bin/python
-#
-# Copyright (C) 2014 Ipsilon Contributors, see COPYING for license
+# Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
-from ipsilon.login.common import LoginFormBase, LoginManagerBase
-from ipsilon.login.common import FACILITY
+from ipsilon.login.common import LoginFormBase, LoginManagerBase, \
+ LoginManagerInstaller
from ipsilon.util.plugin import PluginObject
from ipsilon.util.log import Log
+from ipsilon.util import config as pconfig
from ipsilon.info.infoldap import InfoProvider as LDAPInfo
import ldap
+import subprocess
class LDAP(LoginFormBase, Log):
self.lm.info = None
if not self.ldap_info:
- self.ldap_info = LDAPInfo()
+ self.ldap_info = LDAPInfo(self._site)
- return self.ldap_info.get_user_data_from_conn(conn, dn)
+ base = self.lm.base_dn
+ return self.ldap_info.get_user_data_from_conn(conn, dn, base,
+ username)
return None
if username and password:
try:
- userdata = self._authenticate(username, password)
- if userdata:
- userattrs = dict()
- for d, v in userdata.get('userdata', {}).items():
- userattrs[d] = v
- if 'groups' in userdata:
- userattrs['groups'] = userdata['groups']
- if 'extras' in userdata:
- userattrs['extras'] = userdata['extras']
+ userattrs = self._authenticate(username, password)
authed = True
except Exception, e: # pylint: disable=broad-except
errmsg = "Authentication failed"
error_password=not password,
error_username=not username
)
- # pylint: disable=star-args
+ self.lm.set_auth_error()
return self._template('login/form.html', **context)
self.description = """
Form based login Manager that uses a simple bind LDAP operation to perform
authentication. """
- self._options = {
- 'help text': [
- """ The text shown to guide the user at login time. """,
- 'string',
- 'Insert your Username and Password and then submit.'
- ],
- 'username text': [
- """ The text shown to ask for the username in the form. """,
- 'string',
- 'Username'
- ],
- 'password text': [
- """ The text shown to ask for the password in the form. """,
- 'string',
- 'Password'
- ],
- 'server url': [
- """ The LDAP server url """,
- 'string',
- 'ldap://example.com'
- ],
- 'tls': [
- " What TLS level show be required " +
- "(Demand, Allow, Try, Never, NoTLS) ",
- 'string',
- 'Demand'
- ],
- 'bind dn template': [
- """ Template to turn username into DN. """,
- 'string',
- 'uid=%(username)s,ou=People,dc=example,dc=com'
- ],
- 'get user info': [
- """ Get user info via ldap directly after auth (Yes/No) """,
- 'string',
- 'Yes'
- ],
- }
- self.conf_opt_order = ['server url', 'bind dn template',
- 'get user info', 'tls', 'username text',
- 'password text', 'help text']
+ self.new_config(
+ self.name,
+ pconfig.String(
+ 'server url',
+ 'The LDAP server url.',
+ 'ldap://example.com'),
+ pconfig.Template(
+ 'bind dn template',
+ 'Template to turn username into DN.',
+ 'uid=%(username)s,ou=People,dc=example,dc=com'),
+ pconfig.String(
+ 'base dn',
+ 'The base dn to look for users and groups',
+ 'dc=example,dc=com'),
+ pconfig.Condition(
+ 'get user info',
+ 'Get user info via ldap using user credentials',
+ True),
+ pconfig.Pick(
+ 'tls',
+ 'What TLS level show be required',
+ ['Demand', 'Allow', 'Try', 'Never', 'NoTLS'],
+ 'Demand'),
+ pconfig.String(
+ 'username text',
+ 'Text used to ask for the username at login time.',
+ 'Username'),
+ pconfig.String(
+ 'password text',
+ 'Text used to ask for the password at login time.',
+ 'Password'),
+ pconfig.String(
+ 'help text',
+ 'Text used to guide the user at login time.',
+ 'Provide your Username and Password')
+ )
@property
def help_text(self):
@property
def get_user_info(self):
- return (self.get_config_value('get user info').lower() == 'yes')
+ return self.get_config_value('get user info')
@property
def bind_dn_tmpl(self):
return self.get_config_value('bind dn template')
+ @property
+ def base_dn(self):
+ return self.get_config_value('base dn')
+
def get_tree(self, site):
self.page = LDAP(site, self, 'login/ldap')
return self.page
-class Installer(object):
+class Installer(LoginManagerInstaller):
- def __init__(self):
+ def __init__(self, *pargs):
+ super(Installer, self).__init__()
self.name = 'ldap'
- self.ptype = 'login'
+ self.pargs = pargs
def install_args(self, group):
group.add_argument('--ldap', choices=['yes', 'no'], default='no',
- help='Configure PAM authentication')
+ help='Configure LDAP authentication')
group.add_argument('--ldap-server-url', action='store',
help='LDAP Server Url')
group.add_argument('--ldap-bind-dn-template', action='store',
help='LDAP Bind DN Template')
+ group.add_argument('--ldap-tls-level', action='store', default=None,
+ help='LDAP TLS level')
+ group.add_argument('--ldap-base-dn', action='store',
+ help='LDAP Base DN')
- def configure(self, opts):
+ def configure(self, opts, changes):
if opts['ldap'] != 'yes':
return
# Add configuration data to database
- po = PluginObject()
+ po = PluginObject(*self.pargs)
po.name = 'ldap'
po.wipe_data()
+ po.wipe_config_values()
- po.wipe_config_values(FACILITY)
config = dict()
if 'ldap_server_url' in opts:
config['server url'] = opts['ldap_server_url']
if 'ldap_bind_dn_template' in opts:
config['bind dn template'] = opts['ldap_bind_dn_template']
- config['tls'] = 'Demand'
- po.save_plugin_config(FACILITY, config)
+ if 'ldap_tls_level' in opts and opts['ldap_tls_level'] is not None:
+ config['tls'] = opts['ldap_tls_level']
+ else:
+ config['tls'] = 'Demand'
+ if 'ldap_base_dn' in opts and opts['ldap_base_dn'] is not None:
+ config['base dn'] = opts['ldap_base_dn']
+ po.save_plugin_config(config)
# Update global config to add login plugin
- po = PluginObject()
- po.name = 'global'
- globalconf = po.get_plugin_config(FACILITY)
- if 'order' in globalconf:
- order = globalconf['order'].split(',')
- else:
- order = []
- order.append('ldap')
- globalconf['order'] = ','.join(order)
- po.save_plugin_config(FACILITY, globalconf)
+ po.is_enabled = True
+ po.save_enabled_state()
+
+ # For selinux enabled platforms permit httpd to connect to ldap,
+ # ignore if it fails
+ try:
+ subprocess.call(['/usr/sbin/setsebool', '-P',
+ 'httpd_can_connect_ldap=on'])
+ except Exception: # pylint: disable=broad-except
+ pass