#!/bin/bash # Define logging functions send_systemd_notify() { # return if no systemd-notify found type systemd-notify >/dev/null 2>&1 || return systemd-notify "$@" } log_failure_msg() { send_systemd_notify --status "Error: $@" echo $@ } # Create slapd config for the NorduGrid/ARC information system ARC_LOCATION=${ARC_LOCATION:-/cvmfs/dirac.egi.eu/dirac/v8.0.27/Linux-x86_64} if [ ! -d "$ARC_LOCATION" ]; then log_failure_msg "ARC_LOCATION ($ARC_LOCATION) not found" exit 1 fi # ARC_CONFIG if [ "x$ARC_CONFIG" = "x" ]; then if [ -r $ARC_LOCATION/etc/arc.conf ]; then ARC_CONFIG=$ARC_LOCATION/etc/arc.conf elif [ -r /etc/arc.conf ]; then ARC_CONFIG=/etc/arc.conf fi if [ ! -r "$ARC_CONFIG" ]; then log_failure_msg "arc.conf is missing at path: $ARC_CONFIG or no ARC_LOCATION is set" log_failure_msg "If this file is in a non-standard place it can be set" log_failure_msg " with the ARC_CONFIG environment variable" exit 1 fi fi # Define runtime config location for infosys LDAP prefix=/cvmfs/dirac.egi.eu/dirac/v8.0.27/Linux-x86_64 runtime_config_dir=/run/arc if [ ! -d "$runtime_config_dir" ]; then mkdir -p "$runtime_config_dir" fi export ARC_RUNCONFIG="$runtime_config_dir/arc-infosys-ldap.conf" unset runtime_config_dir unset prefix # Define arcconfig-parser and dump running configuration arcconfig_parser=${ARC_LOCATION}/libexec/arc/arcconfig-parser ${arcconfig_parser} -c ${ARC_CONFIG} --save -r ${ARC_RUNCONFIG} # Check for infosys block if ! ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys; then log_failure_msg "Missing [infosys] configuration block" exit 1 fi # Check for infosys/ldap block if ! ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/ldap; then log_failure_msg "Missing [infosys/ldap] configuration block" exit 1 fi eval $(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/ldap -b infosys -b common -e bash) bdii_user=$CONFIG_user if [ -z "$bdii_user" ]; then # Get ldap user from passwd bdii_user=`getent passwd ldap openldap | sed 's/:.*//;q'` if [ -z "$bdii_user" ]; then echo "Warning, could not find ldap or openldap user" echo "resorting to using the root user" bdii_user=root fi fi # These values may be set in arc.conf, otherwise use sensible defaults slapd_loglevel=${CONFIG_slapd_loglevel:-0} slapd_hostnamebind=${CONFIG_slapd_hostnamebind:-"*"} slapd_port=${CONFIG_port:-2135} ldap_schema_dir=${CONFIG_ldap_schema_dir} threads=${CONFIG_threads:-32} timelimit=${CONFIG_timelimit:-2400} bdii_location=${CONFIG_bdii_location:-/usr} infosys_ldap_run_dir=${CONFIG_infosys_ldap_run_dir:-/run/arc/infosys} mkdir -p ${infosys_ldap_run_dir} chown ${bdii_user}: ${infosys_ldap_run_dir} bdii_var_dir=${CONFIG_bdii_var_dir:-/var/lib/arc/bdii} bdii_run_dir=${CONFIG_bdii_run_dir:-/run/arc/bdii} # PIDFile location handling slapd_pid_file=$( readlink -m ${bdii_run_dir}/db/slapd.pid ) # forced pidfile location instead of arc.conf-based (if FORCE_ARC_RUNDIR is set) if [ -n "$FORCE_ARC_RUNDIR" ]; then pid_dir="${FORCE_ARC_RUNDIR}/bdii/db" mkdir -p "$pid_dir" chown -R ${bdii_user}: "$pid_dir" pid_file="$( readlink -m ${pid_dir}/slapd.pid )" if [ "x${slapd_pid_file}" != "x${pid_file}" ]; then custom_pid_file="${slapd_pid_file}" rm -f "$custom_pid_file" slapd_pid_file="${pid_file}" fi unset pid_dir pid_file fi rm -f "${slapd_pid_file}" bdii_db_config=${CONFIG_bdii_db_config:-"/etc/bdii/DB_CONFIG"} bdii_database=${CONFIG_bdii_database:-"hdb"} # Check for existance of core ldap schema coreschema=$(find /etc/openldap /etc/ldap ${ldap_schema_dir} -name core.schema \ -printf "%h/%f\n" 2>/dev/null) if [ "x" = "x$coreschema" ]; then log_failure_msg "Could not find ldap core schema file" exit 1 fi # Check for existance of Glue schemas. glueschemadir=$(find /etc/openldap /etc/ldap ${ldap_schema_dir} -name Glue-CORE.schema \ -printf "%h\n" 2>/dev/null) if [ "x" = "x$glueschemadir" ]; then log_failure_msg "Could not find glue schema directory under /etc" exit 1 fi # Check for existence of a system ldap, this command will be used by bdii slapd_cmd= if [ "x" = "x$CONFIG_slapd" ]; then O_IFS=$IFS IFS=: for dir in $PATH; do if [ -x "$dir/slapd" ]; then slapd_cmd="$dir/slapd" break fi done IFS=$O_IFS else slapd_cmd=$CONFIG_slapd fi if [ -z "$slapd_cmd" ] || [ ! -x "$slapd_cmd" ]; then log_failure_msg "Could not find ldap server binary, usually /usr/sbin/slapd" exit 1 fi find_ldap_database_module() { # First try to find a separate module ldapdir=$(find /usr/lib64/openldap /usr/lib/openldap /usr/lib64/ldap \ /usr/lib/ldap -name "back_${database}.la" -printf ":%h/" 2>/dev/null) if [ -n "$ldapdir" ]; then # Separate module found ldapmodule="moduleload back_${database}" grep -E -q "${ldapdir}(:|$)" <<< ${ldapdirs} || \ ldapdirs=${ldapdirs}${ldapdir} else # Separate module not found - check for preloaded module ldapmodule= if [ $(grep -Ec "${database}_db_init|${database}_back_db_init" "$slapd_cmd") -eq 0 ]; then # Module not found database= fi fi } find_ldap_overlay_module() { # Try to find a separate module ldapdir=$(find /usr/lib64/openldap /usr/lib/openldap /usr/lib64/ldap \ /usr/lib/ldap -name "${overlay}.la" -printf ":%h/" 2>/dev/null) if [ -n "$ldapdir" ]; then # Separate module found ldapmodule="moduleload ${overlay}" grep -E -q "${ldapdir}(:|$)" <<< ${ldapdirs} || \ ldapdirs=${ldapdirs}${ldapdir} else # Module not found ldapmodule= overlay= fi } ldapdirs= database=${bdii_database} find_ldap_database_module if [ -z "${database}" ]; then log_failure_msg "Could not find ldap ${bdii_database} database module" exit 1 fi moduleload_bdii="${ldapmodule}" database=relay find_ldap_database_module if [ -z "${database}" ]; then echo "Could not find ldap relay database module, top-bdii integration is disabled." fi moduleload_relay="${ldapmodule}" overlay=rwm find_ldap_overlay_module if [ -z "$overlay" ]; then echo "Could not find ldap rwm overlay module, top-bdii integration is disabled." fi moduleload_rwm="${ldapmodule}" if ${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/index; then database=shell find_ldap_database_module if [ -z "${database}" ]; then log_failure_msg "Could not find ldap shell database module" exit 1 fi moduleload_shell="${ldapmodule}" else moduleload_shell= fi ldapdirs=`sed 's/^://' <<< $ldapdirs` #ldapdirs=`sed 's/:$//' <<< $ldapdirs` if [ -n "$ldapdirs" ]; then modulepath="modulepath $ldapdirs" else modulepath= fi for i in "/etc/bdii/BDII.schema" "${bdii_location}/etc/BDII.schema"; do if [ -r $i ]; then bdii_schema="include $i" break fi done bdii_slapd_conf=${infosys_ldap_run_dir}/bdii-slapd.conf rm -f $bdii_slapd_conf # Put SLAPD start helpers to known directory helpers_dir=$infosys_ldap_run_dir if [ -n "$FORCE_ARC_RUNDIR" ]; then helpers_dir="${FORCE_ARC_RUNDIR}/infosys" mkdir -p "${helpers_dir}" fi bdii_slapd_cmd=${helpers_dir}/bdii-slapd.cmd rm -f $bdii_slapd_cmd bdii_slapd_post_cmd=${helpers_dir}/bdii-slapd-post.cmd rm -f $bdii_slapd_post_cmd # Ensure the configuration file is not world-readable, # as it contains the slapd database password (umask 077; > $bdii_slapd_conf) pass=`/usr/bin/mkpasswd -s 0 2> /dev/null` || pass=$RANDOM$RANDOM cat <<-EOF >> $bdii_slapd_conf # This file was automatically generated by $0." # Do not modify. include ${coreschema} ${bdii_schema} #glue schemas include ${glueschemadir}/Glue-CORE.schema include ${glueschemadir}/Glue-CE.schema include ${glueschemadir}/Glue-CESEBind.schema include ${glueschemadir}/Glue-MDS.schema #glue2 schema include ${glueschemadir}/GLUE20.schema #nordugrid specific schemas include ${ARC_LOCATION}/share/arc/ldap-schema/nordugrid.schema $modulepath $moduleload_bdii $moduleload_relay $moduleload_rwm $moduleload_shell allow bind_v2 pidfile $slapd_pid_file argsfile $bdii_run_dir/db/slapd.args loglevel $slapd_loglevel threads $threads idletimeout 120 sizelimit unlimited timelimit $timelimit EOF if [ -n "${moduleload_rwm}" ]; then admindomain=$(${arcconfig_parser} --load -r ${ARC_RUNCONFIG} -b infosys/glue2 -o admindomain_name) admindomain="urn:ad:${admindomain:-UNDEFINEDVALUE}" cat <<-EOF >> $bdii_slapd_conf # Relay to allow top-bdii to parse info as the CE was a site-bdii database relay suffix "GLUE2GroupID=resource,o=glue" overlay rwm rwm-rewriteEngine on rwm-rewriteContext default rwm-rewriteRule "GLUE2GroupID=resource,o=glue" "GLUE2GroupID=services,o=glue" ":" rwm-rewriteContext searchFilter rwm-rewriteContext searchEntryDN rwm-rewriteContext searchAttrDN rwm-rewriteContext matchedDN database relay suffix "GLUE2GroupID=resource,GLUE2DomainID=$admindomain,o=glue" overlay rwm rwm-rewriteEngine on rwm-rewriteContext default rwm-rewriteRule "GLUE2GroupID=resource,GLUE2DomainID=$admindomain,o=glue" "GLUE2GroupID=services,o=glue" ":" rwm-rewriteContext searchFilter rwm-rewriteContext searchEntryDN rwm-rewriteRule "(.*[^ ],)?[ ]?GLUE2GroupID=services,o=glue" "\$1GLUE2GroupID=services,GLUE2DomainID=$admindomain,o=glue" ":" rwm-rewriteContext searchAttrDN rwm-rewriteContext matchedDN database relay suffix "GLUE2GroupID=services,GLUE2DomainID=$admindomain,o=glue" overlay rwm suffixmassage "GLUE2GroupID=services,o=glue" EOF fi cat <<-EOF >> $bdii_slapd_conf # ${bdii_database} database definitions for o=grid database ${bdii_database} cachesize 150000 dbnosync suffix "o=grid" checkpoint 131072 60 rootdn "o=grid" rootpw $pass directory $bdii_var_dir/db/arc # ${bdii_database} database definitions for o=glue database ${bdii_database} cachesize 150000 dbnosync suffix "o=glue" checkpoint 131072 60 rootdn "o=glue" rootpw $pass directory $bdii_var_dir/db/glue2 # ${bdii_database} database definitions for o=infosys database ${bdii_database} cachesize 60 dbnosync suffix "o=infosys" checkpoint 131072 60 rootdn "o=infosys" rootpw $pass directory $bdii_var_dir/db/stats EOF chown $bdii_user: $bdii_slapd_conf [ -x /sbin/restorecon ] && /sbin/restorecon $bdii_slapd_conf # Write slapd starting command if [ "x$slapd_hostnamebind" = "x*" ]; then echo exec ${slapd_cmd} -f ${bdii_slapd_conf} -h \"ldap://${slapd_hostnamebind}:${slapd_port}\" -u ${bdii_user} > ${bdii_slapd_cmd} else echo exec ${slapd_cmd} -f ${bdii_slapd_conf} -h \"ldap://localhost:${slapd_port} ldap://${slapd_hostnamebind}:${slapd_port}\" -u ${bdii_user} > ${bdii_slapd_cmd} fi chmod +x ${bdii_slapd_cmd} # Write post-exec script to check slapd is up and running cat <<-EOF > ${bdii_slapd_post_cmd} iterlimit=30 while [ \$iterlimit -ge 0 ] && ! [ -r "${slapd_pid_file}" ]; do sleep 1 iterlimit=\$(expr \$iterlimit - 1) done EOF # copy forced pidfile to custom arc.conf pidfile (if forced pid was requested) if [ -n "${custom_pid_file}" ]; then echo "mkdir -p \"${custom_pid_file%/*}\"" >> ${bdii_slapd_post_cmd} echo "cp -a \"${slapd_pid_file}\" \"${custom_pid_file}\"" >> ${bdii_slapd_post_cmd} fi # Initialize the database directories mkdir -p $bdii_run_dir/db mkdir -p $bdii_run_dir/archive chown $bdii_user: $bdii_run_dir chown $bdii_user: $bdii_run_dir/db chown $bdii_user: $bdii_run_dir/archive [ -x /sbin/restorecon ] && /sbin/restorecon -R $bdii_run_dir/db [ -x /sbin/restorecon ] && /sbin/restorecon -R $bdii_run_dir/archive mkdir -p $bdii_var_dir/archive mkdir -p $bdii_var_dir/db/arc mkdir -p $bdii_var_dir/db/glue2 mkdir -p $bdii_var_dir/db/stats rm -f $bdii_var_dir/db/arc/* 2>/dev/null rm -f $bdii_var_dir/db/glue2/* 2>/dev/null rm -f $bdii_var_dir/db/stats/* 2>/dev/null chown $bdii_user: $bdii_var_dir/db chown $bdii_user: $bdii_var_dir/archive chown $bdii_user: $bdii_var_dir/db/arc chown $bdii_user: $bdii_var_dir/db/glue2 chown $bdii_user: $bdii_var_dir/db/stats [ -x /sbin/restorecon ] && /sbin/restorecon -R $bdii_var_dir/db [ -x /sbin/restorecon ] && /sbin/restorecon -R $bdii_var_dir/archive # Workaround for BDII DB_CONFIG cachesize bigger than actual memory set_cachesize_line=`egrep '^[[:space:]]*'set_cachesize ${bdii_db_config}` if [ -n "${set_cachesize_line}" ]; then if [ -e /proc/meminfo ]; then memsize=$(grep MemFree /proc/meminfo | awk '{printf "%.0f", $2 * 1024}') default_set_cachesize=$(echo ${set_cachesize_line} | awk '{print $2 * 1073741824 + $3}') half_memsize=$(( ${memsize} / 2 )) if [ $default_set_cachesize -ge $half_memsize ]; then echo "The system does not fulfill BDII optimal memory requirements" echo "ARC will try to fix it anyway..." new_set_cachesize=$(( $memsize / 16 )) TEMPBDIIDBCONFIG=`mktemp -q /tmp/DB_CONFIG.XXXXXX` chmod 644 $TEMPBDIIDBCONFIG sed "s/^set_cachesize.*$/set_cachesize 0 $new_set_cachesize 1/" ${bdii_db_config} > $TEMPBDIIDBCONFIG bdii_db_config=${TEMPBDIIDBCONFIG} echo "DB_CONFIG set_cachesize is now: 0 $new_set_cachesize 1" fi else echo "/proc/meminfo does not exist. Cannot apply BDII memory workaround" echo "slapd might fail to start" fi fi # End of BDII set_cachesize workaround # copy BDII DB_CONFIG in ARC locations cp ${bdii_db_config} ${bdii_var_dir}/db/arc/DB_CONFIG cp ${bdii_db_config} ${bdii_var_dir}/db/glue2/DB_CONFIG cp ${bdii_db_config} ${bdii_var_dir}/db/stats/DB_CONFIG chown $bdii_user: ${bdii_var_dir}/db/arc/DB_CONFIG chown $bdii_user: ${bdii_var_dir}/db/glue2/DB_CONFIG chown $bdii_user: ${bdii_var_dir}/db/stats/DB_CONFIG # if the BDII low memory workaround has been applied, remove the temp file if [ -r $TEMPBDIIDBCONFIG ]; then rm -f $TEMPBDIIDBCONFIG fi