#!/bin/bash -x set -e #The postinst script may be called in the following ways: #'postinst configure most-recently-configured-version' # The files contained in the package will be unpacked. All package # dependencies will at least be unpacked. If there are no circular # dependencies involved, all package dependencies will be configured. # For behavior in the case of circular dependencies, see the discussion # in Binary Dependencies - Depends, Recommends, Suggests, Enhances, Pre-Depends, Section 7.2. #old-'postinst abort-upgrade new-version' #conflictor's-'postinst abort-remove in-favour package new-version' #'postinst abort-remove' #deconfigured's-'postinst abort-deconfigure in-favour failed-install-package version [removing conflicting-package version]' # The files contained in the package will be unpacked. All package # dependencies will at least be "Half-Installed" and will have previously # been configured and not removed. However, dependencies may not be # configured or even fully unpacked in some error situations.[47] # The postinst should still attempt any actions for which its dependencies # are required, since they will normally be available, but consider # the correct error handling approach if those actions fail. # Aborting the postinst action if commands or facilities from the # package dependencies are not available is often the best approach. ##### ##### Read the commandline options ##### Only 'configure' is handled with processing, other actions ##### are ignored for now ##### ACTION=${1} ARG_VERSION=${2} ##### ##### Source the debconf library ##### if [ -e "/usr/share/debconf/confmodule" ]; then . /usr/share/debconf/confmodule else echo "debconf must be installed. Exiting." exit 1 fi ##### ##### GLOBAL VARIABLES ##### declare RECONFIGURE declare FIRSTINST declare UPGRADE declare IP_ADDRESS declare CONTEXT # XML_TEMPLATE_FLAGS associative array will contain the boolean values for the various flags as specified in the xml config file # Data Structure=([templateName]="seen-flag derived-value-flag user-entered-value-flag configured-value-flag") declare -A XML_TEMPLATE_FLAGS # XML_QUESTION_VALUES associative array will contain the value to the template questions as specified in the xml config file # Data Structure=([templateName]="value") declare -A XML_QUESTION_VALUES # DEB_QUESTION_FLAGS associative array will contain the boolean values for the various flags as stored in the debian backend db # Data Structure=([templateName]="seen-flag derived-value-flag user-entered-value-flag configured-value-flag") declare -A DEB_QUESTION_FLAGS # DEB_QUESTION_VALUES associative array will contain the values for the template questions as stored in the debian backend db # Data Structure=([templateName]="value") declare -A DEB_QUESTION_VALUES # DEB_QUESTION_VALUES associative array will contain a boolean for the template questions that have changed in the debian backend db # Data Structure=([templateName]="true|false") declare -A DB_QUESTION_CHANGED # The Global Constants TOMCAT=tomcat8 TOMCAT_USER=tomcat8 DATAONE_USER=tomcat8 TOMCAT_HOME=/var/lib/tomcat8 JDK_PACKAGE=openjdk-8-jdk JDK_HOME=/usr/lib/jvm/java-8-openjdk-amd64 DEFAULT_JAVA_HOME=/usr/lib/jvm/default-java SOURCE_DIR=/usr/share/dataone-cn-os-core SCRIPT_DIR=${SOURCE_DIR}/debian APACHE_CONF_DIR=/etc/apache2 MOD_JK_CONF_DIR=/etc/libapache2-mod-jk APACHE_WWW_DIR=/var/www D1_CONF_DIR=/etc/dataone NODE_PROPS="$D1_CONF_DIR/node.properties" LDAP_CONF_DIR=/etc/ldap SITES="cn-ssl" JAVA_SECURITY=${JDK_HOME}/jre/lib/security/java.security JAVA_SECURITY_EXT_DIR=${JDK_HOME}/jre/lib/ext JAVA_KEYSTORE=${JDK_HOME}/jre/lib/security/cacerts LDAP_USER=openldap CILOGON_CERTS="cilogon-basic.pem cilogon-silver.pem cilogon-openid.pem" SSL_CERT_DIR=/etc/ssl/certs #SSL_SERVER_KEY_DIR=/etc/ssl/private/ D1_LOG_DIR=/var/log/dataone D1_LOG_FILE=dataone-cn-os-core.install.log D1_TMP_DIR=/tmp D1_DEB_CONF_XML_URL="https://repository.dataone.org/software/cicore/trunk/cn-buildout/dataone-cn-os-core/etc/dataone/d1DebConfig.xml" D1_DEB_CONF_XML="d1DebConfig.xml" D1_DEB_XSD_URL="https://repository.dataone.org/software/cicore/trunk/d1_schemas/dataoneDebPkgConfigTypes.xsd" D1_DEB_XSD="dataoneDebPkgConfigTypes.xsd" SUCCESS=0 SERVER_SSL_PREFIX_DIR=/etc/letsencrypt/live #positions of the flags in XML_TEMPLATE_FLAGS and DEB_QUESTION_FLAGS SEEN=0 DERIVED_VALUE=1 USER_ENTERED_VALUE=2 CONFIGURED_VALUE=3 # Use as suffix to backedup files LONG_DATE=$(date +%Y%m%d%H%M%S) # Create a difficult to guess token to pass for Solr auth SOLR_TOKEN=`date +%m%s%Y%N%d | sed 's/0//g'` ##### ##### FUNCTION DEFINITIONS ##### ##### ##### logError() ##### redirect stdout to stderr ##### functions to echo to STDERR or the install log instead of STDOUT ##### function logError() { echo -e "$@" 1>&2 } ##### ##### log() ##### append stdout to a logfile ##### function log() { # # Set Up logging # Reminder: don't echo to stdout, it messes up debconf # if [ ! -e ${D1_LOG_DIR} ]; then mkdir -p ${D1_LOG_DIR} fi chown -R tomcat8:tomcat8 ${D1_LOG_DIR} now=$(date "+%Y-%m-%d %H:%M:%S %Z: ") echo -e "${now} postinst $@" >> ${D1_LOG_DIR}/${D1_LOG_FILE} } ##### ##### exitWithFailureCode( ERROR_CODE ) ##### Ensures that passwords are wiped, database is stopped and exit is called with an error code ##### function exitWithFailureCode() { local errorCode=$1 db_set dataone-cn-os-core/cn.openldap.password "" # clear the cached pw db_fset dataone-cn-os-core/cn.openldap.password seen false db_set dataone-cn-os-core/cn.keystore.password "" # clear the cached pw db_fset dataone-cn-os-core/cn.keystore.password seen false db_stop exit $errorCode } ##### ##### join (EXPR, LIST) ##### Joins the separate strings of LIST into a single string with fields separated by the value of EXPR, and assigns that ##### new string to the global variable RTN_JOIN. ##### RTN_JOIN=""; function join() { RTN_JOIN=""; local exprString=$1 shift local -a listFields=($@) tmpJoin=$(printf "${exprString}%s" "${listFields[@]}") RTN_JOIN=${tmpJoin:1} RTN_JOIN="${RTN_JOIN#"${RTN_JOIN%%[![:space:]]*}"}" # remove leading whitespace characters RTN_JOIN="${RTN_JOIN%"${RTN_JOIN##*[![:space:]]}"}" # remove trailing whitespace characters return } ##### find out if ldap is running ##### if it is not try to restart ##### if it does not restart, then fail function confirm_ldap_running() { if ! (pidof slapd >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then if ! (/etc/init.d/slapd start >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then log "Slapd failed to start" return 1 fi sleep 10 if ! (pidof slapd >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Slapd cannot run" return 1 fi fi return 0 } ##### ##### process_derived_debian_config() ##### Find all the templates in XML_QUESTION_VALUES that are marked as ##### derived from other elements in the xml file and fill them out ##### function process_derived_debian_config() { log "start process_derived_debian_config" for template_name in ${!XML_QUESTION_VALUES[@]} do eval declare -a DEB_FLAG_BOOLEAN=("${DEB_QUESTION_FLAGS[$template_name]}") if [ "${DEB_FLAG_BOOLEAN[$SEEN]}" == "false" ]; then eval declare -a XML_TEMPLATE_BOOLEAN=("${XML_TEMPLATE_FLAGS[$template_name]}") if [ "${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]}" == "true" ]; then local SEEN_FLAG="true" local CHANGED_FLAG="false" case "${template_name}" in "dataone-cn-os-core/cn.iplist") CN_IPLIST=(`xmlstarlet sel -t --match "//environment[@context='${CONTEXT}']/machine" --value-of "concat(@ip, ' ')" "$D1_CONF_DIR/${D1_DEB_CONF_XML}"`) join ' ' ${CN_IPLIST[@]} local IPLIST=${RTN_JOIN} db_get $template_name local DEB_IPLIST=$RET if [[ -n $DEB_IPLIST && $IPLIST != $DEB_IPLIST ]]; then CHANGED_FLAG="true" fi db_set $template_name ${IPLIST} # log "IPLIST ${IPLIST[@]}" DEB_QUESTION_VALUES+=([$template_name]="${IPLIST}") ;; "dataone-cn-os-core/cn.hostnamelist") CN_HOSTNAMELIST=(`xmlstarlet sel -t --match "//environment[@context='${CONTEXT}']/machine/question[@keyref='dataone-cn-os-core/cn.hostname']" --value-of "concat(text(), ' ')" "$D1_CONF_DIR/${D1_DEB_CONF_XML}"`) join ' ' ${CN_HOSTNAMELIST[@]} local HOSTNAMELIST=${RTN_JOIN} db_get $template_name local DEB_HOSTNAMELIST=$RET if [[ -n $DEB_HOSTNAMELIST && $HOSTNAMELIST != $DEB_HOSTNAMELIST ]]; then CHANGED_FLAG="true" fi db_set $template_name ${HOSTNAMELIST} # log "HOSTNAMELIST ${HOSTNAMELIST[@]}" DEB_QUESTION_VALUES+=([$template_name]="${HOSTNAMELIST}") ;; "dataone-cn-os-core/cn.nodeids") CN_NODEIDSLIST=(`xmlstarlet sel -t --match "//environment[@context='${CONTEXT}']/machine/question[@keyref='dataone-cn-os-core/cn.nodeid']" --value-of "concat(text(), ' ')" "$D1_CONF_DIR/${D1_DEB_CONF_XML}"`) join ';' ${CN_NODEIDSLIST[@]} NODEIDSLIST=${RTN_JOIN} db_get $template_name local DEB_NODEIDSLIST=$RET if [[ -n $DEB_NODEIDSLIST && $NODEIDSLISTT != $DEB_NODEIDSLIST ]]; then CHANGED_FLAG="true" fi db_set $template_name ${NODEIDSLIST} # log "NODEIDSLIST ${NODEIDSLIST[@]}" DEB_QUESTION_VALUES+=([$template_name]="${NODEIDSLIST}") ;; "dataone-cn-os-core/cn.context.label") db_get $template_name local DEB_CONTEXT=$RET if [[ -n $DEB_CONTEXT && DEB_CONTEXT != $CONTEXT ]]; then CHANGED_FLAG="true" fi db_set $template_name ${CONTEXT} # log "CONTEXT $CONTEXT" DEB_QUESTION_VALUES+=([$template_name]="${CONTEXT}") ;; *) SEEN_FLAG="false" log "unable to process derived template $template_name." ;; esac db_fset $template_name seen $SEEN_FLAG XML_TEMPLATE_BOOLEAN[$SEEN]=$SEEN_FLAG db_fset $template_name derived-value ${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]} db_fset $template_name configured-value ${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]} db_fset $template_name user-entered-value ${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]} unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") DB_QUESTION_CHANGED+=([$template_name]="$CHANGED_FLAG") fi db_go fi done log "end process_derived_debian_config" } ##### ##### process_create_debian_config() ##### This function will populate the debian backend db for the ##### first time during an install ##### ##### From the templates in the structure XML_QUESTION_VALUES that were ##### pulled from the xml file ##### populate the datastructures DEB_QUESTION_VALUES and DEB_QUESTION_FLAGS ##### to the reflect the state of the debian backend database ##### function process_create_debian_config() { log "start process_create_debian_config" local TEMPLATE_VALUE local DB_VALUE local EXCEPTION_DB_VALUE #for each template in templates data structure, find out if DB 'seen' flag is false. #if seen is true, then accept the value as provided, or it's a noop (already configured by ansible). for template_name in ${!XML_QUESTION_VALUES[@]} do eval declare -a DEB_FLAG_BOOLEAN=("${DEB_QUESTION_FLAGS[$template_name]}") if [ "${DEB_FLAG_BOOLEAN[SEEN]}" == "false" ]; then eval declare -a XML_TEMPLATE_BOOLEAN=("${XML_TEMPLATE_FLAGS[$template_name]}") if [ "${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]}" == "true" ]; then #if configured-value is true, then get the answer from the questions section for the machine/environment db_set $template_name "${XML_QUESTION_VALUES[$template_name]}" db_fset $template_name seen true XML_TEMPLATE_BOOLEAN[$SEEN]="true" db_fset $template_name derived-value ${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]} db_fset $template_name configured-value ${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]} db_fset $template_name user-entered-value ${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]} DEB_QUESTION_VALUES+=([$template_name]="${XML_QUESTION_VALUES[$template_name]}") log "XML_QUESTION_VALUES $template_name ${XML_QUESTION_VALUES[$template_name]}" unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") DB_QUESTION_CHANGED+=([$template_name]="false") elif [ "${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]}" == "true" ]; then #if template flag user-entered-value is true, then prompt the user for input. if (db_input high "$template_name"); then db_go else ## find if the value was set by some other system, such as ansible log "unable to update user-entered template $template_name" db_get $template_name EXCEPTION_DB_VALUE=$RET if [[ -z ${EXCEPTION_DB_VALUE} ]]; then # nothing else to do here but fail, db_input failed and the value is not set in debconf backend log "failed to retrieve user-entered template $template_name" exitWithFailureCode 86 fi fi db_fset $template_name seen true XML_TEMPLATE_BOOLEAN[$SEEN]="true" db_fset $template_name derived-value ${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]} db_fset $template_name configured-value ${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]} db_fset $template_name user-entered-value ${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]} db_get $template_name TEMPLATE_VALUE=$RET DEB_QUESTION_VALUES+=([$template_name]="${TEMPLATE_VALUE}") log "USER ENTERED VALUE $template_name ${TEMPLATE_VALUE}" unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") DB_QUESTION_CHANGED+=([$template_name]="false") fi else ### it already been seen, pull the DEB_QUESTION values from the database db_get $template_name local DB_VALUE=$RET log "SETTING DEB_QUESTION_VALUES $template_name $DB_VALUE" DEB_QUESTION_VALUES+=([$template_name]="${DB_VALUE}") DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") fi done #if template flag derived-value is true, then ignore.(the derived templates will be processed after all other user-entered and configured values are set) process_derived_debian_config log "end process_create_debian_config" } ##### ##### process_update_debian_config() ##### This function will update the debian backend db for ##### anytime the package is upgraded ##### ##### From the templates in the structure XML_QUESTION_VALUES that were ##### pulled from the xml file ##### update the datastructures DEB_QUESTION_VALUES and DEB_QUESTION_FLAGS ##### to the reflect the state of the debian backend database ##### function process_update_debian_config() { log "start process_update_debian_config" local OLD_DB_VALUE local NEW_DB_VALUE # for an update: # for each template in templates data structure, find out if DB 'seen' flag is false. # if 'seen' is true, then accept the value as provided, or it's a noop (already configured by ansible). for template_name in ${!XML_QUESTION_VALUES[@]} do eval local -a DEB_FLAG_BOOLEAN=("${DEB_QUESTION_FLAGS[$template_name]}") eval local -a XML_TEMPLATE_BOOLEAN=("${XML_TEMPLATE_FLAGS[$template_name]}") #if seen is false, then check other flag values: if [ "${DEB_FLAG_BOOLEAN[$SEEN]}" == "false" ]; then # if db has a user-entered-value flag true and the template user-entered-value is false, there is a discrepency between what is expected and what has # been stored. This happens if the user has overrided the default behaviour somehow db_get $template_name OLD_DB_VALUE=$RET if [[ "$CONTEXT" != "CUSTOM" && "${DEB_FLAG_BOOLEAN[$USER_ENTERED_VALUE]}" == "true" && "${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]}" == "false" ]]; then # compare the values as stored in the template and the db. if [[ "${OLD_DB_VALUE}" == "${XML_QUESTION_VALUES[$template_name]}" ]]; then log "USER ENTERED VALUE changed to TEMPLATE_VALUE $template_name ${XML_QUESTION_VALUES[$template_name]}" # if the values are the same then, leave values alone. # update the flags in the db to coincide with the flag in the template, changed flag remains false for derived values. db_fset $template_name derived-value ${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]} db_fset $template_name configured-value ${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]} db_fset $template_name user-entered-value ${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]} if [ "${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]}" == "false" ]; then db_fset $template_name seen true XML_TEMPLATE_BOOLEAN[$SEEN]="true" fi DEB_FLAG_BOOLEAN[$USER_ENTERED_VALUE]="false" unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") DB_QUESTION_CHANGED+=([$template_name]="false") DEB_QUESTION_VALUES+=([$template_name]="${XML_QUESTION_VALUES[$template_name]}") else # if the values are different, then set the default value of the question from the one held by the db, and prompt the user,changed flag is true. # report the flag values as they are held in the db if (db_input high "$template_name"); then db_go else log "failed to update user-entered template $template_name" fi db_fset $template_name seen true DEB_FLAG_BOOLEAN[$SEEN]="true" unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${DEB_FLAG_BOOLEAN[@]}") db_get $template_name NEW_DB_VALUE=$RET if [[ "$OLD_DB_VALUE" == "$NEW_DB_VALUE" ]]; then DB_QUESTION_CHANGED+=([$template_name]="false") else DB_QUESTION_CHANGED+=([$template_name]="true") fi DEB_QUESTION_VALUES+=([$template_name]="${NEW_DB_VALUE}") # log "USER ENTERED VALUE entered $template_name $NEW_TEMPLATE_VALUE" fi fi # if xml and debian template flag is user-entered if [[ "${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]}" == "true" ]]; then # then set the default value of the question from the one held by the db # and prompt the user, changed flag is true. db_get $template_name OLD_DB_VALUE=$RET if (db_input high "$template_name"); then db_go else log "failed to update user-entered template $template_name" fi db_fset $template_name derived-value ${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]} db_fset $template_name configured-value ${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]} db_fset $template_name user-entered-value ${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]} db_fset $template_name seen true XML_TEMPLATE_BOOLEAN[$SEEN]="true" db_get $template_name NEW_DB_VALUE=$RET if [[ "$OLD_DB_VALUE" == "$NEW_DB_VALUE" ]]; then DB_QUESTION_CHANGED+=([$template_name]="false") else DB_QUESTION_CHANGED+=([$template_name]="true") fi DEB_QUESTION_VALUES+=([$template_name]="${NEW_DB_VALUE}") unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") # log "USER ENTERED VALUE entered $template_name $NEW_TEMPLATE_VALUE" fi # if configured-value is true, if [[ "${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]}" == "true" ]]; then # then compare the template and db values, if [[ "${OLD_DB_VALUE}" != "${XML_QUESTION_VALUES[$template_name]}" ]]; then # if they are different update the db and set changed flag to true db_set $template_name ${XML_QUESTION_VALUES[$template_name]} db_fset $template_name derived-value ${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]} db_fset $template_name configured-value ${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]} db_fset $template_name user-entered-value ${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]} db_fset $template_name seen true XML_TEMPLATE_BOOLEAN[$SEEN]="true" DEB_QUESTION_VALUES+=([$template_name]="${XML_QUESTION_VALUES[$template_name]}") unset -v DEB_QUESTION_FLAGS[$template_name] DEB_QUESTION_FLAGS+=([$template_name]="${XML_TEMPLATE_BOOLEAN[@]}") DB_QUESTION_CHANGED+=([$template_name]="true") # log "TEMPLATE VALUE of $template_name ${XML_QUESTION_VALUES[$template_name]}" else DEB_QUESTION_VALUES+=([$template_name]="${OLD_DB_VALUE}") DB_QUESTION_CHANGED+=([$template_name]="false") fi fi else ### it already been seen, pull the DEB_QUESTIONs from the database db_get $template_name local DB_VALUE=$RET # log "SETTING DEB_QUESTION_VALUES $template_name $DB_VALUE" DEB_QUESTION_VALUES+=([$template_name]="${DB_VALUE}") fi done process_derived_debian_config log "end process_update_debian_config" } ##### ##### resetTemplateSeenFlag() ##### reset all the DEB_QUESTION_FLAGS that have seen set to true to false ##### needed for coordination with ansible ##### function resetDebQuestionSeenFlag() { for template_name in ${!DEB_QUESTION_FLAGS[@]} do eval local -a DEB_FLAG_BOOLEAN=("${DEB_QUESTION_FLAGS[$template_name]}") if [[ "${DEB_FLAG_BOOLEAN[$SEEN]}" == "true" && "$template_name" != "dataone-cn-os-core/cn.openldap.firstcn" ]]; then db_fset $template_name seen false fi done } ##### ##### build_debianDB_template_data_structures() ##### read the flags from the debian backend db into bash datastructures ##### populating the DEB_QUESTION_VALUES will be performed later ##### function build_debianDB_template_data_structures() { if (debconf-show dataone-cn-os-core >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "before build_debianDB_template_data_structures" fi local -a DEBIAN_FLAGS local DEBIAN_FLAGS_STR for template_name in ${!XML_TEMPLATE_FLAGS[@]} do # note that the posistions of the flags in the array db_fget $template_name seen DEBIAN_FLAGS[$SEEN]=${RET} db_fget $template_name derived-value DEBIAN_FLAGS[$DERIVED_VALUE]=${RET} db_fget $template_name user-entered-value DEBIAN_FLAGS[$USER_ENTERED_VALUE]=${RET} db_fget $template_name configured-value DEBIAN_FLAGS[$CONFIGURED_VALUE]=${RET} join ' ' ${DEBIAN_FLAGS[@]} DEB_QUESTION_FLAGS+=([$template_name]="${RTN_JOIN}") done } ##### ##### build_xml_template_data_structures() ##### read the values from the xml config file into bash datastructures ##### determines the ip of the machine ##### sets the context ##### function build_xml_template_data_structures() { # local MY_POSSIBLE_IPS=(`/sbin/ifconfig -a | grep -o -P 'inet\s((?!127\.0\.\d+\.\d+)(?:(?:[01]?\d?\d?|2[0-4]\d|25[0-5])\.?){4})' | awk '{ print $2 }'`) local MY_POSSIBLE_IPS=(`hostname --all-ip-addresses`) local ALL_ENVIRONMENT_IPS=(`xmlstarlet sel -t --match "//environment[@context != 'CUSTOM']/machine" --value-of "concat(@ip, ' ')" "${D1_CONF_DIR}/${D1_DEB_CONF_XML}"`) for i in ${MY_POSSIBLE_IPS[@]} do if [[ "${ALL_ENVIRONMENT_IPS[@]}" =~ "${i}" ]]; then IP_ADDRESS=${i} fi done log "build_xml_template_data_structures from ${MY_POSSIBLE_IPS[@]} found $IP_ADDRESS" # build the datastructure to hold information from the templates section of the xml file. # seen derived-value user-entered-value configured-value local TEMPLATE_NAMES=(`xmlstarlet sel -t --match "//templates/template" --value-of "concat(@key, ' ')" "${D1_CONF_DIR}/${D1_DEB_CONF_XML}"`) if [ -n $IP_ADDRESS ]; then # The IP ADDRESS is found within the xml config file, therefore, we can continue to configure the system via xml configuration for template_name in ${TEMPLATE_NAMES[@]} do # log "build_xml_template_data_structures found $template_name" eval local -A FLAG_VALUES=(`xmlstarlet sel -t --match "//templates/template[@key='${template_name}']/flag" \ --value-of "string('[')" --value-of "@name" --value-of "string(']=\"')" \ --value-of "node()" --value-of "string('\"')" -n \ "${D1_CONF_DIR}/${D1_DEB_CONF_XML}"`) # log "build_xml_template_data_structures found $template_name ${!FLAG_VALUES[@]} ${FLAG_VALUES[@]}" XML_TEMPLATE_FLAGS+=([$template_name]="${FLAG_VALUES[seen]} ${FLAG_VALUES[derived-value]} ${FLAG_VALUES[user-entered-value]} ${FLAG_VALUES[configured-value]}") unset FLAG_VALUES done # Determine the context from the ip address local CN_CONTEXT_LIST=(`xmlstarlet sel -t --match "//machine[@ip='${IP_ADDRESS}']" --value-of " string('dataone-cn-os-core/cn.context.label ')" --value-of "parent::node()/@context" "${D1_CONF_DIR}/${D1_DEB_CONF_XML}"`) # Set the global context variable CONTEXT=${CN_CONTEXT_LIST[1]} XML_QUESTION_VALUES=([dataone-cn-os-core/cn.context.label]="$CONTEXT") # build the datastructure to hold information from the questions section of the xml file. or the value of OLD_IFS=$IFS IFS=$'\n' eval XML_QUESTION_VALUES+=(`xmlstarlet sel -t --match "//environment[@context='${CONTEXT}']/question" --value-of "string('[')" --value-of "@keyref" --value-of "string(']=\"')" --value-of "node()" --value-of "string('\"')" -n "$D1_CONF_DIR/${D1_DEB_CONF_XML}"`) eval XML_QUESTION_VALUES+=(`xmlstarlet sel -t --match "//machine[@ip='${IP_ADDRESS}']/question" --value-of "string('[')" --value-of "@keyref" --value-of "string(']=\"')" --value-of "node()" --value-of "string('\"')" -n "$D1_CONF_DIR/${D1_DEB_CONF_XML}"`) IFS=$OLD_IFS else # The IP ADDRESS was not found within the xml config file, therefore, we will build a CUSTOM installation in which the user must answer all the template questions IP_ADDRESS=$(hostname -i) CONTEXT="CUSTOM" for template_name in ${TEMPLATE_NAMES[@]} do XML_TEMPLATE_FLAGS+=([$template_name]="false false true false") done fi # XXX this is a hack for the time being. may need to add it to the template later # but it does not follow in the normal question/template fields of the # xml file db_set dataone-cn-os-core/cn.ipaddress "${IP_ADDRESS}" # clear the cached pw db_fset dataone-cn-os-core/cn.ipaddress seen true } ##### ##### download_verify_config_xml() ##### attempt to download the configuration xml from the dataone releases website ##### also attempt to download the xml schema of the configuration file as well ##### if both downloads are successful, then validate the downloaded config xml ##### and then copy over the configuration in /etc/dataone ##### if only the xml download is successful, then make certain it is wellformed ##### and then copy over the configuration in /etc/dataone ##### if neither download is successful, then the default ##### config xml in /etc/dataone will be used ##### ##### function download_validate_config_xml() { if (curl --silent --fail -o "${D1_TMP_DIR}/${D1_DEB_CONF_XML}" "${D1_DEB_CONF_XML_URL}" &>/dev/null ) && [ -e "${D1_TMP_DIR}/${D1_DEB_CONF_XML}" ]; then log "Downloaded ${D1_DEB_CONF_XML}" # Download the xml schema in order validate the xml file if (curl --silent --fail -o "${D1_TMP_DIR}/${D1_DEB_XSD}" "${D1_DEB_XSD_URL}" &>/dev/null) && [ -e "${D1_TMP_DIR}/${D1_DEB_XSD}" ]; then ### the val -b will print out the list of invalid xml files ### if files are valid, nothing will be returned if (xmlstarlet val -q -s "${D1_TMP_DIR}/${D1_DEB_XSD}" "${D1_TMP_DIR}/${D1_DEB_CONF_XML}" &>/dev/null); then log "${D1_DEB_CONF_XML} is valid" cp -f "${D1_TMP_DIR}/${D1_DEB_CONF_XML}" $D1_CONF_DIR log "copied ${D1_DEB_CONF_XML} to ${D1_CONF_DIR}" else log "invalid xml ${D1_DEB_CONF_XML} downloaded, using current version in ${D1_CONF_DIR} instead" fi else ### Here we have downloaded the xml file, but the xsd download failed. ### We could just check the xml file for well-formedness and continue with the downloaded file ### or we could ignore the downloaded xml and use the last known valid version in /etc/dataone log "unable to download ${D1_DEB_XSD} to validate ${D1_DEB_CONF_XML}" if (xmlstarlet val -q -w "${D1_TMP_DIR}/${D1_DEB_CONF_XML}" &>/dev/null); then log "${D1_DEB_CONF_XML} is wellformed." cp -f "${D1_TMP_DIR}/${D1_DEB_CONF_XML}" "${D1_CONF_DIR}/${D1_DEB_CONF_XML}" log "copied ${D1_DEB_CONF_XML} to ${D1_CONF_DIR}" else log "xml ${D1_DEB_CONF_XML} not well formed. Using current version in ${D1_CONF_DIR} instead" fi fi else log "Failure to download ${D1_DEB_CONF_XML}. use ${D1_CONF_DIR}/${D1_DEB_CONF_XML} instead" fi } ##### ##### configure_node_property() ##### given a template_name, find the value that should be substituted in the properties file ##### and perform the substitution ##### function configure_node_property() { local TEMPLATE_NAME=$1 local NODE_PROPS_FILE=$2 local OVERRIDE=$3 local NODE_VALUE if [ -e ${NODE_PROPS} ]; then # Fetch the context's node id list from the debconf database if [ -z "$OVERRIDE" ]; then NODE_VALUE=${DEB_QUESTION_VALUES[dataone-cn-os-core/$TEMPLATE_NAME]} else NODE_VALUE=$OVERRIDE fi sed -i.bak "s/\(${TEMPLATE_NAME} *=\).*/\1${NODE_VALUE}/i" ${NODE_PROPS_FILE} else log "The file ${NODE_PROPS} must be in place to proceed." exitWithFailureCode 64 fi } ##### ##### configure_node_property() ##### the /etc/dataone/node.properties file is configured per machine. ##### The values are pulled out of the debian database and ##### substituted for tokens found in the properties file ##### function configure_node_properties_file() { local NODE_PROPS="$D1_CONF_DIR/node.properties" configure_node_property "cn.context.label" $NODE_PROPS local SYNCHRONIZED=${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.synchronized]} if [[ "${SYNCHRONIZED}" != *false* ]];then configure_node_property "cn.iplist" $NODE_PROPS else configure_node_property "cn.iplist" $NODE_PROPS "127.0.0.1" fi configure_node_property "cn.nodeids" $NODE_PROPS configure_node_property "cn.nodeid" $NODE_PROPS configure_node_property "cn.router.nodeId" $NODE_PROPS configure_node_property "cn.router.hostname" $NODE_PROPS local HOST_NAME=${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.router.hostname]} PUBLICCERT_VALUE=${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.publiccert.filename]} CERT_FILE_PATH=${SERVER_SSL_PREFIX_DIR}/${HOST_NAME}/${PUBLICCERT_VALUE} CERT_FILE_PATH_ESC=${CERT_FILE_PATH//\//\\\/} log "Public cert filename is: ${CERT_FILE_PATH_ESC}" configure_node_property "cn.server.publiccert.filename" $NODE_PROPS "${CERT_FILE_PATH_ESC}" log "Start configuration of D1Client certificate" CLIENT_CERT_FILE_LABEL="D1Client.certificate.filename" if [[ -e ${NODE_PROPS} && "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.filename]}" != "false" ]]; then # Change the property of D1Client certificate filename to the one accepted during configuration if ! (sed -i.bak "s/\(${CLIENT_CERT_FILE_LABEL} *=\).*/\1${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.filename]}/" ${NODE_PROPS} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to modify ${CLIENT_CERT_FILE_LABEL} in ${D1_LOG_DIR}/${D1_LOG_FILE}" fi else log "Client cert filename is missing. Must set ${CLIENT_CERT_FILE_LABEL} in ${NODE_PROPS} for SSL to function properly" fi if ! (sed -i.bak "s/SOLRTOKEN/${SOLR_TOKEN}/" ${NODE_PROPS} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to modify SOLRTOKEN in ${NODE_PROPS}" fi if ! (sed -i.bak "s/CN_ENV_HOSTNAME_LIST/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.hostnamelist]}/" ${NODE_PROPS} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to modify CN_ENV_HOSTNAME_LIST in ${NODE_PROPS}" fi log "Start configuration of Hostname in ${NODE_PROPS}" # set the FQDN of the machine if [ -n "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.hostname]}" ]; then if ! (sed -i.bak "s/SERVER_NAME/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.hostname]}/" ${NODE_PROPS} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to modify SERVER_NAME in ${NODE_PROPS}" fi else log "dataone-cn-os-core/cn.hostname can not be set in ${NODE_PROPS}" fi } ##### ##### configure_certificates() ##### make certain that the x509 certificate and keys are in the ##### correct subjectory with the correct permissions ##### function configure_certificates() { log "Start configuration of DataONE CN client certificate" ################################################################## # Check the dataone client certificate provided by the user # This certificate can not be added to the SVN repository because it is not # secure to do so; it includes the public and private key # -- access to the file must be restricted ################################################################## if [ ! -e "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.filename]}" ]; then log "Client cert file is missing. Please provide it as ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.filename]}. Without this, SSL will not function properly." exitWithFailureCode 62 fi ################################################################## # Check the dataone private key provided by the user # This key can not be added to the SVN repository because it is not # secure to do so -- access to the file must be restricted ################################################################## # check if this is a new install log "Start configuration of DataONE private key" local HOST_NAME=${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.router.hostname]} if [ ! -e "${SERVER_SSL_PREFIX_DIR}/${HOST_NAME}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.privatekey.filename]}" ];then log "Key file is missing. Please provide it as ${SERVER_SSL_PREFIX_DIR}/${HOST_NAME}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.privatekey.filename]}. Without this, SSL will not function properly." exitWithFailureCode 63 fi if [ ! -e "${SERVER_SSL_PREFIX_DIR}/${HOST_NAME}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.publiccert.filename]}" ]; then log "Server Public Certificate file is missing. Please provide it as ${SERVER_SSL_PREFIX_DIR}/${HOST_NAME}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.publiccert.filename]}. Without this, SSL will not function properly." exitWithFailureCode 64 fi # set permissions correctly for the certs and private dirs if [ -d ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]} ] && [ -d ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]} ]; then if ! (chown -R ${TOMCAT_USER}:ssl-cert ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to chown on ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}" fi if ! (chown -R ${TOMCAT_USER}:ssl-cert ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to chown on ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}" fi else log "either ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]} or ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]} is missing. Much will fail after this install process" fi } ##### ##### configure_ufw() ##### set up the Coordinating Node firewall ##### function configure_ufw() { log "Start configuration of UFW" ############################################################################### # Configure UFW ############################################################################### #open up the correct ports if [[ "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.iplist]}" == [1-9]* ]]; then for IP in ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.iplist]} do if [[ "${IP}" != "${IP_ADDRESS}" ]]; then # ldap syncrepl if ! (ufw allow to any port 389 from ${IP} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to allow ufw 389 from ${IP}" fi log "Added 'ufw allow to any port 389 from ${IP}' rule" fi done fi if ! (ufw allow ssh >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to allow ufw ssh" exitWithFailureCode 65 fi # critical for remote management, don't remove if ! (ufw allow http >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to allow ufw http" exitWithFailureCode 66 fi if ! (ufw allow https >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to allow ufw https" exitWithFailureCode 67 fi MONITOR_HOST=$(nslookup monitor.dataone.org | grep Add | grep -v '#' | cut -f 2 -d ' ') if ! (ufw allow from ${MONITOR_HOST} to any port 6556 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to allow from ${MONITOR_HOST} to any port 6556" fi } ##### ##### install_configure_jdk ##### install and configure the jdk ##### function configure_jdk() { log "configure default java, java and keytool" update-alternatives --set java ${JDK_HOME}/jre/bin/java update-alternatives --set javac ${JDK_HOME}/bin/javac update-alternatives --set keytool ${JDK_HOME}/jre/bin/keytool #update-alternatives --set javaws ${JDK_HOME}/jre/bin/javaws log "set the defaul-java to openjdk 8" rm -rf $DEFAULT_JAVA_HOME ln -s $JDK_HOME $DEFAULT_JAVA_HOME } ##### ##### configure_keystore() ##### import certificates into the java keystore ##### function configure_keystore() { ############################################################################### # Configure Java keystore with GoDaddy and DataONE CA ############################################################################### # Get the password local JAVA_KEYSTORE_PASSWORD="${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.keystore.password]}" # output from keytool is piped to exit 0 so that if keytool fails due to the file already having # been added then the postinst script does not fail due to the subshell failing # After we switched to use LE certificates, it is not necessary to import its certificates to the java key store anymore since they are there. #local INTERMEDIATE_BUNDLE="${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.cachain.filename]}" #log "Attempting to remove ${SSL_CERT_DIR}/${INTERMEDIATE_BUNDLE} from Java keystore: ${JAVA_KEYSTORE}" #(keytool -delete -noprompt -alias ${INTERMEDIATE_BUNDLE} -keystore ${JAVA_KEYSTORE} -storepass ${JAVA_KEYSTORE_PASSWORD} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 | exit 0) #log "Adding ${SSL_CERT_DIR}/${INTERMEDIATE_BUNDLE} to Java keystore: ${JAVA_KEYSTORE}" #(keytool -importcert -noprompt -alias ${INTERMEDIATE_BUNDLE} -file ${SSL_CERT_DIR}/${INTERMEDIATE_BUNDLE} -keystore ${JAVA_KEYSTORE} -storepass ${JAVA_KEYSTORE_PASSWORD} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 | exit 0) # get the DataONE CA (keytool -importcert -noprompt -alias DataONECA -file ${SSL_CERT_DIR}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.dataone.ca.filename]} -keystore ${JAVA_KEYSTORE} -storepass ${JAVA_KEYSTORE_PASSWORD} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 | exit 0) log "Adding ${SSL_CERT_DIR}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.dataone.ca.filename]} to Java keystore: ${JAVA_KEYSTORE} -$RTN_KEYTOOL" # Always clear the cached keystore password db_set dataone-cn-os-core/cn.keystore.password "" # clear the cached pw db_fset dataone-cn-os-core/cn.keystore.password seen false eval local -a DEB_FLAG_BOOLEAN=("${DEB_QUESTION_FLAGS[dataone-cn-os-core/cn.keystore.password]}") DEB_FLAG_BOOLEAN[$SEEN]="false" unset -v DEB_QUESTION_FLAGS[dataone-cn-os-core/cn.keystore.password] DEB_QUESTION_FLAGS+=([dataone-cn-os-core/cn.keystore.password]="${DEB_FLAG_BOOLEAN[@]}") } ##### ##### configure_apache() ##### modify apache configuration files to allow for dataone operations ##### such as ssl ##### function configure_apache() { ############################################################################### # Configure Apache ############################################################################### ## Stop apache log "Stopping Apache" if (pidof apache2 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then if ! (/etc/init.d/apache2 stop >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Error Unable to stop apache" exitWithFailureCode 68 fi fi ## change the available port 80 only to localhost if [ -e ${APACHE_CONF_DIR}/ports.conf ]; then ## if ports.conf has *:80 as its NameVirtualHost, then change it to 127.0.0.1:80 if (egrep -q 'NameVirtualHost[[:space:]]+\*:80' ${APACHE_CONF_DIR}/ports.conf); then if ! (sed -i.bak --regexp-extended 's/(NameVirtualHost[[:space:]]+)\*:80/\1127.0.0.1:80/;' ${APACHE_CONF_DIR}/ports.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify NameVirtualHost in ${APACHE_CONF_DIR}/ports.conf" fi fi fi ## make certain we have a directory for the JKMount directives of our apps if [ ! -d ${APACHE_CONF_DIR}/jk_mount ]; then if ! (mkdir -p ${APACHE_CONF_DIR}/jk_mount >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to mkdir ${APACHE_CONF_DIR}/jk_mount" fi if ! (chmod 750 ${APACHE_CONF_DIR}/jk_mount >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chmod ${APACHE_CONF_DIR}/jk_mount" fi fi ## if the jk.conf file has changed then copy in a new jk.conf file if [ -e ${APACHE_CONF_DIR}/mods-available/jk.conf ]; then ## if there is a difference, then the diff script returns false if ! (diff ${SCRIPT_DIR}/jk.conf ${APACHE_CONF_DIR}/mods-available/jk.conf); then log "Backing up ${APACHE_CONF_DIR}/mods-available/jk.conf to ${APACHE_CONF_DIR}/mods-available/jk.conf.${LONG_DATE}" if ! (mv ${APACHE_CONF_DIR}/mods-available/jk.conf ${APACHE_CONF_DIR}/mods-available/jk.conf.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to move ${APACHE_CONF_DIR}/mods-available/jk.conf ${APACHE_CONF_DIR}/mods-available/jk.conf.${LONG_DATE}" fi fi fi log "Copying jk.conf to ${APACHE_CONF_DIR}/mods-available/" if ! (cp ${SCRIPT_DIR}/jk.conf ${APACHE_CONF_DIR}/mods-available/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/jk.conf to ${APACHE_CONF_DIR}/mods-available/" fi ## copy in workers.properties file for mod-jk if [ -e ${MOD_JK_CONF_DIR}/workers.properties ]; then ## if there is a difference, then the diff script returns false if ! (diff ${SCRIPT_DIR}/workers.properties ${MOD_JK_CONF_DIR}/workers.properties); then if [ -n "${WORKERS_PROPS_DIFF}" ]; then log "Backing up ${MOD_JK_CONF_DIR}/workers.properties to ${MOD_JK_CONF_DIR}/workers.properties.${LONG_DATE}" if ! (mv ${MOD_JK_CONF_DIR}/workers.properties ${MOD_JK_CONF_DIR}/workers.properties.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to move ${MOD_JK_CONF_DIR}/workers.properties to ${MOD_JK_CONF_DIR}/workers.properties.${LONG_DATE}" fi fi fi fi log "Copying workers.properties to ${MOD_JK_CONF_DIR}/" if ! (cp ${SCRIPT_DIR}/workers.properties ${MOD_JK_CONF_DIR}/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/workers.properties to ${MOD_JK_CONF_DIR}/" fi log "Copying qos to ${APACHE_CONF_DIR}/mods-available/" if ! (cp ${SCRIPT_DIR}/qos.conf ${APACHE_CONF_DIR}/conf-available/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/qos.conf to ${APACHE_CONF_DIR}/conf-available/" fi log "Copying mod_qos_500_error.xml to ${APACHE_CONF_DIR}/mods-available/" if ! (cp ${SCRIPT_DIR}/mod_qos_500_error.xml ${APACHE_WWW_DIR}/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/mod_qos_500_error.xml to ${APACHE_WWW_DIR}/" fi ## disable and then re-enable mod_proxy, mod_rewrite, and mod_headers log "Refreshing Proxy" if ! (a2dismod proxy_ajp >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable proxy_ajp apache module" fi if ! (a2dismod proxy_http >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable proxy_http apache module" fi if ! (a2dismod proxy >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable proxy apache module" fi if ! (a2enmod proxy >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable proxy apache module" fi if ! (a2enmod proxy_http >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable proxy_http apache module" fi if ! (a2enmod proxy_ajp >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to ensable proxy_ajp apache module" fi log "Refreshing Rewrite" if ! (a2dismod rewrite >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable rewrite apache module" fi if ! (a2enmod rewrite >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to ensable rewrite apache module" fi log "Refreshing Headers" if ! (a2dismod headers >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable headers apache module" fi if ! (a2enmod headers >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to ensable headers apache module" fi log "Refreshing Cache module" if ! (a2dismod disk_cache >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable apache disk_cache module" fi if ! (a2enmod disk_cache >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable apache disk_cache module" fi # Turn on the ssl module log "Refreshing Mod SSL" if ! (a2dismod ssl >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable ssl site" fi if ! (a2enmod ssl >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable ssl site" fi ## disable and then re-enable mod qos to pick up changes log "Refreshing Mod QoS" if ! (a2dismod qos >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable mod qos" fi if ! (a2enmod qos >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable mod qos" fi ## disable and then re-enable mod jk to pick up changes log "Refreshing Mod JK" if ! (a2dismod jk >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable jk apache site" fi if ! (a2enmod jk >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable jk apache site" fi ## disable and then re-enable mod qos to pick up changes log "Refreshing Mod Expires" if ! (a2dismod expires >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable mod expires" fi if ! (a2enmod expires >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable mod expires" fi ## disable the default apache site, which gets in the way of the other sites if ! (a2dissite 000-default >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable 000-default apache site" fi ## mod_qos needs to be modified to add in exclusions for all the CNs # in this environment local MOD_QOS_CN_EXCLUSIONS="\n" if [[ "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.iplist]}" == [1-9]* ]]; then for IP in ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.iplist]} do MOD_QOS_CN_EXCLUSIONS+="\tQS_SrvMaxConnExcludeIP\t${IP}\n" done if ! (sed -i 's/CN_QS_SRVMAXCONNEXCLUDEIP/'${MOD_QOS_CN_EXCLUSIONS}'/' ${APACHE_CONF_DIR}/conf-available/qos.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to configure apache mod_qos to exclude CNs" fi fi ## copy in site configuration files for SITE in ${SITES} do if [ -e "${APACHE_CONF_DIR}/sites-available/${SITE}.conf" ]; then ## if there is a difference, then the diff script returns false if ! (diff ${SCRIPT_DIR}/${SITE}.conf ${APACHE_CONF_DIR}/sites-available/${SITE}.conf); then log "Backing up ${APACHE_CONF_DIR}/sites-available/${SITE}.conf to ${APACHE_CONF_DIR}/sites-available/${SITE}.conf.${LONG_DATE}" if ! (mv ${APACHE_CONF_DIR}/sites-available/${SITE}.conf ${APACHE_CONF_DIR}/sites-available/${SITE}.conf.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to move ${APACHE_CONF_DIR}/sites-available/${SITE}.conf ${APACHE_CONF_DIR}/sites-available/${SITE}.conf.${LONG_DATE}" fi fi fi log "Copying ${SITE}.conf site file to ${APACHE_CONF_DIR}/sites-available/" if ! (cp ${SCRIPT_DIR}/${SITE}.conf ${APACHE_CONF_DIR}/sites-available/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/${SITE}.conf ${APACHE_CONF_DIR}/sites-available/" continue fi ## replace the token SERVER_NAME in the site file if [ -n ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.router.hostname]} ]; then if ! (sed -i.bak 's/SERVER_NAME/'${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.router.hostname]}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify SERVER_NAME in ${SITE}.conf Apache" fi else log "dataone-cn-os-core/cn.router.hostname can not be set in ${APACHE_CONF_DIR}/sites-available/${SITE}.conf" fi ## replace the token SERVER_ALIAS in the site file if [ -n ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.hostname]} ]; then if ! (sed -i.bak 's/SERVER_ALIAS/'${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.hostname]}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify SERVER_ALIAS in ${SITE}.conf Apache" fi else log "dataone-cn-os-core/cn.hostname can not be set in ${APACHE_CONF_DIR}/sites-available/${SITE}.conf" fi ## replace the token SEARCH_SERVER_NAME in the site file if [ -n ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.search.hostname]} ]; then if ! (sed -i.bak 's/SEARCH_HOSTNAME/'${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.search.hostname]}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify SEARCH_NAME in ${SITE}.conf Apache" fi else log "dataone-cn-os-core/cn.router.hostname can not be set in ${APACHE_CONF_DIR}/sites-available/${SITE}.conf" fi ## Set the server side SSL CA bundle #local INTERMEDIATE_BUNDLE="${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.cachain.filename]}" #if ! (sed -i.bak 's/INTERMEDIATE_BUNDLE/'${INTERMEDIATE_BUNDLE}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then #log "Unable to modify INTERMEDIATE_BUNDLE in ${SITE}.conf Apache" #fi ## Set the client side SSL CA chain file if ! (sed -i.bak 's/D1_CHAIN_FILE/'${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.dataone.ca.filename]}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify D1_CHAIN_FILE in ${SITE}.conf Apache" fi ## Set the client side SSL certificate file if ! (sed -i.bak 's/CN_HOSTNAME/'${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.router.hostname]}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify PUBLIC_SERVER_CERT_FILE in ${SITE}.conf Apache" fi ## Set the client side SSL private key file if ! (sed -i.bak 's/D1_PRIVATEKEY_FILE/'${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.server.privatekey.filename]}'/' ${APACHE_CONF_DIR}/sites-available/${SITE}.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify D1_PRIVATEKEY_FILE in ${SITE}.conf Apache" fi ## enable ${SITE} site log "Enabling ${SITE} site" if ! (a2dissite ${SITE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to disable ${SITE} Apache!" fi if ! (a2ensite ${SITE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to enable ${SITE} Apache!" fi done ## Start Apache if ! (/etc/init.d/apache2 start >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to Start Apache!" exitWithFailureCode 69 fi } ##### ##### configure_tomcat() ##### modify tomcate configuration files to allow for dataone operations ##### function configure_tomcat() { # findout if tomcat is running if (/etc/init.d/${TOMCAT} status >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then ## Stop tomcat log "Stopping Tomcat" if ! (/etc/init.d/${TOMCAT} stop >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to Stop Tomcat!" exitWithFailureCode 70 fi fi ## determine if the tomcat init script has a sufficient heap size ## XXX XXX XXX -RPW THE MAX/INITIAL HEAP PER ENVIRONMENT SHOULD BE CONFIGURED IN THE XML FILE #if [ -e "/etc/init.d/tomcat8" ]; then ## XXX XXX XXX -RPW ## we should determine if any changes have been made to /etc/init.d/tomcat8 and make a backup copy ## before proceeding with its modification ## The modification of JAVA_OPTS should move to the /etc/default/tomcat8 #if ! (egrep -q 'JAVA_OPTS\=.+\-Xmx' /etc/init.d/tomcat8); then #log "THERE WAS AN ERROR /etc/init.d/tomcat NO LONGER HAS -Xmx DEFINED" ## -Xmx is not set, that is bad, the tomcat installation must ## have change significantly. We must manually add it to the JAVA_OPTS LINE ## and then change this script to handle the exact line to add it to #else #if ! (egrep -q 'JAVA_OPTS\=.+\-XX\:MaxPermSize' /etc/init.d/tomcat8); then ## THE MAIN PROBLEM WITH THIS APPROACH CURRENTLY IS SUPPORTING THE DIFFERENT ENVIRONEMENTS ## developer VMs will not be able to support this amount of heap space ## in fact our development environment probably cannot #if ! (sed -i.bak --regexp-extended '0,/(^JAVA_OPTS\=)"([^"]*)"/s//\1"\2 -Xmx8192M -Xms1024M -XX:MaxPermSize=512M"/;' /etc/init.d/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then #log "Unable to modify heap space settings in /etc/init.d/tomcat8" #fi #if ! (rm /etc/default/tomcat8.bak >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then #log "Unable to remove /etc/default/tomcat8.bak" #fi #fi #fi #if ! (egrep -q 'ulimit.+\-Hn' /etc/init.d/tomcat8); then # if ! (sed -i.bak --regexp-extended 's/^(\#\!\/bin\/sh.*$)/\1\n ulimit -Hn 16384\n ulimit -Sn 16384\n/;' /etc/init.d/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to modify ulimit in /etc/init.d/tomcat8" # fi # if ! (rm /etc/init.d/tomcat8.bak >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to remove /etc/init.d/tomcat8.bak" # fi #fi #fi if [ -e "/etc/default/tomcat8" ]; then if ! (egrep -q '^\#?JAVA_OPTS\=".+\-XX\:\+UseConcMarkSweepGC"' /etc/default/tomcat8); then if ! (egrep -q 'JAVA_OPTS\=.+\-XX\:\+UseParallelGC' /etc/default/tomcat8); then echo "JAVA_OPTS=\"\${JAVA_OPTS} -XX:+UseParallelGC\"" >> /etc/default/tomcat8 fi else if ! (egrep -q 'JAVA_OPTS\=.+\-XX\:\+UseParallelGC' /etc/default/tomcat8); then ## XXX XXX XXX -RPW ## What happens if UseConcMarkSweepGC is not a part of JAVA_OPTS, but we still want to include ## UseParallelGC as our main garbage collection method if ! (sed -i.bak --regexp-extended s/UseConcMarkSweepGC/UseParallelGC/ /etc/default/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify UseConcMarkSweepGC in /etc/default/tomcat8" fi if ! (rm /etc/default/tomcat8.bak >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to remove /etc/default/tomcat8.bak" fi fi fi if ! (egrep -q 'JAVA_OPTS\=.+\-XX\:MaxPermSize' /etc/default/tomcat8); then ## THE MAIN PROBLEM WITH THIS APPROACH CURRENTLY IS SUPPORTING THE DIFFERENT ENVIRONEMENTS ## developer VMs will not be able to support this amount of heap space ## in fact our development environment probably cannot log "Can't find the memory setting on /etc/default/tomcat8, then set them." if ! (sed -i.bak --regexp-extended '0,/(^JAVA_OPTS\=)"([^"]*)"/s//\1"\2 -Xmx8192M -Xms1024M -XX:MaxPermSize=512M"/;' /etc/default/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify heap space settings in /etc/default/tomcat8" fi fi fi ## copy in jk.conf file if [ -e "${TOMCAT_HOME}/conf/server.xml" ]; then ## if there is a difference, then the diff script returns false if ! (diff ${SCRIPT_DIR}/server.xml ${TOMCAT_HOME}/conf/server.xml); then log "Backing up ${TOMCAT_HOME}/conf/server.xml to ${TOMCAT_HOME}/conf/server.xml.${LONG_DATE}" if ! (mv ${TOMCAT_HOME}/conf/server.xml ${TOMCAT_HOME}/conf/server.xml.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to move ${TOMCAT_HOME}/conf/server.xml to ${TOMCAT_HOME}/conf/server.xml.${LONG_DATE}" fi fi fi log "Copying server.xml to ${TOMCAT_HOME}/conf/" if ! (cp ${SCRIPT_DIR}/server.xml ${TOMCAT_HOME}/conf/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/server.xml ${TOMCAT_HOME}/conf/" fi ## add slash-handling properties to catalina.properties file ## (tomcat doesn't support include, so need to add it to the main file) if [ -e "${TOMCAT_HOME}/conf/catalina.properties" ]; then if ! (grep -q 'ALLOW_ENCODED_SLASH' ${TOMCAT_HOME}/conf/catalina.properties); then if ! (cp ${TOMCAT_HOME}/conf/catalina.properties ${TOMCAT_HOME}/conf/catalina.properties.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${TOMCAT_HOME}/conf/catalina.properties to ${TOMCAT_HOME}/conf/catalina.properties.${LONG_DATE} " fi log Appending slash-handling Java system properties to ${TOMCAT_HOME}/conf/catalina.properties echo >> ${TOMCAT_HOME}/conf/catalina.properties echo \# Dataone configuration for handling encoded slash and backslashes >> ${TOMCAT_HOME}/conf/catalina.properties echo org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true >> ${TOMCAT_HOME}/conf/catalina.properties echo org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true >> ${TOMCAT_HOME}/conf/catalina.properties fi fi if ! (chown -R ${TOMCAT_USER}:${TOMCAT_USER} /etc/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown on /etc/tomcat8" fi if ! (chown -R ${TOMCAT_USER}:${TOMCAT_USER} /var/lib/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown on /var/lib/tomcat8" fi if ! (chown -R ${TOMCAT_USER}:${TOMCAT_USER} /var/log/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown on /var/log/tomcat8" fi if ! (chown -R ${TOMCAT_USER}:${TOMCAT_USER} /var/cache/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown on /var/cache/tomcat8" fi if ! (chown -R ${TOMCAT_USER}:${TOMCAT_USER} /usr/share/tomcat8 >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown on /usr/share/tomcat8" fi } ##### ##### configure_openldap() ##### modify openldap configuration files to allow for dataone operations ##### populate the LDAP database for firsttime operations ##### the script will generate ldif configuration files based on ##### /etc/ldap/slapd.conf ##### function configure_openldap() { ############################################################################### # Configure OpenLDAP ############################################################################### ## Only populate LDAP on first run, otherwise migrate log "Configuring OpenLDAP" local ADDRESSES local DATAONE_CA_FILEPATH local LDAP_CERTIFICATE local LDAP_PRIVATEKEY local SYNC_SETTINGS local SYNC_CONF local MIGRATE_VERSION=0 local OPENLDAP_POPULATED local return_val db_get dataone-cn-os-core/cn.openldap.populated OPENLDAP_POPULATED=$RET if [ -n "$ARG_VERSION" ]; then MIGRATE_VERSION=$ARG_VERSION fi if [ -e "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.certificate.filename]}" ]; then LDAP_CERTIFICATE="${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.certificate.filename]}" LDAP_CERTIFICATE=${LDAP_CERTIFICATE//\//\\\/} else log "unable to locate ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.certificate.filename]}" exitWithFailureCode 94 fi if [ -e "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.privatekey.filename]}" ]; then LDAP_PRIVATEKEY="${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.privatekey.filename]}" LDAP_PRIVATEKEY=${LDAP_PRIVATEKEY//\//\\\/} else log "unable to locate ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.privatekey.filename]}" exitWithFailureCode 95 fi # # CN Service and D1-Processing needs the ldap password in a properties # file so that they may connect to ldap to retrieve information # the migrate perl scripts need the values in the properties file too in order to connect to ldap # if ! (cp ${SCRIPT_DIR}/ldapService.properties ${D1_CONF_DIR}/ldapService.properties >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to copy ${SCRIPT_DIR}/ldapService.properties to ${D1_CONF_DIR}/ldapService.properties" exitWithFailureCode 96 fi if ! (sed -i.bak "s/PASSWORD/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.password]}/" ${D1_CONF_DIR}/ldapService.properties >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to change the ldap admin password in ${D1_CONF_DIR}/ldapService.properties" exitWithFailureCode 97 fi if ! (chown ${TOMCAT_USER}:${TOMCAT_USER} ${D1_CONF_DIR}/ldapService.properties >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to chown on ${D1_CONF_DIR}/ldapService.properties" fi if ! (chmod -R 640 ${D1_CONF_DIR}/ldapService.properties >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to chmod on ${D1_CONF_DIR}/ldapService.properties" fi ### modify the migration scripts ### considering the perl scripts are not used now. comment out the ### use of the perl scripts. IF a need arises in the future ### to modify LDAP because of a migration issue, then the ### scripts will need to be revisited/refactored ### https://redmine.dataone.org/issues/6874 # if [ -n "$LDAP_CERTIFICATE" ]; then # if ! (sed -i.bak "s/^\(ldap_repl_pem\)/my \$\1=\"${LDAP_CERTIFICATE}\";/" ${SCRIPT_DIR}/ldap/migrateLdap.pl >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to modify ldap_repl_pem value in ${SCRIPT_DIR}/ldap/migrateLdap.pl " # fi # if ! (sed -i.bak "s/^\(ldap_repl_pem\)/my \$\1=\"${LDAP_CERTIFICATE}\";/" ${SCRIPT_DIR}/ldap/prepareMigrateLdap.pl >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to modify ldap_repl_pem value in ${SCRIPT_DIR}/ldap/prepareMigrateLdap.pl " # fi # fi # if [ -n "$LDAP_PRIVATEKEY" ]; then # if ! (sed -i.bak "s/^\(ldap_repl_key\)/my \$\1=\"${LDAP_PRIVATEKEY}\";/" ${SCRIPT_DIR}/ldap/migrateLdap.pl >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to modify ldap_repl_key value in ${SCRIPT_DIR}/ldap/migrateLdap.pl " # exitWithFailureCode 98 # fi # if ! (sed -i.bak "s/^\(ldap_repl_key\)/my \$\1=\"${LDAP_PRIVATEKEY}\";/" ${SCRIPT_DIR}/ldap/prepareMigrateLdap.pl >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to modify ldap_repl_key value in ${SCRIPT_DIR}/ldap/prepareMigrateLdap.pl " # exitWithFailureCode 99 # fi # fi # # log "Preparing for Migrating all dataone schema specific entries" # if ! (${SCRIPT_DIR}/ldap/prepareMigrateLdap.pl --version $MIGRATE_VERSION>> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then # exitWithFailureCode 82 # fi # for 1.2.0 remove dependency on dataone.schema changes # if [ -e "${LDAP_CONF_DIR}/schema/dataone.schema" ]; then # if ! (diff ${SCRIPT_DIR}/ldap/dataone.schema ${LDAP_CONF_DIR}/schema/dataone.schema); then # log "Schema changing: Run the pre migration script" # if (pidof slapd >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Preparing for Migrating all dataone schema specific entries" # if ! (${SCRIPT_DIR}/ldap/prepareMigrateLdap.pl --version $MIGRATE_VERSION>> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then # exitWithFailureCode 82 # fi # else # log "No migration. Ldap Not running" # fi # # log "Backing up ${LDAP_CONF_DIR}/schema/dataone.schema to ${LDAP_CONF_DIR}/schema/dataone.schema.${LONG_DATE}" # if ! (mv ${LDAP_CONF_DIR}/schema/dataone.schema ${LDAP_CONF_DIR}/schema/dataone.schema.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Unable to move ${LDAP_CONF_DIR}/schema/dataone.schema to ${LDAP_CONF_DIR}/schema/dataone.schema.${LONG_DATE}" # fi # fi # fi ## place schema extension if [ -z "${OPENLDAP_POPULATED}" ] || [ "${OPENLDAP_POPULATED}" == "false" ]; then confirm_ldap_running return_val=$? if [ "$return_val" -ne "$SUCCESS" ] then log "Slapd is not running and cannot be restarted. Failure!" exitWithFailureCode 90 fi if ! (sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b 'cn={1}cosine,cn=schema,cn=config' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd cosine.ldif failed. Unable to continue" exitWithFailureCode 71 fi fi if ! (sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b 'cn={2}nis,cn=schema,cn=config' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd nis.ldif failed. Unable to continue" exitWithFailureCode 72 fi fi if ! (sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b 'cn={3}inetorgperson,cn=schema,cn=config' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd inetorgperson.ldif failed. Unable to continue" exitWithFailureCode 73 fi fi if ! (sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b 'cn=module{0},cn=config' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f ${SCRIPT_DIR}/ldap/backendDBConfig.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd backendDBConfig.ldif failed. Unable to continue" exitWithFailureCode 74 fi fi else log "LDAP database has already been populated." fi log "Copying dataone.schema to ${LDAP_CONF_DIR}/schema/" if ! (cp ${SCRIPT_DIR}/ldap/dataone.schema ${LDAP_CONF_DIR}/schema/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/ldap/dataone.schema to ${LDAP_CONF_DIR}/schema/" fi if ! (chown -R ${LDAP_USER}:${LDAP_USER} ${LDAP_CONF_DIR}/schema/dataone.schema >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown ${LDAP_CONF_DIR}/schema/dataone.schema" fi ## place slapd.conf template if [ -e ${LDAP_CONF_DIR}/slapd.conf ]; then ## if there is a difference, then the diff script returns false if ! (diff ${SCRIPT_DIR}/ldap/slapd.conf ${LDAP_CONF_DIR}/slapd.conf); then log "Backing up ${LDAP_CONF_DIR}/slapd.conf to ${LDAP_CONF_DIR}/slapd.conf.${LONG_DATE}" if ! (mv ${LDAP_CONF_DIR}/slapd.conf ${LDAP_CONF_DIR}/slapd.conf.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to move ${LDAP_CONF_DIR}/slapd.conf to ${LDAP_CONF_DIR}/slapd.conf.${LONG_DATE}" fi fi fi log "Copying slapd.conf to ${LDAP_CONF_DIR}/" if ! (cp ${SCRIPT_DIR}/ldap/slapd.conf ${LDAP_CONF_DIR}/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy ${SCRIPT_DIR}/ldap/slapd.conf to ${LDAP_CONF_DIR}" fi ## place ldap.conf template if [ -e ${LDAP_CONF_DIR}/ldap.conf ]; then if ! (diff ${SCRIPT_DIR}/ldap/ldap.conf ${LDAP_CONF_DIR}/ldap.conf); then log "Backing up ${LDAP_CONF_DIR}/ldap.conf to ${LDAP_CONF_DIR}/ldap.conf.${LONG_DATE}" if ! (mv ${LDAP_CONF_DIR}/ldap.conf ${LDAP_CONF_DIR}/ldap.conf.${LONG_DATE} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to Move ${LDAP_CONF_DIR}/ldap.conf to ${LDAP_CONF_DIR}/ldap.conf.${LONG_DATE}" fi fi fi log "Copying ldap.conf to ${LDAP_CONF_DIR}/" if ! (cp ${SCRIPT_DIR}/ldap/ldap.conf ${LDAP_CONF_DIR}/ >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to copy${SCRIPT_DIR}/ldap/ldap.conf to ${LDAP_CONF_DIR}" fi # Fetch the DataONE CA DATAONE_CA_FILEPATH="${SSL_CERT_DIR}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.dataone.ca.filename]}" DATAONE_CA_FILEPATH=${DATAONE_CA_FILEPATH//\//\\\/} ## Configure the ldap.conf file with correct value for the CA cert if [ -e ${LDAP_CONF_DIR}/ldap.conf ]; then if ! (sed -i.bak "s/^\(TLS_CACERT *\).*/\1 ${DATAONE_CA_FILEPATH}/" ${LDAP_CONF_DIR}/ldap.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify TLS_CACERT value in ${LDAP_CONF_DIR}/slapd.conf" fi fi ## Configure the slapd.conf file with correct values if [ -e ${LDAP_CONF_DIR}/slapd.conf ]; then # Fetch the ldap rootpw from the debconf database ## hash the given password when writing to the file LDAP_ROOT_PASSWORD=${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.password]} LDAP_ROOT_PASSWORD=`slappasswd -n -s ${LDAP_ROOT_PASSWORD}` log "using hashed password ${LDAP_ROOT_PASSWORD}" if ! (sed -i.bak "s/^\(rootpw *\).*/\1 ${LDAP_ROOT_PASSWORD}/" ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify rootpw value in ${LDAP_CONF_DIR}/slapd.conf" fi # configure the replicaiton certificate fullpath location if [ -n "$LDAP_CERTIFICATE" ]; then if ! (sed -i.bak "s/^\(TLSCertificateFile *\).*/\1 ${LDAP_CERTIFICATE}/" ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify TLSCACertificateFile value in ${LDAP_CONF_DIR}/slapd.conf" fi # make sure we have the correct ownership if ! (chown ${TOMCAT_USER}:ssl-cert "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.certificate.filename]}">> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown ${TOMCAT_USER}:ssl-cert on ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.certificate.filename]}" fi else log "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.certificate.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.certificate.filename]} does not exist. slapd, among other services, will fail" fi # configure the replication private key fullpath location if [ -n "$LDAP_PRIVATEKEY" ]; then if ! (sed -i.bak "s/^\(TLSCertificateKeyFile *\).*/\1 ${LDAP_PRIVATEKEY}/" ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify TLSCertificateKeyFile value in ${LDAP_CONF_DIR}/slapd.conf" fi # Set the DataONE CA if ! (sed -i.bak "s/^\(TLSCACertificateFile *\).*/\1 ${DATAONE_CA_FILEPATH}/" ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to modify TLSCACertificateFile value in ${LDAP_CONF_DIR}/slapd.conf" fi # make sure we have the correct ownership for the key if ! (chown ${TOMCAT_USER}:ssl-cert "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.privatekey.filename]}" >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to chown ${TOMCAT_USER}:ssl-cert on ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.privatekey.filename]}" fi else log "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.client.key.dir]}/${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.replication.privatekey.filename]} does not exist. slapd, among other services, will fail" fi # Allow us to use non-standard cert/key locations for slapd if ! (aa-complain /etc/apparmor.d/usr.sbin.slapd >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "apparmor failed. needs repair." fi # TODO: instead of disabling apparmor, add exceptions to the config # file located here: /etc/apparmor.d/usr.sbin.slapd # Set up sychronization across the listed servers #declare -i count count=0 SYNC_SETTINGS="\n"; # synchronization definitions and settings if [ "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.synchronized]}" == "true" ]; then db_get dataone-cn-os-core/cn.hostnamelist local ADDRESSES=${RET} db_get dataone-cn-os-core/cn.nodeids local NODEIDS=( ${RET} ) # node ids array for address in ${ADDRESSES}; do # only create a replica entry for servers others than this server CURRENTNODEID=${NODEIDS[$count]} log "Node id in the list is ${CURRENTNODEID}" if [ "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.nodeid]}" == "${CURRENTNODEID}" ]; then let count=${count}+1 continue else let count=${count}+1 log "Adding LDAP sync config for ${address}" SYNC_SETTINGS="${SYNC_SETTINGS}\nsyncRepl rid=${count}" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tprovider=ldap:\/\/${address}:389" SYNC_SETTINGS="${SYNC_SETTINGS}\n\turi=ldap:\/\/${address}:389" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tbinddn=\"cn=admin,dc=dataone,dc=org\"" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tbindmethod=simple" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tcredentials=${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.password]}" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tsearchbase=\"dc=org\"" SYNC_SETTINGS="${SYNC_SETTINGS}\n\ttype=refreshAndPersist" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tstarttls=yes" SYNC_SETTINGS="${SYNC_SETTINGS}\n\ttls_cert=${LDAP_CERTIFICATE}" SYNC_SETTINGS="${SYNC_SETTINGS}\n\ttls_key=${LDAP_PRIVATEKEY}" SYNC_SETTINGS="${SYNC_SETTINGS}\n\ttls_cacert=${DATAONE_CA_FILEPATH}" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tinterval=00:00:00:05" SYNC_SETTINGS="${SYNC_SETTINGS}\n\tretry=\"12 5 300 +\"" SYNC_SETTINGS="${SYNC_SETTINGS}\n\ttimeout=1" fi done SYNC_SETTINGS="${SYNC_SETTINGS}\n\nmirrormode on" SYNC_SETTINGS="${SYNC_SETTINGS}\noverlay syncprov" SYNC_SETTINGS="${SYNC_SETTINGS}\nsyncprov-checkpoint 50 5" SYNC_SETTINGS="${SYNC_SETTINGS}\nsyncprov-sessionlog 100\n" # Fetch the ldap serverID from the debconf database db_get dataone-cn-os-core/cn.openldap.serverID SYNC_CONF="${RET}${SYNC_SETTINGS}" log ${SYNC_CONF} if ! (sed -i.bak "s/^\(serverID *\).*/\1${SYNC_CONF}/" ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to write replication settings in ${LDAP_CONF_DIR}/slapd.conf" fi else # Fetch the ldap serverID from the debconf database db_get dataone-cn-os-core/cn.openldap.serverID log "No LDAP replication selected. Setting serverID only." if ! (sed -i.bak "s/^\(serverID *\).*/\1 ${RET}/" ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to change the ServerId in ${LDAP_CONF_DIR}/slapd.conf" fi fi else log "Couldn't set LDAP configuration correctly. Configure ${LDAP_CONF_DIR}/slapd.conf manually." fi ## set permissions if ! (chown -R ${LDAP_USER}:${LDAP_USER} ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to chown on ${LDAP_CONF_DIR}/slapd.conf" fi if ! (chown -R ${LDAP_USER}:${LDAP_USER} ${LDAP_CONF_DIR}/ldap.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to chown on ${LDAP_CONF_DIR}/ldap.conf" fi if ! (chmod 0600 ${LDAP_CONF_DIR}/slapd.conf >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to chmod on ${LDAP_CONF_DIR}/slapd.conf" fi # add to ssl-cert group so it can read private keys if ! (adduser ${LDAP_USER} ssl-cert >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to add ${LDAP_USER} to group ssl-cert." fi # try to add the dc=org before going through the rest of the routine # the worst that could happen is a denied message ## stop the default service log "Stopping slapd" if (pidof slapd >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then if ! (/etc/init.d/slapd stop >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to stop slapd. Trying SIGARLM" if ! (kill -s ALRM `cat /var/run/slapd/slapd.pid` >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Killing slapd with SIGALRM failed" exitWithFailureCode 78 else if (pidof slapd >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to stop slapd." exitWithFailureCode 78 fi fi fi else log "Slapd not running" fi ## start, using slapd.conf file log "Generating ldif config using: ${LDAP_CONF_DIR}/slapd.conf" if [ -e ${LDAP_CONF_DIR}/slapd.d ]; then if ! (rm -rf ${LDAP_CONF_DIR}/slapd.d/* >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "unable to remove files from ${LDAP_CONF_DIR}/slapd.d" fi fi if ! (slaptest -f ${LDAP_CONF_DIR}/slapd.conf -F ${LDAP_CONF_DIR}/slapd.d >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Unable to process slapd.conf into the ${LDAP_CONF_DIR}/slapd.d. LDAP will not be functional." exitWithFailureCode 79 fi #if [ -e "${LDAP_CONF_DIR}/slapd.d/cn=config/olcDatabase={1}hdb.ldif" ]; then ## NOTE: I see this being broken across a linebreak now with version 2.4.21 (BRL 20120731) ## http://www.openldap.org/its/index.cgi/Software%20Bugs?id=6465 ## (if i read the bug report correctly it is fixed starting at 2.4.24) ## the string uri="" finds its way into olcDatabase={1}hdb.ldif file ## into the olcSyncrepl directive and breaks OpenLDAP ## the string uri="" may be found at the beginning of a line, end of a line, ## middle of the line, or breaking across lines. ## if it breaks across lines, we need to preserve the newline, ## and ensure the line afterwards starts with a space. ## otherwise remove the string, guaranteeing only a single space separates ## previous setting string to the next setting string #if ! (/usr/bin/perl -pi.bak -e 'BEGIN{undef $/;} s/\hu(\s*)r(\s*)i(\s*)\=(\s*)\"(\s*)\"(\n?)/$1$2$3$4$5$6/mg' ${LDAP_CONF_DIR}/slapd.d/cn=config/olcDatabase={1}hdb.ldif 2>&1 ); then #log "perl correction of ${LDAP_CONF_DIR}/slapd.d/cn=config/olcDatabase={1}hdb.ldif failed" #fi #if ! (rm ${LDAP_CONF_DIR}/slapd.d/cn=config/olcDatabase={1}hdb.ldif.bak >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then #log "unable to remove ${LDAP_CONF_DIR}/slapd.d/cn=config/olcDatabase={1}hdb.ldif.bak" #fi #else #log "unable to find ${LDAP_CONF_DIR}/slapd.d/cn=config/olcDatabase={1}hdb.ldif" #exitWithFailureCode 84 #fi if [ -e /etc/ldap/slapd.d ]; then if ! (chown -R ${LDAP_USER}:${LDAP_USER} /etc/ldap/slapd.d >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then log "chown on /etc/ldap/slapd.d failed" exitWithFailureCode 80 fi else log "/etc/ldap/slapd.d does not exist. Something has gone horribly wrong" exitWithFailureCode 80 fi ## make sure we own the storage folder if [ -e /var/lib/ldap ]; then if ! (chown -R ${LDAP_USER}:${LDAP_USER} /var/lib/ldap >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then log "chown on /var/lib/ldap failed" fi else log "/var/lib/ldap does not exist. Something has gone horribly wrong" exitWithFailureCode 81 fi log "Starting slapd" LDAP_RUNNING="yes" if ! (/etc/init.d/slapd start >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then log "Slapd failed to start" exitWithFailureCode 91 fi sleep 5 # openldap doesn't seem to come up quickly enough confirm_ldap_running return_val=$? if [ "$return_val" -ne "$SUCCESS" ] then log "Slapd is not running and cannot be restarted. Failure!" exitWithFailureCode 92 fi # populate or migrate the LDAP database with the LDIF file for the chosen context if [ -z "${OPENLDAP_POPULATED}" ] || [ "${OPENLDAP_POPULATED}" == "false" ]; then log "This is the first CN to be installed in the environment" log "Adding dataone schema specific entries" # find out if org.ldif has been added if ! (ldapsearch -Y EXTERNAL -H ldapi:/// -b 'dc=org' -s base + 2> /dev/null | grep -q -P '^dn:\sdc=org$' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f ${SCRIPT_DIR}/ldap/org.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd org.ldif failed. Unable to continue" exitWithFailureCode 75 fi fi if [ "${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.firstcn]}" == "true" ]; then if ! (sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b 'dc=org' -s one 2> /dev/null | grep -q -P '^dn:\sdc=dataone,dc=org$' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f ${SCRIPT_DIR}/ldap/dataone.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd dataone.ldif failed. Unable to continue" exitWithFailureCode 76 fi fi if ! (sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b 'dc=org' -s one 2> /dev/null | grep -q -P '^dn:\sdc=cilogon,dc=org$' >/dev/null 2>&1 ); then if ! (sudo ldapadd -Y EXTERNAL -H ldapi:/// -f ${SCRIPT_DIR}/ldap/cilogon.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "ldapadd cilogon.ldif failed. Unable to continue" exitWithFailureCode 77 fi fi if [[ -e "${SCRIPT_DIR}/ldap/${CONTEXT,,}NodeList.ldif" && -n $LDAP_RUNNING ]]; then log "Adding all dataone schema specific entries" if ! (ldapadd -v -c -D cn=admin,dc=dataone,dc=org -w ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.password]} -H ldap://localhost:389 -x -f ${SCRIPT_DIR}/ldap/${CONTEXT,,}NodeList.ldif >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then log "ldapadd of ${SCRIPT_DIR}/ldap/${CONTEXT,,}NodeList.ldif failed" fi else log "${SCRIPT_DIR}/ldap/${CONTEXT,,}NodeList.ldif does not exist or ldap not running- unable to populate ldap for environment ${CONTEXT}" fi else log "Not the first CN in the environment. Skipping LDAP population." fi db_set dataone-cn-os-core/cn.openldap.populated true db_fset dataone-cn-os-core/cn.openldap.populated seen true ### considering the perl scripts are not used now. comment out the ### use of the perl scripts. IF a need arises in the future ### to modify LDAP because of a migration issue, then the ### scripts will need to be revisited/refactored ### https://redmine.dataone.org/issues/6874 # else # if [ -n "$LDAP_RUNNING" ]; then # log "Migrating all dataone schema specific entries" # if ! (${SCRIPT_DIR}/ldap/migrateLdap.pl --version $MIGRATE_VERSION>> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then # exitWithFailureCode 82 # fi # else # log "No migration. Ldap Not running" # fi fi ## list the entries if [ -n "$LDAP_RUNNING" ]; then log "Listing LDAP Coordinating Node entries for: dc=dataone,dc=org" if ! (ldapsearch -LLL -D cn=admin,dc=dataone,dc=org -w ${DEB_QUESTION_VALUES[dataone-cn-os-core/cn.openldap.password]} -H ldap://localhost:389 -x -b 'dc=dataone,dc=org' 'd1NodeType=cn' >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1 ); then log "ldapsearch for dc=dataone,dc=org failed" fi fi # Always clear the cached keystore password db_set dataone-cn-os-core/cn.openldap.password "" # clear the cached pw db_fset dataone-cn-os-core/cn.openldap.password seen false eval local -a DEB_FLAG_BOOLEAN=("${DEB_QUESTION_FLAGS[dataone-cn-os-core/cn.openldap.password]}") DEB_FLAG_BOOLEAN[$SEEN]="false" unset -v DEB_QUESTION_FLAGS[dataone-cn-os-core/cn.openldap.password] DEB_QUESTION_FLAGS+=([dataone-cn-os-core/cn.openldap.password]="${DEB_FLAG_BOOLEAN[@]}") ## done with OpenLDAP log "LDAP configuration complete" sleep 5 } ##### ##### configure_bouncycastle() ##### install the bouncycastle jars into the java security ext directory ##### and modify the java security properties file to allow bouncycastle ##### to handle auth ##### function configure_bouncycastle() { ############################################################################### # Configure BouncyCastle for Java Security (before starting tomcat) ############################################################################### ## XXX XXX XXX -RPW Do we still need bouncy castle as a jce provider for our installation to work? ## 2015-03-18 BRL: remove bouncycastle jars on install and require individual projects to manage that dependency if ! (grep -q -P '=org\.bouncycastle\.jce\.provider\.BouncyCastleProvider' ${JAVA_SECURITY}); then echo "bouncycastle security provider NOT previously installed" else echo "bouncycastle security provider previously installed" ## TODO: remove BC provider entry from java.security? fi if [ -e ${JAVA_SECURITY_EXT_DIR}/bcprov-*.jar ]; then echo "we need to remove the bcprov-*.jar file" if ! (rm ${JAVA_SECURITY_EXT_DIR}/bcprov-*.jar >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Removing ${JAVA_SECURITY_EXT_DIR}/bcprov-*.jar failed" fi #if ! (cp ${SOURCE_DIR}/bcprov-jdk15on-1.46.jar ${JAVA_SECURITY_EXT_DIR} >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then # log "Copy of ${SOURCE_DIR}/bcprov-jdk15on-1.46.jar to ${JAVA_SECURITY_EXT_DIR} failed" #fi fi if [ -e ${JAVA_SECURITY_EXT_DIR}/bcmail-*.jar ]; then echo "we need to remove the bcmail-*.jar file" if ! (rm ${JAVA_SECURITY_EXT_DIR}/bcmail-*.jar >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Removing ${JAVA_SECURITY_EXT_DIR}/bcmail-*.jar failed" fi fi } ##### ##### configure_check_mk() ##### make certain check_mk exists and has correct permissions ##### function configure_check_mk() { ############################################################################### # Configure check_mk ############################################################################### if [ -e /usr/lib/check_mk_agent ]; then if ! (chown -R root:root /usr/lib/check_mk_agent >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "failed to chown -R root:root /usr/lib/check_mk_agent" fi if ! (chmod -R 755 /usr/lib/check_mk_agent >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "failed to chmod -R 755 /usr/lib/check_mk_agent" fi else log "check_mk_agent is missing. Something has gone horribly wrong" exitWithFailureCode 83 fi ###################################### } ##### ##### debug_xml_template_flags() ##### log a bunch of settings from the XML_TEMPLATE_FLAGS datastructure ##### function debug_xml_template_flags() { local template_name log "XML_TEMPLATE_FLAGS\t SEEN \t DERIVED_VALUE \t CONFIGURED_VALUE \t USER_ENTERED_VALUE" for template_name in ${!XML_TEMPLATE_FLAGS[@]} do eval declare -a XML_TEMPLATE_BOOLEAN=("${XML_TEMPLATE_FLAGS[$template_name]}") log "$template_name\t${XML_TEMPLATE_BOOLEAN[$SEEN]}\t${XML_TEMPLATE_BOOLEAN[$DERIVED_VALUE]}\t${XML_TEMPLATE_BOOLEAN[$CONFIGURED_VALUE]}\t${XML_TEMPLATE_BOOLEAN[$USER_ENTERED_VALUE]}" done } ##### ##### debug_xml_question_values() ##### log a bunch of settings from the XML_QUESTION_VALUES datastructure ##### function debug_xml_question_values() { local template_name log "XML_QUESTIONS \t VALUES" for template_name in ${!XML_QUESTION_VALUES[@]} do if ! [[ $template_name =~ ^.*password.*$ ]]; then log "$template_name \t ${XML_QUESTION_VALUES[$template_name]}" fi done } ##### ##### debug_deb_question_flags() ##### log a bunch of settings from the DEB_QUESTION_FLAGS datastructure ##### function debug_deb_question_flags() { log "DEB_QUESTION_FLAGS\t SEEN \t DERIVED_VALUE \t CONFIGURED_VALUE \t USER_ENTERED_VALUE" for template_name in ${!DEB_QUESTION_FLAGS[@]} do eval declare -a DEB_QUESTION_BOOLEAN=("${DEB_QUESTION_FLAGS[$template_name]}") log "$template_name\t${DEB_QUESTION_BOOLEAN[$SEEN]}\t${DEB_QUESTION_BOOLEAN[$DERIVED_VALUE]}\t${DEB_QUESTION_BOOLEAN[$CONFIGURED_VALUE]}\t${DEB_QUESTION_BOOLEAN[$USER_ENTERED_VALUE]}" done } ##### ##### debug_deb_question_values() ##### log a bunch of settings from the DEB_QUESTION_VALUES datastructure ##### function debug_deb_question_values() { local template_name log "DEB_QUESTION \t VALUES" for template_name in ${!DEB_QUESTION_VALUES[@]} do if ! [[ $template_name =~ ^.*password.*$ ]]; then log "$template_name \t ${DEB_QUESTION_VALUES[$template_name]}" fi done } ##### ##### main() ##### simulate a main function ##### function main() { log "dataone-cn-os-core.postinst called with action: ${ACTION} and version: ${ARG_VERSION}" case "${ACTION}" in abort-remove) log "Removal aborted." ;; abort-upgrade) log "Upgrade aborted." ;; abort-deconfigure) log "Deconfigure aborted." ;; configure) log "Configure called." if [ -z "$ARG_VERSION" ]; then FIRSTINST="yes" else UPGRADE="yes" fi download_validate_config_xml build_xml_template_data_structures build_debianDB_template_data_structures debug_xml_question_values debug_xml_template_flags if [ -n "$DEBCONF_RECONFIGURE" ]; then log "MUST RECONFIGURE!!!" RECONFIGURE="yes" fi if (/usr/bin/dpkg --compare-versions "${ARG_VERSION}" lt 1.2.1); then RECONFIGURE="yes" fi if [[ "$FIRSTINST" == "yes" || "$RECONFIGURE" == "yes" ]]; then ################################################################## # Set the context of the deployment (LOCALHOST, DEV, STAGE, SANDBOX, PRODUCTION) ################################################################## # Fetch the cn.context.label from the debconf database and set the per-environment variables log "First Installation" process_create_debian_config debug_deb_question_values debug_deb_question_flags configure_certificates configure_node_properties_file configure_ufw configure_jdk configure_keystore configure_apache configure_tomcat configure_openldap configure_bouncycastle log "ETC configuration" ############################################################################### # Start Tomcat ############################################################################### log "starting Tomcat server" if ! (/etc/init.d/${TOMCAT} start >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "Tomcat server failed to start" fi if ! (cp ${SOURCE_DIR}/d1_cn_approve_node.jar /usr/share/java >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "failed to copy ${SOURCE_DIR}/d1_cn_approve_node.jar to /usr/share/java" fi chmod 700 /usr/share/java/d1_cn_approve_node.jar chmod 700 /usr/local/bin/dataone-approve-node log "Configuration of dataone-cn-os-core complete." else ## does not appear that update will have to touch tomcat # if tomcat is re-installed and the configuration files # deleted, or otherwise corrupted, then # this package will need to be reconfigured log "Update the configuration." process_update_debian_config debug_deb_question_values debug_deb_question_flags # if any of the following template questions change # then reconfigure the certificates # dataone-cn-os-core/cn.client.key.dir # dataone-cn-os-core/cn.client.certificate.filename # dataone-cn-os-core/cn.server.privatekey.filename # dataone-cn-os-core/cn.server.publiccert.filename # dataone-cn-os-core/cn.client.certificate.dir if [[ "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.client.key.dir]}" == "true" || "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.client.certificate.filename]}" == "true" || "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.server.privatekey.filename]}" == "true" || "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.server.publiccert.filename]}" == "true" || "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.client.certificate.dir]}" == "true" ]];then configure_certificates fi # if any of the following template questions change # then reconfigure the node properties file # dataone-cn-os-core/cn.context.label # dataone-cn-os-core/cn.iplist # dataone-cn-os-core/cn.nodeids # dataone-cn-os-core/cn.nodeid # dataone-cn-os-core/cn.router.nodeId # dataone-cn-os-core/cn.router.hostname # dataone-cn-os-core/cn.client.certificate.filename # dataone-cn-os-core/cn.hostname # if [[ "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.context.label]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.iplist]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.nodeids]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.nodeid]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.router.nodeId]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.router.hostname]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.client.certificate.filename]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.hostname]}" == "true" ]];then # configure_node_properties_file # fi # the node properties file is always overwritten, so we have to configure it without conditions configure_node_properties_file # if the following template question changes # then reconfigure ufw # dataone-cn-os-core/cn.iplist configure_jdk if [[ "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.iplist]}" == "true" ]]; then configure_ufw fi # if the following template question changes # then reconfigure the keystore # dataone-cn-os-core/cn.dataone.ca.filename #if [[ "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.dataone.ca.filename]}" == "true" ]]; then configure_keystore #fi # if the following template questions change # then reconfigure apache # dataone-cn-os-core/cn.hostname # dataone-cn-os-core/cn.dataone.ca.filename # dataone-cn-os-core/cn.server.publiccert.filename # dataone-cn-os-core/cn.server.privatekey.filename # if [[ "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.hostname]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.dataone.ca.filename]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.server.publiccert.filename]}" == "true" || # "${DB_QUESTION_CHANGED[dataone-cn-os-core/cn.server.privatekey.filename]}" == "true" ]];then # configure_apache #fi # XXX reconfigure apache and tomcat until add in better logic to determine when static files have changed configure_apache configure_tomcat # due to the fact that we do not know if the password has been changed # we will always have to reconfigure openldap until # the logic surrounding passwords change configure_openldap #reconfigure the bouncycastle if it is ncessary. configure_bouncycastle fi ##### #### postinst needs to determine if ansible is controlling the install/upgrade #### need to communicate between ansible and debian about the state of the installation #### if ansible is run to upgrade, then the next time postinst runs #### the seen flag will be true, and we accept all of ansible's values #### however if seen is false, then we assume that debian is #### running alone and should determine how to update the #### template values #### then postinst will assume that ansible is not controlling the install #### always do this as the last method to call for either #### install/reconfigure or update resetDebQuestionSeenFlag ;; esac db_stop exit 0 } #### This is the start of all the processing!!! if (debconf-show dataone-cn-os-core >> ${D1_LOG_DIR}/${D1_LOG_FILE} 2>&1); then log "before main" fi main ################ NOTHING SHOULD APPEAR BELOW THIS LINE ################