diff --git a/Dockerfile.nipapd b/Dockerfile.nipapd index 14d7fe265..35bc0a34a 100644 --- a/Dockerfile.nipapd +++ b/Dockerfile.nipapd @@ -37,6 +37,8 @@ MAINTAINER Kristian Larsson ENV DEBIAN_FRONTEND=noninteractive +ARG myrootcert + # apt update, upgrade & install packages RUN apt-get update -qy && apt-get upgrade -qy \ && apt-get install -qy devscripts \ @@ -49,9 +51,16 @@ RUN apt-get update -qy && apt-get upgrade -qy \ python-docutils \ python-pip \ python-dev \ + libldap2-dev \ + libsasl2-dev \ + libssl-dev \ + ca-certificates \ && pip --no-input install envtpl \ && rm -rf /var/lib/apt/lists/* +# install cert +COPY $myrootcert /usr/local/share/ca-certificates +RUN update-ca-certificates COPY nipap /nipap WORKDIR /nipap diff --git a/Dockerfile.www b/Dockerfile.www index 0957f3a6e..2bbf802e9 100644 --- a/Dockerfile.www +++ b/Dockerfile.www @@ -29,6 +29,8 @@ MAINTAINER Lukas Garberg ENV NIPAPD_HOST=nipapd NIPAPD_PORT=1337 WWW_USERNAME=guest WWW_PASSWORD=guest +ARG myrootcert + # apt update, upgrade & install packages RUN apt-get update -qy && apt-get upgrade -qy \ && apt-get install -qy apache2 \ @@ -43,9 +45,17 @@ RUN apt-get update -qy && apt-get upgrade -qy \ python-docutils \ python-pip \ python-dev \ + libldap2-dev \ + libsasl2-dev \ + libssl-dev \ + ca-certificates \ && pip --no-input install envtpl \ && rm -rf /var/lib/apt/lists/* +# install cert +COPY $myrootcert /usr/local/share/ca-certificates +RUN update-ca-certificates + # Install pynipap, nipap and nipap-www COPY pynipap /pynipap COPY nipap /nipap diff --git a/nipap-www/entrypoint.sh b/nipap-www/entrypoint.sh index 34d530e8c..f90c700ef 100755 --- a/nipap-www/entrypoint.sh +++ b/nipap-www/entrypoint.sh @@ -17,6 +17,10 @@ chmod -R u=rwX /var/cache/nipap-www # Configure apache cat << EOF > /etc/apache2/sites-available/000-default.conf + +# increase logging for wsgi apps +LogLevel info wsgi:trace5 + WSGIScriptAlias / /etc/nipap/www/nipap-www.wsgi ErrorLog \${APACHE_LOG_DIR}/error.log diff --git a/nipap-www/nipap-www.wsgi b/nipap-www/nipap-www.wsgi index 5520b687b..387d4459d 100644 --- a/nipap-www/nipap-www.wsgi +++ b/nipap-www/nipap-www.wsgi @@ -1,10 +1,13 @@ # # Set up a wsgi environment for mod_wsgi # +import os, sys, logging.config + +APP_CONFIG="/etc/nipap/nipap-www.ini" + +logging.config.fileConfig(APP_CONFIG) -import os, sys os.environ['PYTHON_EGG_CACHE'] = '/var/cache/nipap-www/eggs' from paste.deploy import loadapp - -application = loadapp('config:/etc/nipap/nipap-www.ini') +application = loadapp('config:%s' % APP_CONFIG) diff --git a/nipap/nipap.conf.dist b/nipap/nipap.conf.dist index 6e30f9d47..2a4bcf2a2 100644 --- a/nipap/nipap.conf.dist +++ b/nipap/nipap.conf.dist @@ -96,6 +96,7 @@ db_sslmode = {{DB_SSLMODE}} ; database SSL mode # [auth] default_backend = local ; which backend to use by default +secondary_backend = ldap1 ; define fallback backend in case username doesn't contain @ auth_cache_timeout = 3600 ; seconds cached auth entries are stored # example backend with SQLite @@ -110,7 +111,7 @@ db_path = /etc/nipap/local_auth.db ; path to SQLite database used # #basedn = ou=Users,dc=example,dc=com ; base DN #uri = ldaps://ldap.example.com ; LDAP server URI -#tls = False ; initiate TLS, use ldap:// +#tls = False ; initiate TLS, use ldap:// # # LDAP style #binddn_fmt = uid={},ou=Users,dc=example,dc=com diff --git a/nipap/nipap/authlib.py b/nipap/nipap/authlib.py index 3472c3db5..cd593d43b 100644 --- a/nipap/nipap/authlib.py +++ b/nipap/nipap/authlib.py @@ -161,17 +161,22 @@ def get_auth(self, username, password, authoritative_source, auth_options=None): for key in rem: del(self._auth_cache[key]) + self._logger.debug("Received username %s" % str(username)) + user_authbackend = username.rsplit('@', 1) - # Find out what auth backend to use. - # If no auth backend was specified in username, use default + # Do not use default backend unless you login as localadmin. backend = "" - if len(user_authbackend) == 1: + if str(username) == "localadmin": backend = self._config.get('auth', 'default_backend') - self._logger.debug("Using default auth backend %s" % backend) else: - backend = user_authbackend[1] - + if len(user_authbackend) == 1: + backend = self._config.get('auth', 'secondary_backend') + else: + backend = user_authbackend[1] + + self._logger.debug("Using auth backend %s" % backend) + # do we have a cached instance? auth_str = ( str(username) + str(password) + str(authoritative_source) + str(auth_options) ) @@ -368,13 +373,16 @@ def authenticate(self): return self._authenticated try: + self._logger.debug('username %s formatted _ldap_binddn_fmt username %s' % (self.username, self._ldap_binddn_fmt.format(ldap.dn.escape_dn_chars(self.username)))) self._ldap_conn.simple_bind_s(self._ldap_binddn_fmt.format(ldap.dn.escape_dn_chars(self.username)), self.password) except ldap.SERVER_DOWN as exc: - raise AuthError('Could not connect to LDAP server') + self._logger.debug('Could not connect to LDAP server: %s' % exc) + raise AuthError('Could not connect to LDAP server: '+str(exc)) except (ldap.INVALID_CREDENTIALS, ldap.INVALID_DN_SYNTAX, ldap.UNWILLING_TO_PERFORM) as exc: # Auth failed self._logger.debug('erroneous password for user %s' % self.username) + self._logger.debug(exc) self._authenticated = False return self._authenticated @@ -387,11 +395,13 @@ def authenticate(self): try: # Create separate connection for search? if self._ldap_search_conn is not None: - self._ldap_search_conn.simple_bind(self._ldap_search_binddn, self._ldap_search_password) + self._ldap_search_conn.simple_bind_s(self._ldap_search_binddn, self._ldap_search_password) search_conn = self._ldap_search_conn else: search_conn = self._ldap_conn + self._logger.debug('username %s formatted _ldap_search username %s' % (self.username, self._ldap_search.format(ldap.dn.escape_dn_chars(self.username)))) + res = search_conn.search_s(self._ldap_basedn, ldap.SCOPE_SUBTREE, self._ldap_search.format(ldap.dn.escape_dn_chars(self.username)), ['cn','memberOf']) if res[0][1]['cn'][0] is not None: self.full_name = res[0][1]['cn'][0].decode('utf-8') @@ -417,10 +427,11 @@ def authenticate(self): raise AuthError(exc) except KeyError: raise AuthError('LDAP attribute missing') - except IndexError: + except IndexError as exc: self.full_name = '' # authentication fails if either ro_group or rw_group are configured # and the user is not found. + self._logger.debug(exc) if self._ldap_rw_group or self._ldap_ro_group: self._authenticated = False return self._authenticated