#!/bin/ksh93
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r714 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_ldap_server.sh 1.4 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2011 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)32	1.4  src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_ldap_server.sh, hacmp.assist, 61haes_r714 8/6/13 16:54:52

#================================================
# The following, commented line enforces coding
# standards when this file is edited via vim.
#================================================
# vim:tabstop=4:shiftwidth=4:expandtab:smarttab
#================================================

# Start of POD-formatted documentation. Viewing suggestions:
#      perldoc <FILENAME>
#      pod2text -c <FILENAME>
#      pod2text -c --code <FILENAME>
#      pod2html <FILENAME>
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_add_ldap_server

=head1 VERSION

 Version Number:  1.4
 Last Extracted:  1/31/14 04:41:43
 Last Changed:    8/6/13 16:54:52

 Path, Component, Release(, Level):
 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_ldap_server.sh, hacmp.assist, 61haes_r714

=head1 SYNOPSIS

 # Configuring one or more LDAP servers for the cluster
 clmgr add ldap_server <server>[,<server#2>,...] \
             ADMIN_DN=<admin_distinguished_name> \
                 PASSWORD=<admin_password> \
             BASE_DN=<suffix_distinguished_name> \
             SSL_KEY=<full_path_to_key> \
                 SSL_PASSWORD=<SSL_key_password> \
             VERSION=<version> \
             DB2_INSTANCE_PASSWORD=<password> \
             ENCRYPTION_SEED=<seed> \
             [ SCHEMA=<schema_type> ] \
             [ PORT={636|###} ]

 # Adding one or more already-configured LDAP servers to the cluster
 clmgr add ldap_server <server>[,<server#2>,...] \
             ADMIN_DN=<admin_distinguished_name> \
                 PASSWORD=<admin_password> \
             BASE_DN=<suffix_distinguished_name> \
             SSL_KEY=<full_path_to_key> \
                 SSL_PASSWORD=<SSL_key_password> \
             [ PORT={636|###} ]

 NOTE: if more than one server is specified, they must be in a
       peer-to-peer configuration, sharing the same port number.

 NOTE: the alias for "ldap_server" is "ls".

=head1 DESCRIPTION

Attempts to configure one or more LDAP servers for the cluster to use
for federated security.

=head1 ARGUMENTS

 1. properties [REQUIRED] [hash ref]
    An associative array within which data about the
    created object can be returned to the caller.

 2. servers [REQUIRED] [string]
    The hostname of the LDAP servers to be used by the cluster.
    If a replica, referral, or proxy server is used, a comma
    separated list of the respective hostnames is required.

 3. admin_dn [REQUIRED] [string]
    The LDAP server administrator distinguished name (DN).

    Examples: cn=admin cn=administrator cn=user.

 4. password [REQUIRED] [string]
    The test-only password for the administrator distinguished name (DN).

 5. base_dn [REQUIRED] [string]
    The base distinguished name for the LDAP servers.
    The suffix, or base, distinguished name (DN) to search on the
    LDAP server for users, groups, and other network information
    entities. Examples: cn=aixdata o=ibm.

 6. ssl_key [REQUIRED] [string]
    The full path to an SSL key, to be used for communications.

 7. ssl_password [REQUIRED] [string]
    The password associated with the specified SSL key.
    If a password is not specified, it is assumed that a password stash
    file exists with the same file specification as the SSL key path,
    but with an extension of ".sth".

 8. port [OPTIONAL] [string]
    The port number to connect to on the LDAP server(s). Defaults to 636.

 9. schema [OPTIONAL] [string]
    The LDAP schema used to represent user/group entries in the
    LDAP server.

    rfc2307aix - Sets up the LDAP server using RFC 2307 and auxiliary
                 AIX schema. It is recommended that you use this schema
                 because of its interoperability through RFC 2307 and
                 full AIX attribute support. This is the default value
                 and not editable.

 10. version [OPTIONAL] [string]
    The version of the LDAP servers. Must be at least 6.2.0.0.

 11. db2_pswd [REQUIRED] [string]
    The password for the DB2 instance, which is always same as
    the TDS instance ("ldapdb2" by default).

 12. enc_seed [REQUIRED] [string]
    Alphanumeric and length should be minimum 12 characters.

=head1 RETURN

 0: no errors were detected; the operation appears to have been successful
 1: a general error has occurred
 2: a specified resource does not exist, or could not be found
 3: some required input was missing
 4: some detected input was incorrect in some way
 5: a required dependency does not exist
 6: a specified search failed to match any data

=head1 COPYRIGHT

COPYRIGHT International Business Machines Corp. 2005,2010
All Rights Reserved

=cut
} # End of POD-formatted documentation.


function KLIB_HACMP_add_ldap_server {
    LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL"
    : version=1.4, src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_ldap_server.sh, hacmp.assist, 61haes_r714
    : INPUTS: $*

    typeset -n properties=$1
    typeset servers=${2//\"/}
    typeset admin_dn=${3//\"/}
    typeset password=${4//\"/}
    typeset base_dn=${5//\"/}
    typeset ssl_key=${6//\"/}
    typeset ssl_password=${7//\"/}
    typeset port=${8//\"/}
    typeset schema=${9//\"/}
    typeset version=${10//\"/}
    typeset db2_pswd=${11//\"/}
    typeset enc_seed=${12//\"/}

    [[ $CLMGR_LOGGING == 'med' ]] && set +x  # Only trace param values

    #===================================
    : Declare and initialize variables
    #===================================
    typeset -i rc=$RC_UNKNOWN

    #=================
    : Validate input
    #=================
    if [[ -z $servers ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2
        rc=$RC_MISSING_INPUT

    elif [[ " ${existing[*]} " == *\ $servers\ * ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 "\nERROR: the specified object already exists: \"%1\$s\"\n\n" "$ldap_server" 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    #================================
    : Check for all required inputs
    #================================
    for PAIR in "ADMIN_DN|$admin_dn" \
                "PASSWORD|$password" \
                "BASE_DN|$base_dn"
    do
        typeset ATTR=${PAIR%%\|*}
        typeset VALUE=${PAIR##*\|}

        if [[ $VALUE == *([[:space:]]) ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" "$ATTR" 1>&2
            rc=$RC_MISSING_INPUT
        fi
    done

    #==============================================================
    : If the VERSION attribute is specified, then the customer is
    : configuring a new LDAP server, not an existing one. That is
    : the only operation that requires the VERSION attribute.
    #==============================================================
    typeset -i newConfig=0
    if [[ -n $version ]]; then
        newConfig=1
    fi

    #====================================================================
    : If configuring an existing LDAP server, the SSL info is required.
    : For new LDAP server configurations, it is not, since the SSL key
    : is automatically generated.
    #====================================================================
    if (( ! newConfig )); then
        if [[ $ssl_key == *([[:space:]]) ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 '\nERROR: this operation requires the "%1$s" attribute.\n\n' SSL_KEY 1>&2
            rc=$RC_MISSING_INPUT

        elif [[ -n $ssl_key && $ssl_key != /* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 106 '\nERROR: the specified path does not appear to be in absolute format:\n%1$s\n\n' "$ssl_key" 1>&2
            rc=$RC_INCORRECT_INPUT

        elif [[ -n $ssl_key && ! -e $ssl_key ]]; then
            CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 107 '\nERROR: the specified path/file does not appear to exist on "%2$s": %1$s\n\n' "$ssl_key" "$LOCAL_NODE" 1>&2
            rc=$RC_NOT_FOUND
        fi

        if [[ $ssl_password == *([[:space:]]) ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 '\nERROR: this operation requires the "%1$s" attribute.\n\n' SSL_PASSWORD 1>&2
            rc=$RC_MISSING_INPUT
        fi
    fi

    if [[ -n $schema ]] && (( ! newConfig )); then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 "\nERROR: option \"%1\$s\" is required when any of the following option(s) are used: %2\$s\n\n" SCHEMA VERSION 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $db2_pswd ]] && (( ! newConfig )); then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 "\nERROR: option \"%1\$s\" is required when any of the following option(s) are used: %2\$s\n\n" DB2_INSTANCE_PASSWORD VERSION 1>&2
        rc=$RC_INCORRECT_INPUT
    elif [[ -z $db2_pswd ]] && (( newConfig )); then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" DB2_INSTANCE_PASSWORD 1>&2
        rc=$RC_MISSING_INPUT
    fi

    if [[ -n $enc_seed ]] && (( ! newConfig )); then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 37 "\nERROR: option \"%1\$s\" is required when any of the following option(s) are used: %2\$s\n\n" ENCRYPTION_SEED VERSION 1>&2
        rc=$RC_INCORRECT_INPUT
    elif [[ -z $enc_seed ]] && (( newConfig )); then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 "\nERROR: missing required argument:  %1\$s\n" ENCRYPTION_SEED 1>&2
        rc=$RC_MISSING_INPUT
    fi

    if [[ -n $enc_seed ]] && (( ${#enc_seed} < 12 )); then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 9999 '\nERROR: %1$s must be at least %2$d characters long.\n\n' ENCRYPTION_SEED 12 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    if [[ -n $port && $port != +([[:digit:]]) ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" PORT 1>&2
        rc=$RC_INCORRECT_INPUT
    fi

    #================================================================
    : Define the LDAP servers if no input errors have been detected
    #================================================================
    if (( $rc == RC_UNKNOWN )); then
        typeset port_opt= schema_opt= version_opt= key_opt= keypw_opt=
        [[ -n $port    ]] && port_opt="-p $port" || port_opt="-p 636"
        [[ -n $schema  ]] && schema_opt="-s $schema" || schema_opt="-s rfc2307aix"
        [[ -n $version ]] && version_opt="-V $version"
        [[ -n $ssl_key ]] && key_opt="-S $ssl_key"
        [[ -n $ssl_password ]] && keypw_opt="-W $ssl_password"

        if (( newConfig )); then
            print -- "$0()[$LINENO]($SECONDS): $HACSPOC/cl_ldap_server_config -h \"$servers\" -a \"$admin_dn\" -w \"$password\" -s rfc2307aix -d \"$base_dn\" -X \"$db2_pswd\" -E \"$enc_seed\" $key_opt $keypw_opt $port_opt $schema_opt $version_opt" >>$CLMGR_TMPLOG
            $HACSPOC/cl_ldap_server_config -h "$servers" \
                                           -a "$admin_dn" \
                                           -w "$password" \
                                           -d "$base_dn" \
                                           -X "$db2_pswd" \
                                           -E "$enc_seed" \
                                           $key_opt \
                                           $keypw_opt \
                                           $port_opt \
                                           $schema_opt \
                                           $version_opt
            rc=$?
            print "$0()[$LINENO]($SECONDS): cl_ldap_server_config RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
        else
            print -- "$0()[$LINENO]($SECONDS): $HACSPOC/cl_ldap_server_existing -h \"${servers//+([[:space:]])/,}\" -a \"$admin_dn\" -w \"$password\" -d \"$base_dn\" $key_opt $keypw_opt $port_opt" >>$CLMGR_TMPLOG
            $HACSPOC/cl_ldap_server_existing -h "${servers//+([[:space:]])/,}" \
                                             -a "$admin_dn" \
                                             -w "$password" \
                                             -d "$base_dn" \
                                             $key_opt \
                                             $keypw_opt \
                                             $port_opt
            rc=$?
            print "$0()[$LINENO]($SECONDS): cl_ldap_server_existing RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
        fi

        if (( $rc != RC_SUCCESS )); then
            rc=$RC_ERROR
        fi

        #===========================================================
        : If output from this operation was requested, retrieve it
        #===========================================================
        if (( $rc == RC_SUCCESS )); then
            if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then
                CL=$LINENO KLIB_HACMP_get_ldap_server_attributes "$servers" properties
            fi
        fi
    fi

    #=======================================================================
    : If a user input error was detected, provide some helpful suggestions
    #=======================================================================
    if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \
       [[ $CLMGR_GUI == *([[:space:]]) ]]
    then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \
        "add ldap_server -h" "LDAP SERVER:" "$CLMGR_PROGNAME" 1>&2
    fi

    log_return_msg "$rc" "$0()" "$LINENO"
    return $?
} # End of "KLIB_HACMP_add_ldap_server()"
