1#!/bin/sh
2
3# testenv.sh - script to check test environment
4#
5# Copyright (C) 2011-2018 Arthur de Jong
6#
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20# 02110-1301 USA
21
22set -e
23
24# get the script name
25script="`basename "$0"`"
26
27# find source and build directory (used for finding auxiliary files)
28srcdir="${srcdir-`dirname "$0"`}"
29builddir="${builddir-`dirname "$0"`}"
30
31# location of nslcd configuration file
32nslcd_cfg="${nslcd_cfg-/etc/nslcd.conf}"
33
34# the configured module name (usually ldap)
35if [ -f "$builddir"/../config.h ]
36then
37  module_name=`sed -n 's/^#define MODULE_NAME "\(.*\)"$/\1/p' "$builddir"/../config.h`
38fi
39module_name="${module_name-ldap}"
40
41# find the names of services that are configured to use LDAP
42nss_list_configured()
43{
44  sed -n 's/^[ \t]*\([a-z]*\)[ \t]*:.*[ \t]'$module_name'.*$/\1/p' /etc/nsswitch.conf \
45    | xargs
46}
47
48# check whether the name is configure to do lookups through LDAP
49nss_is_enabled()
50{
51  name="$1"
52  grep '^[ \t]*'$name'[ \t]*:.*'$module_name'.*' /etc/nsswitch.conf > /dev/null
53}
54
55# check to see if name is configured to do lookups through
56# LDAP and enable if not
57enable_nss()
58{
59  name="$1"
60  if nss_is_enabled "$name"
61  then
62   :
63  else
64    echo "$script: /etc/nsswitch.conf: enable LDAP lookups for $name" >&2
65    if grep -q '^[ \t]*'$name'[ \t]*:' /etc/nsswitch.conf
66    then
67      # modify an existing entry by just adding ldap to the end
68      sed -i 's/^\([ \t]*'$name'[ \t]*:.*[^ \t]\)[ \t]*$/\1 '$module_name'/' /etc/nsswitch.conf
69    else
70      # append a new line
71      printf '%-15s '$module_name'\n' $name':' >> /etc/nsswitch.conf
72    fi
73    # invalidate nscd cache
74    nscd -i "$name" > /dev/null 2>&1 || true
75  fi
76  # we're done
77  return 0
78}
79
80# put a PAM stack in place that enables lookups through LDAP
81# (this is currently hard-coded to only support Debian-based systems)
82enable_pam() {
83  cp "$srcdir"/debian-pam-config /usr/share/pam-configs/ldap
84  pam-auth-update --enable --force ldap
85}
86
87# check nsswitch.conf to see if dbs use ldap
88check_nsswitch() {
89  required="${1:-passwd group}"
90  if [ -r /etc/nsswitch.conf ]
91  then
92    :
93  else
94    echo "$script: ERROR: /etc/nsswitch.conf: not found" >&2
95    return 1
96  fi
97  enabled=`nss_list_configured`
98  if [ -z "$enabled" ]
99  then
100    echo "$script: ERROR: /etc/nsswitch.conf: no LDAP maps configured" >&2
101    return 1
102  fi
103  for x in $required
104  do
105    if nss_is_enabled "$x"
106    then
107      :
108    else
109      echo "$script: ERROR: /etc/nsswitch.conf: $x not using ldap" >&2
110      return 1
111    fi
112  done
113  echo "$script: nsswitch.conf configured for $enabled"
114  return 0
115}
116
117# check PAM stack
118check_pam() {
119  # TODO: implement some tests
120  return 0
121}
122
123# perform an LDAP search
124do_ldap_search() {
125  uri="$1"
126  base="$2"
127  host=`echo "$uri/" | sed -n 's|:368||;s|ldap://\([^/]*\)/.*$|\1|p'`
128  ldapsearch -b "$base" -s base -x -H "$uri" '(objectClass=*)' 2> /dev/null || \
129    ([ -n "$host" ] && LDAPSASL_MECH=none ldapsearch -b "$base" -s base -h "$host" '(objectClass=*)' 2> /dev/null) || \
130    true
131}
132
133# check whether the LDAP server is available
134check_ldap_server() {
135  # see if we can find ldapsearch
136  [ -x "`which ldapsearch 2> /dev/null || true`" ] || {
137    echo "$script: ERROR: ldapsearch not found" >&2
138    return 1
139  }
140  # get first URI from config
141  uri="${1:-`sed -n 's/^uri *//p' "$nslcd_cfg" 2>/dev/null | head -n 1`}"
142  uri="${uri:-`sed -n 's/^uri *//p' "$srcdir"/nslcd-test.conf 2>/dev/null | head -n 1`}"
143  uri="${uri:-ldap://127.0.0.1}"
144  base="${2:-dc=test,dc=tld}"
145  # try to fetch the base DN
146  if do_ldap_search "$uri" "$base" < /dev/null | grep "^dn: $base\$" > /dev/null
147  then
148    echo "$script: LDAP server $uri providing $base"
149    return 0
150  fi
151  echo "$script: ERROR: LDAP server $uri not available for $base" >&2
152  return 1
153}
154
155# check nslcd.conf file for presence and correct configuration
156check_nslcd_conf() {
157  # check if file is present
158  [ -r "$nslcd_cfg" ] || {
159    echo "$script: ERROR: $nslcd_cfg: not found" >&2
160    return 1
161  }
162  # TODO: more tests...
163  return 0
164}
165
166# basic check to see if nslcd is running
167check_nslcd_running() {
168  if [ -r /var/run/nslcd/socket ] && \
169     [ -f /var/run/nslcd/nslcd.pid ] && \
170     kill -0 `cat /var/run/nslcd/nslcd.pid` > /dev/null 2>&1
171  then
172    echo "$script: nslcd running (pid `cat /var/run/nslcd/nslcd.pid`)" >&2
173    return 0
174  fi
175  echo "$script: ERROR: nslcd not running" >&2
176  return 1
177}
178
179case "$1" in
180  enable_nss|nss_enable)
181    # modify /etc/nsswitch.conf to enable ldap for db
182    shift
183    while [ $# -gt 0 ]
184    do
185      enable_nss "$1"
186      shift
187    done
188    exit 0
189    ;;
190  enable_pam)
191    enable_pam
192    exit 0
193    ;;
194  check)
195    # perform all tests for test environment
196    res=0
197    check_nsswitch || res=1
198    check_pam || res=1
199    check_ldap_server || res=1
200    check_nslcd_conf || res=1
201    check_nslcd_running || res=1
202    [ $res -eq 0 ] && echo "$script: test environment OK"  || true
203    exit $res
204    ;;
205  check_nss)
206    # check nsswitch.conf to see if dbs use ldap
207    shift
208    check_nsswitch "$*" || exit 1
209    exit 0
210    ;;
211  check_ldap)
212    # check availability of LDAP server
213    # (optional URI and BASE arguments)
214    shift
215    check_ldap_server "$@" || exit 1
216    exit 0
217    ;;
218  check_nslcd)
219    # check nslcd availability
220    res=0
221    check_ldap_server || res=1
222    check_nslcd_conf || res=1
223    check_nslcd_running || res=1
224    [ $res -eq 0 ] && echo "$script: test environment OK"  || true
225    exit $res
226    ;;
227  *)
228    echo "Usage: $0 {enable_nss|enable_pam|check|check_nss|check_ldap}" >&2
229    exit 1
230    ;;
231esac
232