From d8df23fa06e0b92379c7fedcb44b3e657837bf10 Mon Sep 17 00:00:00 2001 From: a-schild <andre@schild.ws> Date: Thu, 7 Mar 2019 17:23:58 +0100 Subject: [PATCH] - Upgraded to ldapjs 1.0.2 - substring queries are now case insensitive Was an issue in in nextcloud group sharing for example --- CHANGELOG.md | 7 +++++++ README.md | 2 +- ctldap.js | 43 +++++++++++++++++++++++++++++++++++++++---- package.json | 14 +++++++++----- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 257155d..bd38d82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +### 2.1 +- Upgraded to ldapjs 1.0.2 +- Fixed wrong street mapping +- Consistent logging +- substring queries are now case insensitive + Was an issue in in nextcloud group sharing for example + ### 2.0 - adapted to built-in ChurchTools ctldap API diff --git a/README.md b/README.md index 2224a89..129a2b9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# LDAP Wrapper for ChurchTools v2.0 +# LDAP Wrapper for ChurchTools v2.1 This software acts as an LDAP server for ChurchTools >= 3.25.0 diff --git a/ctldap.js b/ctldap.js index 3def6dd..80bb7db 100644 --- a/ctldap.js +++ b/ctldap.js @@ -1,6 +1,7 @@ -// ChurchTools LDAP-Wrapper 2.0 +// ChurchTools LDAP-Wrapper 2.1 // This tool requires a node.js-Server and ChurchTools >= 3.25.0 // (c) 2017 Michael Lux +// (c) 2019 André Schild // License: GNU/GPL v3.0 var ldap = require('ldapjs'); @@ -8,11 +9,14 @@ var fs = require('fs'); var ini = require('ini'); var rp = require('request-promise'); var ldapEsc = require('ldap-escape'); +var parseDN = require('ldapjs').parseDN; var extend = require('extend'); var Promise = require("bluebird"); var path = require('path'); var bcrypt = require('bcrypt'); +var helpers = require('ldap-filter/lib/helpers'); + var config = ini.parse(fs.readFileSync(path.resolve(__dirname, 'ctldap.config'), 'utf-8')); if (config.debug) { console.log("Debug mode enabled, expect lots of output!"); @@ -285,6 +289,7 @@ function requestUsers (req, res, next) { uid: cn, nsuniqueid: "u0", givenname: "LDAP Administrator", + objectclass: ['CTPerson'], } }); } @@ -373,7 +378,7 @@ function sendUsers (req, res, next) { var strDn = req.dn.toString(); req.usersPromise.then(function (users) { users.forEach(function (u) { - if ((req.checkAll || strDn === u.dn) && (req.filter.matches(u.attributes))) { + if ((req.checkAll || parseDN(strDn).equals(parseDN(u.dn))) && (req.filter.matches(u.attributes))) { if (config.debug) { console.log("[DEBUG] MatchUser: " + u.dn); } @@ -390,7 +395,7 @@ function sendUsers (req, res, next) { } /** - * Evaluetes req.groupsPromise and sends matching elements to the client. + * Evaluates req.groupsPromise and sends matching elements to the client. * @param {object} req - Request object * @param {object} res - Response object * @param {function} next - Next handler function of filter chain @@ -399,7 +404,7 @@ function sendGroups (req, res, next) { var strDn = req.dn.toString(); req.groupsPromise.then(function (groups) { groups.forEach(function (g) { - if ((req.checkAll || strDn === g.dn) && (req.filter.matches(g.attributes))) { + if ((req.checkAll || parseDN(strDn).equals(parseDN(g.dn))) && (req.filter.matches(g.attributes))) { if (config.debug) { console.log("[DEBUG] MatchGroup: " + g.dn); } @@ -537,6 +542,36 @@ server.search('', function (req, res, next) { res.end(); }, endSuccess); + +function escapeRegExp(str) { + /* JSSTYLED */ + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); +} + +/** Case insensitive search on substring filters */ +ldap.SubstringFilter.prototype.matches = function (target, strictAttrCase) { + var tv = helpers.getAttrValue(target, this.attribute, strictAttrCase); + if (tv !== undefined && tv !== null) { + var re = ''; + + if (this.initial) + re += '^' + escapeRegExp(this.initial) + '.*'; + this.any.forEach(function (s) { + re += escapeRegExp(s) + '.*'; + }); + if (this.final) + re += escapeRegExp(this.final) + '$'; + + var matcher = new RegExp(re, 'i'); + return helpers.testValues(function (v) { + return matcher.test(v); + }, tv); + } + + return false; +}; + + // Start LDAP server server.listen(parseInt(config.ldap_port), function () { console.log('ChurchTools-LDAP-Wrapper listening @ %s', server.url); diff --git a/package.json b/package.json index 6628630..c7a9b99 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,21 @@ "name": "ctldap", "license": "GPL-3.0", "description": "LDAP Wrapper for ChurchTools", - "version": "1.0.1", + "version": "2.1.0", "private": true, "dependencies": { - "bcrypt": "^2.0.1", + "bcrypt": "^3.0.4", "bluebird": "^3.5.0", "extend": "^3.0.1", "ini": "^1.1.0", - "ldap-escape": "^1.1.4", - "ldapjs": "^0.7.0", + "ldap-escape": "^1.1.5", + "ldapjs": "^1.0.2", "request": "^2.81.0", "request-promise": "^4.2.1" }, - "devDependencies": {} + "devDependencies": {}, + "scripts": { + "start": "node ctldap.js" + } + }