6418N/A#!/bin/ksh93
6418N/A#
6418N/A# $Id$
6418N/A#
6418N/A# CDDL HEADER START
6418N/A#
6418N/A# The contents of this file are subject to the terms of the
6418N/A# Common Development and Distribution License (the "License").
6418N/A# You may not use this file except in compliance with the License.
6418N/A#
6418N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
6418N/A# or http://www.opensolaris.org/os/licensing.
6418N/A# See the License for the specific language governing permissions
6418N/A# and limitations under the License.
6418N/A#
6418N/A# When distributing Covered Code, include this CDDL HEADER in each
6418N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
6418N/A# If applicable, add the following below this CDDL HEADER, with the
6418N/A# fields enclosed by brackets "[]" replaced with your own identifying
6418N/A# information: Portions Copyright [yyyy] [name of copyright owner]
6418N/A#
6418N/A# CDDL HEADER END
6418N/A#
6418N/A# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
6418N/A# Portions Copyright 2013 Jens Elkner.
6418N/A
6418N/A
6418N/A#############################################################################
6418N/A# Main global vars
6418N/A#############################################################################
6418N/ALIC='[-?$Id$ ]
6418N/A[-copyright?Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.]
6418N/A[-copyright?Portions Copyright (c) 2013 Jens Elkner.]
6418N/A[-license?CDDL 1.0]'
6418N/A
6418N/ASDIR=${.sh.file%/*}
6418N/Atypeset -r FPROG=${.sh.file}
6418N/Atypeset -r PROG=${FPROG##*/}
6418N/A
6418N/Atypeset -T LogObj_t=(
6418N/A typeset -Sh 'Color for info messages' GREEN='38;5;232;48;5;118' #'1;30;102';
6418N/A typeset -Sh 'Color for warning messages' BLUE='38;5;21;48;5;118' #'1;34;102';
6418N/A typeset -Sh 'Color for fatal messages' RED='38;5;9;48;5;118' #'1;31;102';
6418N/A typeset -Sih 'Flag, whether to use colored labels' COLORED=1
6418N/A typeset -Sih 'Flag, whether to print verbose infos' VERBOSE=0
6418N/A
6418N/A function log {
6418N/A (( _.COLORED )) && print -u2 "\E[1;$2m${ date +%T; } $1:\E[0m $3" || \
6418N/A print -u2 "${ date +%T; } ${1}: $3"
6418N/A }
6418N/A typeset -Sfh ' log a message to stderr' log
6418N/A function verbose {
6418N/A (( _.VERBOSE )) && _.log "VERB" ${_.GREEN} " $*"
6418N/A }
6418N/A typeset -Sfh ' log a info message to stderr if verbose messages are enabled' info
6418N/A
6418N/A function info {
6418N/A _.log "INFO" ${_.GREEN} "$*"
6418N/A }
6418N/A typeset -Sfh ' log a info message to stderr' info
6418N/A function warn {
6418N/A _.log "WARN" ${_.BLUE} "$*"
6418N/A }
6418N/A typeset -Sfh ' log a warning message to stderr' warn
6418N/A function fatal {
6418N/A _.log "FATAL" ${_.RED} "$*"
6418N/A }
6418N/A typeset -Sfh ' log a fatal error message to stderr' fatal
6418N/A function printMarker {
6418N/A typeset COLOR="$1" L='----------------------------------------------------------------------------'
6418N/A (( _.COLORED )) && print "\E[1;${COLOR:-${_.GREEN}}m${L}\E[0m" || \
6418N/A print "${L}"
6418N/A }
6418N/A typeset -Sfh ' print a marker line to stdout' printMarker
6418N/A)
6418N/ALogObj_t Log
6418N/A
6418N/Atypeset -T ManObj_t=(
6418N/A typeset -Ah 'Variable descriptions. Key: variable name' VAR
6418N/A typeset -Ah 'Function usages. Key: function name' FUNC
6418N/A function addVar {
6418N/A [[ -n ${_.VAR[$1]} ]] && Log.warn "Overwriting previous description for $1"
6418N/A _.VAR[$1]="[+$1?$2]"
6418N/A }
6418N/A typeset -fh 'Add a description (arg2) for the given variable name (arg1)' addVar
6418N/A function addFunc {
6418N/A typeset fname=$1
6418N/A typeset X="$2"
6418N/A [[ -n ${_.FUNC[$fname]} ]] && Log.warn "Overwriting previous usage info for $1()"
6418N/A [[ -z $X ]] && X="$LIC"
6418N/A shift 2
6418N/A while [[ -n $1 ]]; do
6418N/A X+="$1"
6418N/A shift
6418N/A done
6418N/A _.FUNC[$fname]+="$X"
6418N/A }
6418N/A typeset -fh $'Add usage info (arg3 ...) for the given function name (arg1). If implementation details (arg2) is empty, the value of \a$LIC\a gets used instead' addFunc
6418N/A function varUsage {
6418N/A typeset X=""
6418N/A [[ "$1" == '@' || "$1" == '*' ]] && set -- ${!_.VAR[@]}
6418N/A while [[ -n $1 ]]; do
6418N/A X+="${_.VAR[$1]}"
6418N/A shift
6418N/A done
6418N/A print "$X"
6418N/A }
6418N/A typeset -fh $'Get the variable usage info for the named variables (arg2 ...) if available as a concatenated string. See \baddVar()\b' varUsage
6418N/A function funcUsage {
6418N/A printf "${_.FUNC[$1]}"
6418N/A }
6418N/A typeset -fh 'Get the function usage info for the named function (arg1)' funcUsage
6418N/A
6418N/A function listVars {
6418N/A typeset ALL="${ print ${!_.VAR[*]} | tr ' ' '\n' | sort -u; }" VNAME
6418N/A for VNAME in $ALL; do
6418N/A [[ $VNAME == OLDENV || $VNAME == LASTENV ]] && continue
6418N/A typeset -n X=$VNAME
6418N/A print "$VNAME=$X"
6418N/A done
6418N/A unset -n X
6418N/A }
6418N/A typeset -fh 'List all registered environment variables and its current value, except for OLDENV and LASTENV.' listVars
6418N/A)
6418N/AManObj_t Man
6418N/A
6418N/AMan.addFunc showUsage '' '[+NAME?showUsage - show usage info.]
6418N/A[+DESCRIPTION?Shows usage info for the given \afname\a if available.]
6418N/A\n\n\afname\a
6418N/A'
6418N/Afunction showUsage {
6418N/A typeset WHAT="$2"
6418N/A if (( Log.VERBOSE )) && [[ ${WHAT} == 'MAIN' ]]; then
6418N/A typeset PRE=${Man.FUNC[$WHAT]%%\[+NOTES*}
6418N/A typeset POST=${.sh.match}
6418N/A typeset E='[+ENVIRONMENT VARIABLES]{'"${ Man.varUsage '*' ; }"'}'
6418N/A getopts -a "${PROG}" "${ print ${PRE}${E}${POST} ; }" OPT --man
6418N/A else
6418N/A getopts -a "${PROG}" "${ print ${Man.FUNC[$WHAT]}; }" OPT --man
6418N/A fi
6418N/A}
6418N/A
6418N/AMan.addVar PROG 'String. The basename of this script.'
6418N/A
6418N/AMan.addVar INT 'Associative array of Integers. Config relevant int values and flags.'
6418N/Atypeset -A -i INT=( )
6418N/AMan.addVar STR 'Associative array of Strings. Config relevant string values.'
6418N/Atypeset -A STR=( )
6418N/A
6418N/AMan.addVar TMPF 'Associative array of Integers. Int values with a more or less a global character in this script.'
6418N/Atypeset -A -i TMPF=( )
6418N/AMan.addVar TMP 'Associative array of Strings. String values whith a more or less a global character in this script.'
6418N/Atypeset -A TMP=( )
6418N/A
6418N/AMan.addVar CON_ARGS 'String. Contains connection related options for ldap commands.'
6418N/Atypeset CON_ARGS=''
6418N/A
6418N/AMan.addVar AUTH_ARGS 'Indexed array of Strings. Contains authentification related options for ldap commands.'
6418N/Atypeset -a AUTH_ARGS=( )
6418N/A
6418N/AMan.addVar SSD 'Indexed array of Strings. Contains the Service Search Decsriptors to use.'
6418N/Atypeset -a SSD=( )
6418N/A
6418N/A# NOTE: The ACI names are retained to be compatible to previous releases. If one
6418N/A# installs a completely new LDAP infrastructure changing the names should
6418N/A# not be a problem as long as they do not collide with existing aci names!
6418N/A
6418N/AMan.addVar SFX_ANYONE_ACI_NAME 'String constant. The name of the suffix ACI rule, which allows anyone to read, search, compare.'
6418N/Atypeset -r SFX_ANYONE_ACI_NAME='Anonymous access'
6418N/A
6418N/AMan.addVar SFX_SELF_ACI_NAME 'String constant. The name of the suffix ACI rule, which allows a principal to modify its own attributes except those related to password state information and policy.'
6418N/Atypeset -r SFX_SELF_ACI_NAME='Limited self entry modification'
6418N/A
6418N/AMan.addVar SFX_ADMIN_ACI_NAME 'String constant. The name of the suffix ACI rule, which allows the directory configuration administrator all operations on any entry.'
6418N/Atypeset -r SFX_ADMINGRP_ACI_NAME='Configuration Administrator access'
6418N/A
6418N/AMan.addVar SFX_ADMINGRP_ACI_NAME 'String constant. The name of the suffix ACI rule, which allows the directory configuration administrator group all operations on any entry.'
6418N/Atypeset -r SFX_ADMIN_ACI_NAME='Configuration Administrator Group access'
6418N/A
6418N/AMan.addVar PROXY_ACI_NAME 'String constant. The name of the ACI rule, which allows proxies to read passwords.'
6418N/Atypeset -r PROXY_ACI_NAME='LDAP Naming Services proxy_password_read'
6418N/A
6418N/AMan.addVar HOST_ACI_NAME 'String constant. The name of the ACI rule, which allows host principals to write passwords.'
6418N/Atypeset -r HOST_ACI_NAME='LDAP Naming Services host_shadow_write'
6418N/AMan.addVar NON_HOST_ACI_NAME 'String constant. The name of the ACI rule, which denies non-host principals access to shadow data.'
6418N/Atypeset -r NON_HOST_ACI_NAME='LDAP Naming Services deny_non_host_shadow_access'
6418N/A
6418N/AMan.addVar ADMIN_ACI_NAME 'String constant. The name of the ACI rule, which allows Admin principals access to shadow, rbac and mount data.'
6418N/Atypeset -r ADMIN_ACI_NAME='LDAP Naming Services admin_shadow_write'
6418N/AMan.addVar NON_ADMIN_ACI_NAME 'String constant. The name of the ACI rule, which denies non-Admin principals access to shadow data.'
6418N/Atypeset -r NON_ADMIN_ACI_NAME='LDAP Naming Services deny_non_admin_shadow_access'
6418N/AMan.addVar USER_ACI_NAME 'String constant. The name of the ACI rule, which prevents a user from changing administrative fields like uidNumber, homeDirectory, shadowExpire, etc..'
6418N/Atypeset -r USER_ACI_NAME='LDAP Naming Services deny_write_access'
6418N/A
6418N/AMan.addVar VLV_ACI_NAME 'String constant. The name of the global ACI rule, which allows any user to use VLVs for read, search and compare.'
6418N/Atypeset -r VLV_ACI_NAME='VLV Request Control'
6418N/A
6418N/AMan.addVar SELF_GSS_ACI_NAME 'String constant. The name of the ou=people ACI rule, which allows a via SASL/GSSAPI authenticated user read and search on passwords.'
6418N/Atypeset -r SELF_GSS_ACI_NAME='self-read-pwd'
6418N/A
6418N/AMan.addVar HOST_GSS_ACI_NAME 'String constant. The name of the ou=people ACI rule, which allows a via SASL/GSSAPI authenticated hosts read and search on passwords.'
6418N/Atypeset -r HOST_GSS_ACI_NAME='host-read-pwd'
6418N/A
6418N/AMan.addVar AUTH_METHODS 'Indexed array of Strings. A list of currently supported authentication methods.'
6418N/Atypeset -a -r AUTH_METHODS=(
6418N/A 'none' 'simple' 'sasl/DIGEST-MD5'
6418N/A 'tls:simple' 'tls:sasl/DIGEST-MD5' 'sasl/GSSAPI'
6418N/A) # order is important
6418N/A
6418N/AMan.addVar CRED_LEVELS 'Indexed array of Strings. A list of currently supported client credential levels.'
6418N/Atypeset -a -r CRED_LEVELS=( 'anonymous' 'proxy' 'proxy anonymous' 'self' )
6418N/A
6418N/AMan.addVar OID2ADEF 'Associative array of Strings. Key: OID, Value: attribute definition. Used to cache attribute definitions of schemas currently installed on the DS. Gets lazy initialized, i.e. populated when needed.'
6418N/Atypeset -A OID2ADEF=( )
6418N/AMan.addVar ANAME2OID 'Associative array of Strings. Key: attribute name (lowercase), Value: OID. Used to cache name to OID mappings. Gets initialized, when \bOID2ADEF\b gets populated.'
6418N/Atypeset -A ANAME2OID=( )
6418N/A
6418N/AMan.addVar OID2ODEF 'Associative array of Strings. Key: OID, Value: objectclass definition. Used to cache objectclass definitions of schemas currently installed on the DS. Gets lazy initialized, i.e. populated when needed.'
6418N/Atypeset -A OID2ODEF=( )
6418N/A
6418N/AMan.addFunc checkBinary '' '[+NAME?checkBinary - lookup a command.]
6418N/A[+DESCRIPTION?Check the standard path, whether it contains \acmd\a and if not, use \aPATH\a to lookup the command. If found the full path of the command gets printed to stdout, otherwise an error message to stderr.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?\acmd\a found.]
6418N/A [+1?\acmd\a not found.]
6418N/A}
6418N/A[+SEE ALSO?\bwhence\b(1).]
6418N/A\n\n\acmd\a
6418N/A'
6418N/Afunction checkBinary {
6418N/A typeset CMD=$1 X=''
6418N/A for DIR in /usr/bin /usr/sbin ; do
6418N/A [[ -x ${DIR}/${CMD} ]] && print ${DIR}/${CMD} && return 0
6418N/A done
6418N/A X=${ whence -fp ${CMD} ; }
6418N/A [[ -n $X ]] && print "${X}" && return 0
6418N/A X="${.sh.file%/*}/${CMD}"
6418N/A [[ -x ${X} ]] && print "$X" && return 0
6418N/A print -u2 "Missing command '${CMD}'."
6418N/A return 1
6418N/A}
6418N/A
6418N/AMan.addFunc init '' '[+NAME?init - initializes variables and options.]
6418N/A[+DESCRIPTION?Does some basic binary-avail checks and initializes certain values of \bSTR[]]\b, \bINT[]]\b and \bTMP[]]\b.]
6418N/A'
6418N/Afunction init {
6418N/A typeset X='' KEY VAL TAIL
6418N/A integer ERR=0
6418N/A
6418N/A # General commands
6418N/A HOST=${ hostname ; }
6418N/A PING=${ checkBinary ping || (( ERR++ )) ; }
6418N/A STTY=${ checkBinary stty || (( ERR++ )) ; }
6418N/A GETENT=${ checkBinary getent || (( ERR++ )) ; }
6418N/A
6418N/A # LDAP COMMANDS
6418N/A LDAPSEARCH=${ checkBinary ldapsearch || (( ERR++ )) ; }
6418N/A LDAPMODIFY=${ checkBinary ldapmodify || (( ERR++ )) ; }
6418N/A LDAPDELETE=${ checkBinary ldapdelete || (( ERR++ )) ; }
6418N/A LDAPCLIENT=${ checkBinary ldapclient || (( ERR++ )) ; }
6418N/A
6418N/A if (( ERR )); then
6418N/A Log.fatal 'Please adjust your PATH and try again'
6418N/A return 66
6418N/A fi
6418N/A LDAPSEARCH+=' -r'
6418N/A
6418N/A # If DNS domain (resolv.conf) exists use that, otherwise use domainname.
6418N/A if [[ -f /etc/resolv.conf ]]; then
6418N/A while read KEY VAL TAIL ; do
6418N/A if [[ ${KEY} == 'domain' || ${KEY} == 'search' ]]; then
6418N/A X=${VAL}
6418N/A break;
6418N/A fi
6418N/A done < /etc/resolv.conf
6418N/A fi
6418N/A
6418N/A # If for any reason the DOMAIN did not get set (error'd resolv.conf) set
6418N/A # X to the domainname or getent command's output.
6418N/A [[ -z $X ]] && X=${ domainname ; }
6418N/A if [[ -z $X ]]; then
6418N/A typeset -a AX=( ${ ${GETENT} hosts ${HOST} 2>/dev/null ; } )
6418N/A integer I
6418N/A for (( I=${#AX[@]}-1; I > 0; I++ )); do
6418N/A X=${AX[$I]#*.}
6418N/A [[ -n $X ]] && break
6418N/A done
6418N/A fi
6418N/A
6418N/A # Actually one needs to init non-null/zero values, only. However, we want
6418N/A # to have the keys registered ...
6418N/A
6418N/A # idsconfig specific variables.
6418N/A INT[LDAP_ENABLE_SHADOW_UPDATE]=0
6418N/A INT[NEED_PROXY]=0 # 0 = No Proxy, 1 = Create Proxy.
6418N/A INT[NEED_ADMIN]=0 # 0 = No Admin, 1 = Create Admin.
6418N/A INT[NEED_HOSTACL]=0 # 0 = No Host ACL, 1 = Create Host ACL.
6418N/A INT[EXISTING_PROFILE]=0
6418N/A (( INT[TASK_TIMEOUT] < 10 )) && INT[TASK_TIMEOUT]=60
6418N/A STR[LDAP_PROXYAGENT]=''
6418N/A STR[LDAP_PROXYAGENT_CRED]=''
6418N/A STR[LDAP_ADMINDN]=''
6418N/A STR[LDAP_ADMIN_CRED]='' # enableShadowUpdate flag and Admin credential
6418N/A STR[DS_DB]='' # storage backend name
6418N/A STR[LDAP_SUFFIX]='' # suffix within the backend
6418N/A STR[LDAP_DOMAIN]=${X%%.} # domainname on Server (default value)
6418N/A
6418N/A # DS specific information
6418N/A STR[DS_HOST]=''
6418N/A INT[DS_PORT]=389
6418N/A INT[NEED_TIME]=0
6418N/A INT[NEED_SIZE]=0
6418N/A INT[DS_TIMELIMIT]=0
6418N/A INT[DS_SIZELIMIT]=0
6418N/A
6418N/A # LDAP PROFILE related defaults
6418N/A STR[LDAP_ROOTDN]='cn=Directory Manager' # Provide common default.
6418N/A STR[LDAP_ROOTPWD]='' # NULL passwd (is invalid)
6418N/A STR[LDAP_PROFILE_NAME]='default'
6418N/A STR[LDAP_BASEDN]=''
6418N/A STR[LDAP_SERVER_LIST]=''
6418N/A STR[LDAP_AUTHMETHOD]=''
6418N/A INT[LDAP_FOLLOWREF]=0
6418N/A INT[NEED_CRYPT]=0
6418N/A INT[NEED_SRVAUTH_PAM]=0
6418N/A INT[NEED_SRVAUTH_KEY]=0
6418N/A INT[NEED_SRVAUTH_CMD]=0
6418N/A (( ! INT[NEED_CRYPT_IMPORT] )) && INT[NEED_CRYPT_IMPORT]=0
6418N/A STR[LDAP_SEARCH_SCOPE]='one'
6418N/A STR[LDAP_SRV_AUTHMETHOD_PAM]=''
6418N/A STR[LDAP_SRV_AUTHMETHOD_KEY]=''
6418N/A STR[LDAP_SRV_AUTHMETHOD_CMD]=''
6418N/A INT[LDAP_SEARCH_TIME_LIMIT]=30
6418N/A STR[LDAP_PREF_SRVLIST]=''
6418N/A INT[LDAP_PROFILE_TTL]=43200
6418N/A STR[LDAP_CRED_LEVEL]='proxy'
6418N/A INT[LDAP_BIND_LIMIT]=10
6418N/A
6418N/A # Service Search Descriptors (just make sure it is empty)
6418N/A SSD=( ); unset SSD[0] # unset is required!
6418N/A
6418N/A # GSSAPI setup
6418N/A INT[GSSAPI_ENABLE]=0
6418N/A STR[LDAP_KRB_REALM]=''
6418N/A
6418N/A # temp settings
6419N/A TMPF[FCNT]=0 # internal file counter - see nextFile()
6418N/A TMPF[IS_OPENDJ]=0 # set if detected DS is OpenDS/OpenDJ
6418N/A TMPF[DEL_OLD_PROFILE]=0 # 0 = don't, 1 = delete old profile
6418N/A TMPF[STEP]=1 # simple progress indicator
6418N/A TMPF[GSSAPI_AUTH_MAY_BE_USED]=0 # DS GSSAPI SASL support
6418N/A TMPF[NEED_CREATE_SUFFIX]=0 # see add_suffix()
6418N/A TMPF[NEED_CREATE_BACKEND]=0 # see add_suffix()
6418N/A # schema completion syntax to use:
6418N/A # 0 .. detect, 1 .. force OpenDJ, 2 .. force DSEE
6418N/A (( TMPF[SYNTAX] < 0 || TMPF[SYNTAX] > 2 )) && TMPF[SYNTAX]=0
6418N/A
6418N/A TMP[FILE]='' # tmp output filename - see nextFile()
6418N/A TMP[LDAP_ROOTPWF]=${TMP[DIR]}/rootPWD # filename containing the root PW
6418N/A TMP[WARN]='' # set if possibly incompatible DS
6418N/A TMP[SUFFIX_OBJ]='' # suffix objectclass (long name)
6418N/A TMP[SUFFIX_ATT]='' # suffix RDN attr name
6418N/A TMP[SUFFIX_VAL]='' # suffix RDN attr value
6418N/A TMP[DS_DBS_AVAIL]='' # next available suffix DBs
6418N/A TMP[VLV_CMDS]='' # where VLV commands to exec are stored
6418N/A # Set via getopts - just make sure, they are registered
6418N/A [[ -z ${TMP[IN]} ]] && TMP[IN]='' # the config file to read
6418N/A [[ -z ${TMP[OUT]} ]] && TMP[OUT]='' # the config file to write
6418N/A # redirect ldap output to file instead of stdout
6418N/A if (( TMPF[FD] > 2 )); then
6418N/A exec 4>${TMP[DIR]}/ldap.out
6419N/A TMPF[FD]=4
6418N/A fi
6418N/A return 0
6418N/A}
6418N/A
6418N/A# internal
6418N/Afunction showProgress {
6418N/A typeset NUM=${ printf "%3d" TMPF[STEP] ; }
6418N/A Log.info "${NUM}. " "$*"
6418N/A (( TMPF[STEP]++ ))
6418N/A}
6418N/A
6418N/A# internal
6418N/Afunction nextFile {
6418N/A typeset CMD="$1" FN="${2// /_}" EXT='cmd'
6419N/A (( TMPF[FCNT]++ ))
6418N/A case "$1" in
6418N/A add|modify|delete) CMD="ldap$1" EXT='ldif' ;;
6418N/A sh) EXT='sh'
6418N/A esac
6419N/A TMP[FILE]=${ printf "${TMP[DIR]}/%03d_${CMD}_${FN}.${EXT}" ${TMPF[FCNT]} ; }
6418N/A [[ -e ${TMP[FILE]} ]] && Log.warn "Overwriting ${TMP[FILE]} ..."
6418N/A}
6418N/A
6418N/AMan.addFunc show_vars '' '[+NAME?show_vars - List of all config variables and their values.]
6418N/A[+DESCRIPTION?Lists all config variables and their current values in a more or less human readable manner.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage INT STR SSD ; }" '}
6418N/A'
6418N/Afunction show_vars {
6418N/A (( ! VERBOSE )) && return
6418N/A
6418N/A typeset S=${!STR[@]} OUT='Current non-NULL values:\n'
6418N/A S=${ print ${S// /$'\n'} | sort ; }
6418N/A for KEY in $S ; do
6418N/A [[ -n ${STR[$KEY]} ]] && \
6418N/A OUT+=${ printf "%32s = '%s'" ${KEY} "${STR[$KEY]}" ; }'\n'
6418N/A done
6418N/A S=${!INT[@]}
6418N/A S=${ print ${S// /$'\n'} | sort ; }
6418N/A for KEY in $S ; do
6418N/A (( INT[$KEY] )) && \
6418N/A OUT+=${ printf "%32s = %d" ${KEY} "${INT[$KEY]}" ; }'\n'
6418N/A done
6418N/A if (( ${#SSD[@]} )); then
6418N/A OUT+=${ printf "%32s = (" 'SSD' ; }
6418N/A for S in "${SSD[@]}" ; do
6418N/A OUT+="\t\t${S}\n"
6418N/A done
6418N/A OUT+='\t)\n'
6418N/A fi
6418N/A print -u2 "${OUT}"
6418N/A}
6418N/A
6418N/AMan.addFunc save_password '' '[+NAME?save_password - Save password to temporary file.]
6418N/A[+DESCRIPTION?Save the current password from \bSTR[LDAP_ROOTPWD]]\b to the file \bTMP[LDAP_ROOTPWF]]\b.]
6418N/A'
6418N/Afunction save_password {
6418N/A print "${STR[LDAP_ROOTPWD]}" >"${TMP[LDAP_ROOTPWF]}"
6418N/A}
6418N/A#############################################################################
6418N/A# EOG
6418N/A#############################################################################
6418N/A
6418N/A
6418N/A#############################################################################
6418N/A# config file stuff
6418N/A#############################################################################
6418N/AMan.addFunc create_config_file '' '[+NAME?create_config_file - Write config data to the specified file.]
6418N/A[+DESCRIPTION?Write config data to \afile\a.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage INT STR SSD ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?file was written successfully.]
6418N/A [+>= 1?otherwise.]
6418N/A}
6418N/A[+SEE ALSO?\bload_config_file()\b.]
6418N/A\n\n\afile\a
6418N/A'
6418N/Afunction create_config_file {
6418N/A typeset OUT="$1" KEY
6418N/A [[ -z ${OUT} ]] && return 1
6418N/A
6418N/A # Create output file.
6418N/A (
6418N/A print '
6418N/A# '"${OUT}"' - This file contains configuration information for
6418N/A# LDAP naming services. Use the '"${PROG}"' tool to load it.
6418N/A#
6418N/A# WARNING: This file was generated by '"${PROG}"', and is intended to
6418N/A# be loaded by '"${PROG}"' as is. DO NOT EDIT THIS FILE!
6418N/A'
6418N/A print 'typeset -A -i IIN=( )'
6418N/A for KEY in "${!INT[@]}" ; do
6418N/A print "IIN[${KEY}]=${INT[${KEY}]}"
6418N/A done
6418N/A print '\ntypeset -A SIN=( )'
6418N/A for KEY in "${!STR[@]}" ; do
6418N/A printf "SIN[${KEY}]=%q\n" "${STR[${KEY}]}"
6418N/A done
6418N/A print '\ntypeset -a SIN_SSD=( )'
6418N/A for KEY in "${SSD[@]}" ; do
6418N/A [[ -n ${KEY} ]] && printf "SIN_SSD+=( %q )\n" "${KEY}"
6418N/A done
6418N/A print "\n# End of ${OUT}"
6418N/A ) >"${OUT}"
6418N/A}
6418N/A
6418N/A# for backward compatibilty, but not documented: old format is bogus and should
6418N/A# not be used anymore.
6418N/Afunction source_old_config {
6418N/A typeset IN="$1" TODO='' VNAME KEY VAL LINE
6418N/A typeset -A OLDMAP=(
6418N/A [DS_HOST]=IDS_SERVER
6418N/A [DS_PORT]=IDS_PORT
6418N/A [DS_DB]=IDS_DATABASE
6418N/A [DS_TIMELIMIT]=IDS_TIMELIMIT
6418N/A [DS_SIZELIMIT]=IDS_SIZELIMIT
6418N/A [SSD]=LDAP_SERV_SRCH_DES
6418N/A )
6418N/A
6418N/A for KEY in "${!INT[@]}" ; do
6418N/A VNAME=${OLDMAP[${KEY}]}
6418N/A [[ -z ${VNAME} ]] && VNAME=${KEY}
6418N/A typeset -n VAR=${VNAME}
6418N/A INT[${KEY}]=${VAR}
6418N/A TODO+="${VNAME} "
6418N/A done
6418N/A for KEY in "${!STR[@]}" ; do
6418N/A VNAME=${OLDMAP[${KEY}]}
6418N/A [[ -z ${VNAME} ]] && VNAME=${KEY}
6418N/A typeset -n VAR=${VNAME}
6418N/A STR[${KEY}]="${VAR}"
6418N/A TODO+="${VNAME} "
6418N/A done
6418N/A while read LINE; do
6418N/A if [[ ${LINE:0:19} == 'LDAP_SERV_SRCH_DES=' ]]; then
6418N/A VAL="${LINE:19}"
6418N/A [[ -n ${VAL} ]] && SSD+=( "${VAL}" )
6418N/A fi
6418N/A done < "${IN}"
6418N/A
6418N/A # cleanup "global" namespace
6418N/A [[ -n ${TODO} ]] && eval "unset ${TODO}"
6418N/A}
6418N/A
6418N/AMan.addFunc load_config_file '' '[+NAME?load_config_file - load an '"${PROG}"' config file.]
6418N/A[+DESCRIPTION?Loads the initial config from \afile\a, which has been generated in a previous run by '"${PROG}"'. Sets \bTMPF[DEL_OLD_PROFILE]]\b to 1 on success.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage INT STR SSD ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66? \afile\a is not a file or unreadable.]
6418N/A}
6418N/A[+SEE ALSO?\bsave_password()\b, \bshow_vars()\b.]
6418N/A\n\n\afile\a
6418N/A'
6418N/Afunction load_config_file {
6418N/A typeset IN="$1" KEY VAL
6418N/A integer I
6418N/A [[ ! -f ${IN} ]] && Log.fatal "${IN} is not a file" && return 66
6418N/A [[ ! -r ${IN} ]] && Log.fatal "${IN} is not readable" && return 67
6418N/A
6418N/A # source in the stuff - not nice but less work ;-)
6418N/A . "${IN}"
6418N/A
6418N/A KEY=${ typeset -p IIN ; }
6418N/A if [[ -z ${KEY} ]]; then
6418N/A source_old_config "${IN}" || return 68
6418N/A else
6418N/A for KEY in "${!INT[@]}" ; do
6418N/A INT[${KEY}]=${IIN[${KEY}]}
6418N/A done
6418N/A for KEY in "${!STR[@]}" ; do
6418N/A STR[${KEY}]="${SIN[${KEY}]}"
6418N/A done
6418N/A for KEY in "${SIN_SSD[@]}" ; do
6418N/A [[ -n ${KEY} ]] && SSD+=( "${KEY}" )
6418N/A done
6418N/A # cleanup "global" namespace
6418N/A unset IIN SIN SIN_SSD
6418N/A fi
6418N/A
6418N/A TMPF[DEL_OLD_PROFILE]=1
6418N/A save_password
6418N/A show_vars
6418N/A
6418N/A return 0
6418N/A}
6418N/A#############################################################################
6418N/A# End Of config file stuff
6418N/A#############################################################################
6418N/A
6418N/A
6418N/A############################################################################
6418N/A# Basic [menu] stuff
6418N/A############################################################################
6418N/AMan.addFunc display_msg '' '[+NAME?display_msg - display a message]
6418N/A[+DESCRIPTION?Display a message corresponding to the \atag\a passed in.]
6418N/A[+ENVIRONMENT VARIABLES]{'"${ Man.varUsage INT STR TMP ; }" '}
6418N/A\n\n\atag\a
6418N/A'
6418N/Afunction display_msg {
6418N/A typeset X
6418N/A integer I
6418N/A
6418N/A case "$1" in
6418N/A backup_server)
6418N/A print '
6418N/AIt is strongly recommended that you BACKUP the directory server
6418N/Abefore running '"${PROG}"'.
6418N/A
6418N/AHit Ctrl-C at any time before the final confirmation to exit.\n'
6418N/A ;;
6418N/A cred_level_menu)
6418N/A print 'The following are the supported credential levels:'
6418N/A for (( I=0; I < ${#CRED_LEVELS[@]}; I++ )); do
6418N/A printf ' %2d %s\n' $((I+1)) "${CRED_LEVELS[I]}"
6418N/A done
6418N/A ;;
6418N/A auth_method_menu)
6418N/A print 'The following are the supported Client Authentication Methods:'
6418N/A for (( I=0; I < ${#AUTH_METHODS[@]}; I++ )); do
6418N/A printf ' %-2d %s\n' $((I+1)) "${AUTH_METHODS[I]}"
6418N/A done
6418N/A ;;
6418N/A srvauth_method_menu)
6418N/A print 'The following are the supported Service Authentication Methods:'
6418N/A # skip 'none'
6418N/A for (( I=1; I < ${#AUTH_METHODS[@]}; I++ )); do
6418N/A printf ' %-2d %s\n' $((I)) "${AUTH_METHODS[I]}"
6418N/A done
6418N/A ;;
6418N/A prompt_ssd_menu)
6418N/A print ' A Add a Service Search Descriptor (SSD)
6418N/A D Delete a SSD
6418N/A M Modify a SSD
6418N/A P Display all SSDs
6418N/A H Help
6418N/A X Clear all SSDs
6418N/A
6418N/A Q Exit menu'
6418N/A ;;
6418N/A summary_menu)
6418N/A typeset SUFFIX_INFO=''
6418N/A typeset DB_INFO=''
6418N/A
6418N/A if (( TMPF[NEED_CREATE_SUFFIX] )); then
6418N/A SUFFIX_INFO='
6418N/A Suffix to create : '"${STR[LDAP_SUFFIX]}"'\n'
6418N/A (( TMPF[NEED_CREATE_BACKEND] )) && DB_INFO='
6418N/A Database to create : '"${STR[DS_DB]}"'\n'
6418N/A fi
6418N/A typeset BASEDN
6418N/A BASEDN="${STR[LDAP_BASEDN]}${STR[SUFFIX_INFO]}${STR[DB_INFO]}"
6418N/A
6418N/A print ' Summary of Configuration
6418N/A
6418N/A 1 Domain to serve : '"${STR[LDAP_DOMAIN]}"'
6418N/A 2 Base DN to setup : '"${BASEDN}"'
6418N/A 3 Profile name to create : '"${STR[LDAP_PROFILE_NAME]}"'
6418N/A 4 Default Server List : '"${STR[LDAP_SERVER_LIST]}"'
6418N/A 5 Preferred Server List : '"${STR[LDAP_PREF_SRVLIST]}"'
6418N/A 6 Default Search Scope : '"${STR[LDAP_SEARCH_SCOPE]}"'
6418N/A 7 Credential Level : '"${STR[LDAP_CRED_LEVEL]}"'
6418N/A 8 Authentication Method : '"${STR[LDAP_AUTHMETHOD]}"'
6418N/A 9 Enable Follow Referrals : '"${INT[LDAP_FOLLOWREF]}"'
6418N/A 10 DS Time Limit : '"${INT[DS_TIMELIMIT]}"'
6418N/A 11 DS Size Limit : '"${INT[DS_SIZELIMIT]}"'
6418N/A 12 Enable crypt password storage : '"${INT[NEED_CRYPT]}"'
6418N/A 13 Service Auth Method pam_ldap : '"${STR[LDAP_SRV_AUTHMETHOD_PAM]}"'
6418N/A 14 Service Auth Method keyserv : '"${STR[LDAP_SRV_AUTHMETHOD_KEY]}"'
6418N/A 15 Service Auth Method passwd-cmd: '"${STR[LDAP_SRV_AUTHMETHOD_CMD]}"'
6418N/A 16 Search Time Limit : '"${INT[LDAP_SEARCH_TIME_LIMIT]}"'
6418N/A 17 Profile Time to Live : '"${INT[LDAP_PROFILE_TTL]}"'
6418N/A 18 Bind Limit : '"${INT[LDAP_BIND_LIMIT]}"'
6418N/A 19 Enable shadow update : '"${INT[LDAP_ENABLE_SHADOW_UPDATE]}"'
6418N/A 20 Service Search Descriptors Menu\n'
6418N/A ;;
6418N/A sorry)
6418N/A print '
6418N/AHELP - No help is available for this topic.\n'
6418N/A ;;
6418N/A create_suffix_help)
6418N/A print '
6418N/AHELP - Our Base DN is "'"${STR[LDAP_BASEDN]}"'"
6418N/A and we need to create a Directory Suffix,
6418N/A which can be equal to Base DN itself or be any of Base DN parents.
6418N/A All intermediate entries up to suffix will be created on demand.\n'
6418N/A ;;
6418N/A enter_ldbm_db_help)
6418N/A print '
6418N/AHELP - database backend is an internal database for storage of our suffix data.
6418N/A Backend name must be alphanumeric due to Directory Server restriction.
6418N/A'
6418N/A ;;
6418N/A backup_help)
6418N/A print '
6418N/AHELP - Since '"${PROG}"' modifies the directory server configuration,
6418N/A it is strongly recommended that you backup the server prior
6418N/A to running this utility. This is especially true if the server
6418N/A being configured is a production server.\n'
6418N/A ;;
6418N/A port_help)
6418N/A print '
6418N/AHELP - Enter the port number the directory server is configured to
6418N/A use for LDAP.\n'
6418N/A ;;
6418N/A adminport_help)
6418N/A print '
6418N/AHELP - Enter the Admin port number the directory server is configured to
6418N/A use for for DS administration commands.\n'
6418N/A ;;
6418N/A domain_help)
6418N/A print '
6418N/AHELP - This is the DNS domain name this server will be serving. You
6418N/A must provide this name even if the server is not going to be populated
6418N/A with hostnames. Any unqualified hostname stored in the directory
6418N/A will be fully qualified using this DNS domain name.\n'
6418N/A ;;
6418N/A basedn_help)
6418N/A print '
6418N/AHELP - This parameter defines the default location in the directory tree for
6418N/A the naming services entries. You can override this default by using
6418N/A Service Search Descriptors (SSD). You will be given the option to set up
6418N/A an SSD later on in the setup.\n'
6418N/A ;;
6418N/A profile_help)
6418N/A print '
6418N/AHELP - Name of the configuration profile with which the clients will be
6418N/A configured. A directory server can store various profiles for multiple
6418N/A groups of clients. The initialization tool, (ldapclient(1M)), assumes
6418N/A "default" unless another is specified.\n'
6418N/A ;;
6418N/A def_srvlist_help)
6418N/A print '
6418N/AHELP - Provide a list of directory servers to serve clients using this profile.
6418N/A All these servers should contain consistent data and provide similar
6418N/A functionality. This list is not ordered, and clients might change the
6418N/A order given in this list. Note that this is a space separated list of
6418N/A *IP addresses* (not host names). Providing port numbers is optional.\n'
6418N/A ;;
6418N/A pref_srvlist_help)
6418N/A print '
6418N/AHELP - Provide a list of directory servers to serve this client profile.
6418N/A Unlike the default server list, which is not ordered, the preferred
6418N/A servers must be entered IN THE ORDER you wish to have them contacted.
6418N/A If you do specify a preferred server list, clients will always contact
6418N/A them before attempting to contact any of the servers on the default
6418N/A server list. Note that you must enter the preferred server list as a
6418N/A space-separated list of *IP addresses* (not host names). Providing port
6418N/A numbers is optional.\n'
6418N/A ;;
6418N/A srch_scope_help)
6418N/A print '
6418N/AHELP - Default search scope to be used for all searches unless they are
6418N/A overwritten using serviceSearchDescriptors. The valid options
6418N/A are "one", which would specify the search will only be performed
6418N/A at the base DN for the given service, or "sub", which would specify
6418N/A the search will be performed through *all* levels below the base DN
6418N/A for the given service. If you use the default DIT layout, "one" should
6418N/A be ok and probably a little bit faster.\n'
6418N/A ;;
6418N/A cred_lvl_help)
6418N/A print '
6418N/AHELP - This parameter defines what credentials (identity) the clients use to
6418N/A authenticate (bind) to the directory server. This list might contain
6418N/A multiple credential levels and is ordered. If a proxy level is
6418N/A configured, you will also be prompted to enter a bind DN for the
6418N/A proxy agent along with a password. This proxy agent will be created
6418N/A if it does not exist. See also ldapclient(1M).\n'
6418N/A ;;
6418N/A auth_help)
6418N/A print '
6418N/AHELP - The default authentication (bind) method(s) to be used by all services
6418N/A in the client using this profile. This is a ordered list of
6418N/A authentication methods separated by a ";". The supported methods are
6418N/A provided in a menu. Note that sasl/DIGEST-MD5 binds require passwords
6418N/A to be stored un-encrypted on the server. See also ldapclient(1M).\n'
6418N/A ;;
6418N/A srvauth_help)
6418N/A print '
6418N/AHELP - The non-default authentication (bind) methods to be used by certain
6418N/A services (for now pam_ldap, keyserv, and passwd-cmd are supported).
6418N/A The authentication methods specified in this attribute overrides
6418N/A the default authentication method defined in the profile. This
6418N/A feature can be used to select stronger authentication methods for
6418N/A services which require increased security.\n'
6418N/A ;;
6418N/A pam_ldap_help)
6418N/A print '
6418N/AHELP - The authentication (bind) method(s) to be used by pam_ldap when
6418N/A contacting the directory server. This is a ordered list, and, if
6418N/A provided, will override the default authentication method parameter.\n'
6418N/A ;;
6418N/A keyserv_help)
6418N/A print '
6418N/AHELP - The authentication (bind) method(s) to be used by newkey(1M) and chkey(1)
6418N/A when contacting the directory server. This is a ordered list and if
6418N/A provided will override the default authentication method parameter.\n'
6418N/A ;;
6418N/A passwd-cmd_help)
6418N/A print '
6418N/AHELP - The authentication (bind) method(s) to be used by passwd(1) command when
6418N/A contacting the directory server. This is a ordered list and if
6418N/A provided will override the default authentication method parameter.\n'
6418N/A ;;
6418N/A referrals_help)
6418N/A print '
6418N/AHELP - This parameter indicates whether the client should follow
6418N/A ldap referrals if it encounters one during naming lookups.\n'
6418N/A ;;
6418N/A tlim_help)
6418N/A print '
6418N/AHELP - The server time limit value indicates the maximum amount of time the
6418N/A server would spend on a query from the client before abandoning it.
6418N/A A value of "-1" indicates no limit.\n'
6418N/A ;;
6418N/A slim_help)
6418N/A print '
6418N/AHELP - The server sizelimit value indicates the maximum number of entries
6418N/A the server would return in respond to a query from the client. A
6418N/A value of "-1" indicates no limit.\n'
6418N/A ;;
6418N/A crypt_help)
6418N/A print '
6418N/AHELP - By default a DS does not store userPassword attribute values using
6418N/A unix "crypt" formats (like bsdmd5, sunmd5, sha256, sha512, old crypt,
6418N/A etc. - see crypt.conf(4)). If you need to keep your passwords in the
6418N/A crypt formats for backward or pam_unix compatibility, choose "yes".
6418N/A If any other password storage scheme than crypt is used, pam_ldap
6418N/A MUST be used by clients to authenticate users to the system. Note
6418N/A that if you wish to use sasl/*-MD5 in conjunction with pam_ldap,
6418N/A user passwords are/must be stored in the clear text.\n'
6418N/A ;;
6418N/A srchtime_help)
6418N/A print '
6418N/AHELP - The search time limit the client will enforce for directory lookups.\n'
6418N/A ;;
6418N/A profttl_help)
6418N/A print '
6418N/AHELP - The time to live value for profile. The client will refresh its
6418N/A cached version of the configuration profile at this TTL interval.\n'
6418N/A ;;
6418N/A bindlim_help)
6418N/A print '
6418N/AHELP - The time limit for the bind operation to the directory. This
6418N/A value controls the responsiveness of the client in case a server
6418N/A becomes unavailable. The smallest timeout value for a given
6418N/A network architecture/conditions would work best. This is very
6418N/A similar to setting TCP timeout, but only for LDAP bind operation.\n'
6418N/A ;;
6418N/A ssd_help)
6418N/A print '
6418N/AHELP - Using Service Search Descriptors (SSD), you can override the
6418N/A default configuration for a given service. The SSD can be
6418N/A used to override the default search base DN, the default search
6418N/A scope, and the default search filter to be used for directory
6418N/A lookups. SSD are supported for all services (databases)
6418N/A defined in nsswitch.conf(4). See also ldapclient(1M).
6418N/A
6418N/A Note: SSD are powerful tools in defining configuration profiles
6418N/A and provide a great deal of flexibility. However, care
6418N/A must be taken in creating them. If you decide to make use
6418N/A of SSDs, consult the documentation first.\n'
6418N/A ;;
6418N/A ssd_menu_help)
6418N/A print '
6418N/AHELP - Using this menu SSD can be added, updated, or deleted from
6418N/A the profile.
6418N/A
6418N/A A - This option creates a new SSD by prompting for the
6418N/A service name, base DN, and scope. Service name is
6418N/A any valid service as defined in ldap(1). base is
6418N/A either the distinguished name to the container where
6418N/A this service will use, or a relative DN followed
6418N/A by a ",". For more information see ldapclient(1M).
6418N/A D - Delete a previously created SSD.
6418N/A M - Modify a previously created SSD.
6418N/A P - Display a list of all the previously created SSD.
6418N/A X - Delete all of the previously created SSD.
6418N/A
6418N/A Q - Exit the menu and continue with the server configuration.\n'
6418N/A ;;
6418N/A enable_shadow_update_help)
6418N/A print '
6418N/AHELP - Enter "y" to set up the LDAP server for shadow update.
6418N/A The setup will add an administrator identity/credential
6418N/A and modify the necessary access controls for the client
6418N/A to update shadow(4), auth_attr(4), exec_attr(4), prof_attr(4),
6418N/A user_attr(4), and project(4) data on the LDAP server. If
6418N/A sasl/GSSAPI is in use, the Kerberos host principal will be used
6418N/A as the administrator identity.
6418N/A
6418N/A Shadow data is used for password aging and account locking.
6418N/A Please refer to the shadow(4) manual page for details.\n'
6418N/A ;;
6418N/A add_admin_cred_help)
6418N/A print '
6418N/AHELP - Start the setup to add an administrator identity/credential
6418N/A and to modify access controls for the client to update
6418N/A shadow(4), auth_attr(4), exec_attr(4), prof_attr(4),
6418N/A user_attr(4), and project(4) data on the LDAP server.
6418N/A
6418N/A Shadow data is used for password aging and account locking.
6418N/A Please refer to the shadow(4) manual page for details.\n'
6418N/A ;;
6418N/A use_host_principal_help)
6418N/A print '
6418N/AHELP - A profile with a "sasl/GSSAPI" authentication method and a "self"
6418N/A credential level is detected, enter "y" to modify the necessary
6418N/A access controls for allowing the client to update shadow(4) data
6418N/A on the LDAP server.
6418N/A
6418N/A Shadow data is used for password aging and account locking.
6418N/A Please refer to the shadow(4) manual page for details.\n'
6418N/A ;;
6418N/A esac
6418N/A}
6418N/A
6418N/AMan.addVar ANS 'Variable used to return the user input.'
6418N/AMan.addFunc get_ans '' '[+NAME?get_ans - gets an answer from the user.]
6418N/A[+DESCRIPTION?Read a string from stdin. Arguments:]{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage ANS ; }" '}
6418N/A\n\n\aprompt\a [\adefault\a]
6418N/A'
6418N/Afunction get_ans {
6418N/A typeset PROMPT="$1 "
6418N/A [[ -n $2 ]] && PROMPT+="[$2] "
6418N/A
6418N/A read ANS?"${PROMPT}"
6418N/A [[ -z ${ANS} ]] && ANS="$2"
6418N/A}
6418N/A
6418N/A
6418N/AMan.addFunc get_ans_req '' '[+NAME?get_ans_req - get a non-empty answer from the user.]
6418N/A[+DESCRIPTION?Read a string from stdin. Does not return until the string is a non-empty string or a \adefault\a value is given. Arguments:]{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage ANS ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b]
6418N/A\n\n\aprompt\a [\adefault\a]
6418N/A'
6418N/Afunction get_ans_req {
6418N/A ANS=''
6418N/A while [[ -z ${ANS} ]]; do
6418N/A get_ans "$@"
6418N/A [[ -z ${ANS} ]] && Log.warn 'NULL value not allowed'
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc is_numeric '' '[+NAME?is_numeric - check whether arg is a numeric string]
6418N/A[+DESCRIPTION?Check whether the given \astring\a is a numeric string.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?If the string is a numeric string.]
6418N/A [+1?Otherwise.]
6418N/A}
6418N/A[+SEE ALSO?\bnot_numeric()\b]
6418N/A\n\n\astring\a
6418N/A'
6418N/Afunction is_numeric {
6418N/A (( $# != 1 )) && return 1
6418N/A [[ $1 =~ ^[0-9]+$ ]] && return 0 || return 1
6418N/A}
6418N/A
6418N/AMan.addFunc not_numeric '' '[+NAME?not_numeric - check whether arg is NOT a numeric string]
6418N/A[+DESCRIPTION?Check whether the given \astring\a is NOT a numeric string. Useful for if and while statements that want to test for non-numeric data.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?If the string is NOT a numeric string.]
6418N/A [+1?Otherwise.]
6418N/A}
6418N/A[+SEE ALSO?\bis_numeric()\b]
6418N/A\n\n\astring\a
6418N/A'
6418N/Afunction not_numeric {
6418N/A is_numeric $1 && return 1 || return 0
6418N/A}
6418N/A
6418N/AMan.addVar NUM 'Variable used to return the user input as a number.'
6418N/Ainteger NUM
6418N/AMan.addFunc get_number '' '[+NAME?get_number - get a number from the user.]
6418N/A[+DESCRIPTION?Read a string from stdin until it represents a number. Arguments:]
6418N/A{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A [+helpTag?Tag of the help message to show, when the string read is h|H|?|help|Help.]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage NUM ANS ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b, \bis_numeric()\b, \bdisplay_msg()\b]
6418N/A\n\n\aprompt\a \adefault\a [\ahelpTag\a]
6418N/A'
6418N/Afunction get_number {
6418N/A ANS=''
6418N/A
6418N/A get_ans "$1" "$2"
6418N/A
6418N/A while not_numeric $ANS ; do
6418N/A case "${ANS}" in
6418N/A [Hh?] | help | Help) display_msg ${3:-sorry} ;;
6418N/A * ) Log.warn "Invalid value: '${ANS}'" ;;
6418N/A esac
6418N/A get_ans 'Enter a numeric value:' "$2"
6418N/A done
6418N/A NUM=${ANS}
6418N/A}
6418N/A
6418N/A
6418N/AMan.addFunc get_negone_num '' '[+NAME?get_negone_num - get a number >= -1 from the user.]
6418N/A[+DESCRIPTION?Read a string from stdin until it represents a number >= -1. Arguments:]
6418N/A{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A [+helpTag?Tag of the help message to show, when the string read is h|H|?|help|Help.]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage NUM ANS ; }" '}
6418N/A[+SEE ALSO?\bget_number()\b]
6418N/A\n\n\aprompt\a \adefault\a [\ahelpTag\a]
6418N/A'
6418N/Afunction get_negone_num {
6418N/A while : ; do
6418N/A get_number "$1" "$2" "$3"
6418N/A (( NUM >= -1 )) && break
6418N/A Log.warn 'Invalid number! Enter a number >= -1'
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc get_passwd '' '[+NAME?get_passwd - get a password from the user.]
6418N/A[+DESCRIPTION?Read a password from stdin and verify with second until both match. Password gets not echoed to stdout. Arguments:]
6418N/A{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage ANS ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b]
6418N/A\n\n\aprompt\a [\adefault\a]
6418N/A'
6418N/Afunction get_passwd {
6418N/A typeset _PASS1='' _PASS2=''
6418N/A
6418N/A ${STTY} -echo # Turn echo OFF
6418N/A
6418N/A # continue until passwd and re-entered passwd match
6418N/A while : ; do
6418N/A ANS=''
6418N/A # Don't allow NULL for first try.
6418N/A while [[ -z ${ANS} ]]; do
6418N/A get_ans "$@"
6418N/A [[ -z ${ANS} ]] && \
6418N/A print -u2 && Log.warn 'Empty password not allowed'
6418N/A done
6418N/A _PASS1="${ANS}" # Store first try.
6418N/A
6418N/A print
6418N/A get_ans 'Re-enter password:'
6418N/A _PASS2="${ANS}"
6418N/A
6418N/A [[ ${_PASS1} == ${_PASS2} ]] && break
6418N/A print -u2 && Log.warn "passwords don't match - try again"
6418N/A done
6418N/A
6418N/A ${STTY} echo # Turn echo ON
6418N/A
6418N/A print
6418N/A}
6418N/A
6418N/AMan.addFunc get_passwd_nochk '' '[+NAME?get_passwd_nochk - get a password from the user w/o check.]
6418N/A[+DESCRIPTION?Read a password from stdin. Actually the same as \bget_ans()\b but echoing characters read to stdout is switched off. Arguments:]
6418N/A{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage ANS ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b]
6418N/A\n\n\aprompt\a [\adefault\a]
6418N/A'
6418N/Afunction get_passwd_nochk {
6418N/A ${STTY} -echo # Turn echo OFF
6418N/A get_ans "$@"
6418N/A ${STTY} echo # Turn echo ON
6418N/A print
6418N/A}
6418N/A
6418N/AMan.addFunc get_menu_choice '' '[+NAME?get_menu_choice - get a valid menu choice number.]
6418N/A[+DESCRIPTION?Get a menu choice from user. Continue prompting until the choice is in required range. Arguments:]
6418N/A{
6418N/A [+prompt?Message text.]
6418N/A [+min?Min value.]
6418N/A [+max?Max value.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A [+helpTag?If given, "h" is allowed as well and the help message for this tag gets shown, when it got typed and before the prompt is shown the first time. The prompt should contain a hint in this case.]
6418N/A [+menuTag?If given the menu choices for the given menu gest displayed at start and after each help text.]
6418N/A}
6418N/A[+RETURN VALUES]{
6418N/A [+-1?on error (invalid parameters).]
6418N/A [+>= \amin\a?the selected value.]
6418N/A}
6418N/A[+SEE ALSO?\bis_numeric()\b, \bget_ans()\b, \bdisplay_msg()\b.]
6418N/A\n\n\aprompt\a \amin\a \amax\a [\adefault\a [\ahelpTag\a]]
6418N/A'
6418N/Afunction get_menu_choice {
6418N/A if (( $# < 3 )); then
6418N/A Log.warn "${.sh.fun}(): Did not get required parameters"
6418N/A return -1
6418N/A fi
6418N/A
6418N/A [[ -n $6 ]] && display_msg "$6"
6418N/A while : ; do
6418N/A get_ans "$1" "$4"
6418N/A if is_numeric ${ANS} && NUM=${ANS} && (( NUM >= $2 )) && (( NUM <= $3 ))
6418N/A then
6418N/A return ${NUM}
6418N/A fi
6418N/A if [[ -n $5 && ${ANS} == 'h' ]]; then
6418N/A display_msg "$5"
6418N/A [[ -n $6 ]] && display_msg "$6"
6418N/A continue
6418N/A fi
6418N/A Log.warn "Invalid choice! Enter a number in the range $2 .. $3"
6418N/A done
6418N/A return -1
6418N/A}
6418N/A
6418N/AMan.addFunc get_confirm '' '[+NAME?get_confirm - Get confirmation from the user.]
6418N/A[+DESCRIPTION?Read a string from stdin until it matches Y|y|Yes|yes|YES|N|n|No|no|NO or an empty string. Arguments:]
6418N/A{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A [+default?Default value to use if no answer/empty string was read.]
6418N/A [+helpTag?Tag of the help message to show, when the string read is h|H|?|help|Help.]
6418N/A}
6418N/A[+RETURN VALUES]{
6418N/A [+0?for NO]
6418N/A [+1?for YES]
6418N/A}
6418N/A[+SEE ALSO?\bdisplay_msg()\b]
6418N/A\n\n\aprompt\a \adefault\a [\ahelpTag\a]
6418N/A'
6418N/Afunction get_confirm {
6418N/A typeset _ANSWER=''
6418N/A
6418N/A if [[ -z $2 ]]; then
6418N/A Log.fatal "INTERNAL ERROR: ${.sh.fun} requires 2 args, 3rd is optional"
6418N/A exit 2
6418N/A fi
6418N/A
6418N/A while : ; do
6418N/A read _ANSWER?"$1 [$2] "
6418N/A [[ -z ${_ANSWER} ]] && _ANSWER="$2"
6418N/A
6418N/A case "${_ANSWER}" in
6418N/A [Yy] | yes | Yes | YES) return 1 ;;
6418N/A [Nn] | no | No | NO) return 0 ;;
6418N/A [Hh?] | help | Help) display_msg ${3:-sorry} ;;
6418N/A * ) Log.warn 'Please enter y or n' ;;
6418N/A esac
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc get_confirm_nodef '' '[+NAME?get_confirm_nodef - Get confirmation from the user.]
6418N/A[+DESCRIPTION?Read a string from stdin until it matches Y|y|Yes|yes|YES|N|n|No|no|NO. No default value and help tag supported. Arguments:]
6418N/A{
6418N/A [+prompt?instruction/comment/description/question to show.]
6418N/A}
6418N/A[+RETURN VALUES]{
6418N/A [+0?for NO]
6418N/A [+1?for YES]
6418N/A}
6418N/A\n\n[\aprompt\a]...
6418N/A'
6418N/Afunction get_confirm_nodef {
6418N/A typeset _ANSWER=''
6418N/A
6418N/A while : ; do
6418N/A read _ANSWER?"$@ "
6418N/A case "${_ANSWER}" in
6418N/A [Yy] | yes | Yes | YES) return 1 ;;
6418N/A [Nn] | no | No | NO) return 0 ;;
6418N/A * ) Log.warn 'Please enter y or n' ;;
6418N/A esac
6418N/A done
6418N/A}
6418N/A############################################################################
6418N/A# End of basic [menu] stuff
6418N/A############################################################################
6418N/A
6418N/A
6418N/A######################################################################
6418N/A# FUNCTIONS FOR prompt_config_info() START HERE.
6418N/A######################################################################
6418N/AMan.addFunc get_ids_server '' '[+NAME?get_ids_server - Prompt for DS server name.]
6418N/A[+DESCRIPTION?Ask the user for the DS hostname, store it into \bSTR[DS_HOST]]\b and adjusts \bCON_ARGS\b.]
6418N/A[+ENVIRONMENT VARIABLES]{'"${ Man.varUsage CON_ARGS ; }"'}
6418N/A[+SEE ALSO?\bget_ans()\b, \bget_ids_port()\b, \bping\b(1M).]
6418N/A'
6418N/Afunction get_ids_server {
6418N/A typeset SRV="${STR[DS_HOST]}"
6418N/A typeset OS=${ uname -s ; }
6418N/A
6418N/A while : ; do
6418N/A get_ans "Enter the Directory Server's hostname to setup:" \
6418N/A "${STR[DS_HOST]}"
6418N/A SRV="${ANS}"
6418N/A
6418N/A # Ping server to see if alive. If reachable break out of loop
6418N/A if [[ ${OS} == 'SunOS' ]]; then
6418N/A ${PING} "${SRV}" 3 >/dev/null 2>&1 && break
6418N/A else
6418N/A # assume Linux
6418N/A ${PING} -W 3 "${SRV}" >/dev/null 2>&1 && break
6418N/A fi
6418N/A Log.warn "Server '${SRV}' is invalid or unreachable"
6418N/A done
6418N/A STR[DS_HOST]="${SRV}"
6418N/A
6418N/A # Set CON_ARGS since values might have changed
6418N/A CON_ARGS="-h ${SRV} -p ${INT[DS_PORT]}"
6418N/A}
6418N/A
6418N/AMan.addFunc get_ids_port '' '[+NAME?get_ids_port - Prompt for DS port number.]
6418N/A[+DESCRIPTION?Ask the user for the DS port number and host, store it into \bINT[DS_PORT]]\b, \bSTR[DS_HOST]]\b and adjust \bCON_ARGS\b.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage CON_ARGS ; }" '}
6418N/A[+SEE ALSO?\bget_number()\b, \bget_ids_server()\b, \bldapsearch\b(1).]
6418N/A\n\n\aarg\a'
6418N/Afunction get_ids_port {
6418N/A typeset ASK='Enter the port number for the directory server (h=help):'
6418N/A typeset HELP='port_help' KEY='DS_PORT'
6418N/A
6418N/A integer PORT
6418N/A while : ; do
6418N/A # Enter port number
6418N/A get_number "${ASK}" ${INT[${KEY}]} "${HELP}"
6418N/A PORT=${ANS}
6418N/A # Do a simple search to check hostname and LDAP port number
6418N/A if [[ -z $1 ]]; then
6418N/A if ${LDAPSEARCH} -h ${STR[DS_HOST]} -p ${PORT} -b '' \
6418N/A -s base 'objectclass=*' > /dev/null 2>&1
6418N/A then
6418N/A break
6418N/A fi
6418N/A Log.warn "Invalid host or port '${STR[DS_HOST]}:${PORT}'"
6418N/A get_ids_server
6418N/A else
6418N/A break
6418N/A fi
6418N/A done
6418N/A INT[${KEY}]=${PORT}
6418N/A [[ -n $1 ]] && return
6418N/A
6418N/A # Set CON_ARGS since values might have changed
6418N/A CON_ARGS="-h ${STR[DS_HOST]} -p ${PORT}"
6418N/A}
6418N/A
6418N/AMan.addFunc chk_ids_version '' '[+NAME?chk_ids_version - Read the DS version info.]
6418N/A[+DESCRIPTION?Query the DS for version info and store it into \bTMP[DS_INFO]]\b as "ProductName MajorVersionNum MinorVersionNum". If the DS is OpenDS or OpenDJ \bTMPF[IS_OPENDJ]]\b gets set to 1, 0 otherwise. If the DS seems to be unsupported by this script, an appropriate message gets stored into \bTMP[WARN]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?on fatal error (got no info).]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1).]
6418N/A'
6418N/Afunction chk_ids_version {
6418N/A typeset PROD='' X LINE
6418N/A typeset -a SPLIT=( )
6418N/A integer MAJOR=0 MINOR=0
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b cn=monitor -s base 'objectclass=*' \
6418N/A 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A if [[ ${LINE:0:14} == 'vendorVersion=' ]]; then
6418N/A # OpenD*
6418N/A X=${LINE:14}
6418N/A X=${X//Directory Server } # usually <= 2.3.x
6418N/A PROD=${X%% *}
6418N/A SPLIT=( ${.sh.match//./ } )
6418N/A MAJOR=${SPLIT[0]}
6418N/A MINOR=${SPLIT[1]}
6418N/A break
6418N/A elif [[ ${LINE:0:8} == 'version=' ]]; then
6418N/A # *DSEE
6418N/A X=${LINE:8}
6418N/A PROD=${X%%/*}
6418N/A X=${.sh.match#/}
6418N/A SPLIT=( ${X//./ } )
6418N/A MAJOR=${SPLIT[0]}
6418N/A MINOR=${SPLIT[1]}
6418N/A break
6418N/A fi
6418N/A done
6418N/A if [[ -z ${PROD} ]] || (( MAJOR == 0 )); then
6418N/A Log.fatal 'Can not determine the version number of the DS'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A TMP[DS_INFO]="${PROD} ${MAJOR} ${MINOR}"
6418N/A
6418N/A # for easier maintainance we don't put it into a single expr
6418N/A X=''
6418N/A if [[ ${PROD} == 'OpenDS' || ${PROD} == 'OpenDJ' ]]; then
6418N/A TMPF[IS_OPENDJ]=1
6418N/A (( MAJOR < 2 )) && X='1'
6418N/A elif (( MAJOR < 5 || (7 < MAJOR && MAJOR < 11) )); then
6418N/A # not a supported DSEE version
6418N/A TMPF[IS_OPENDJ]=0
6418N/A X='1'
6418N/A fi
6418N/A if [[ -n ${X} ]]; then
6418N/A TMP[WARN]="$PROG only works with DSEE version 5.x, 6.x, 7.x, "
6418N/A TMP[WARN]+='ODSEE 11g and OpenDS/OpenDJ 2.x'
6418N/A Log.warn "${TMP[WARN]}"
6418N/A fi
6418N/A Log.printMarker
6418N/A Log.info "Detected DS: ${PROD} ${MAJOR}.${MINOR}"
6418N/A Log.printMarker
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_dirmgr_dn '' '[+NAME?get_dirmgr_dn - get the directory manger DN.]
6418N/A[+DESCRIPTION?Ask the user for the directory manger DN and store it into \bSTR[LDAP_ROOTDN]]\b and adjust \bAUTH_ARGS\b.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage AUTH_ARGS ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b.]
6418N/A'
6418N/Afunction get_dirmgr_dn {
6418N/A get_ans 'Enter the directory manager DN:' "${STR[LDAP_ROOTDN]}"
6418N/A STR[LDAP_ROOTDN]="${ANS}"
6418N/A AUTH_ARGS=( '-D' "${STR[LDAP_ROOTDN]}" '-j' "${TMP[LDAP_ROOTPWF]}" )
6418N/A}
6418N/A
6418N/AMan.addFunc get_dirmgr_pw '' '[+NAME?get_dirmgr_pw - get the Root DN password.]
6418N/A[+DESCRIPTION?Ask the user for the Root DN (\bSTR[LDAP_ROOTDN]]\b), store it into \bSTR[LDAP_ROOTPWD]]\b as well as a temp file for later use. Finally adjust \bAUTH_ARGS\b and check, whether the changes work.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage AUTH_ARGS ; }" '}
6418N/A[+SEE ALSO?\bget_passwd_nochk()\b, \bsave_password()\b, \bldapsearch\b(1).]
6418N/A'
6418N/Afunction get_dirmgr_pw {
6418N/A typeset RES
6418N/A
6418N/A while : ; do
6418N/A get_passwd_nochk "Enter passwd for ${STR[LDAP_ROOTDN]} :"
6418N/A STR[LDAP_ROOTPWD]="${ANS}" # stored for create_config_file(), only
6418N/A save_password
6418N/A AUTH_ARGS=( '-D' "${STR[LDAP_ROOTDN]}" '-j' "${TMP[LDAP_ROOTPWF]}" )
6418N/A
6418N/A # Verify that ROOTDN and ROOTPWD are valid
6418N/A RES=${ ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b '' -s base 'objectclass=*' supportedLDAPVersion 2>&1 ; }
6418N/A (( $? == 0 )) && break # Both are valid.
6418N/A
6418N/A if [[ ${RES} =~ (credential|no password) ]]; then
6418N/A Log.warn 'Password for Root DN is invalid'
6418N/A else
6418N/A Log.warn "Root DN '${STR[LDAP_ROOTDN]}' is invalid"
6418N/A get_dirmgr_dn
6418N/A fi
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc get_domain '' '[+NAME?get_domain - Ask user for domain to be served.]
6418N/A[+DESCRIPTION?Ask the user for the Domain that will be served by the LDAP server and store it into \bSTR[LDAP_DOMAIN]]\b.]
6418N/A[+SEE ALSO?\bget_ans()\b.]
6418N/A'
6418N/Afunction get_domain {
6418N/A while : ; do
6418N/A get_ans 'Enter the domainname to be served (h=help):' \
6418N/A "${STR[LDAP_DOMAIN]}"
6418N/A case "${ANS}" in
6418N/A [Hh?] | help | Help) display_msg 'domain_help' ; continue ;;
6418N/A esac
6418N/A # check, whether it has at least 2 dot separated components
6418N/A [[ ${ANS} =~ [^.]+\.[^.]+ ]] && break
6418N/A Log.warn "Invalid domainname '${ANS}'"
6418N/A done
6418N/A STR[LDAP_DOMAIN]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc getDSobjectclasses '' '[+NAME?getDSobjectclasses - get all DS schema objectclasses.]
6418N/A[+DESCRIPTION?Fetch all objectclasses definitions of the DS via \bcn=schema\b and cache them into \bOID2ODEF\b. Once successfully fetched, this function does nothing but return 0.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>0?failed to retrieve attribute definitions.]
6418N/A}
6418N/A'
6418N/Afunction getDSobjectclasses {
6418N/A (( ${#OID2ODEF[@]} )) && return 0
6418N/A
6418N/A typeset AT OID NAME TAIL
6418N/A set -o pipefail
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b cn=schema -s base 'objectclass=*' \
6418N/A objectclasses 2>/dev/null | \
6418N/A while read AT OID NAME TAIL ; do
6418N/A [[ ${AT} != 'objectclasses=(' ]] && continue
6418N/A TAIL=${TAIL%%+( )$')'};
6418N/A OID2ODEF["${OID}"]="${TAIL}"
6418N/A : # always return 0
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc getDSattributes '' '[+NAME?getDSattributes - get all DS schema attributes.]
6418N/A[+DESCRIPTION?Fetch all attribute definitions of the DS via \bcn=schema\b and cache them into \bOID2ADEF\b. Also populate the hash map \bANAME2OID\b for all the attributes definied. Once successfully fetched, this function does nothing but return 0.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>0?failed to retrieve attribute definitions.]
6418N/A}
6418N/A'
6418N/Afunction getDSattributes {
6418N/A (( ${#ANAME2OID[@]} )) && return 0
6418N/A
6418N/A typeset AT OID NAME TAIL
6418N/A typeset -l ALIAS
6418N/A set -o pipefail
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b cn=schema -s base 'objectclass=*' \
6418N/A attributeTypes 2>/dev/null | \
6418N/A while read AT OID NAME TAIL ; do
6418N/A [[ ${AT} != 'attributeTypes=(' ]] && continue
6418N/A TAIL=${TAIL%%+( )$')'};
6418N/A OID2ADEF["${OID}"]="${TAIL}"
6418N/A # 'name'
6418N/A if [[ ${TAIL:0:1} == "'" ]]; then
6418N/A NAME=${TAIL:1}
6418N/A ALIAS=${NAME%%"'"*}
6418N/A ANAME2OID["${ALIAS}"]="${OID}"
6418N/A continue
6418N/A fi
6418N/A # ( 'name' 'name 1' ... )
6418N/A NAME=${TAIL%%$')'*}
6418N/A NAME=${NAME##$'('*([[:space:]])}
6418N/A while [[ ${NAME} == ~(E)"'"([^"'"]+)"'" ]]; do
6418N/A ALIAS=${.sh.match[1]}
6418N/A ANAME2OID["${ALIAS}"]="${OID}"
6418N/A NAME=${NAME:${#ALIAS}+2}
6418N/A NAME=${NAME#*([[:space:]])}
6418N/A done
6418N/A : # always return 0
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc check_attrName '' '[+NAME?check_attrName - validate an attribute name.]
6418N/A[+DESCRIPTION?Check that \akey\a is a valid attribute name.]
6418N/A[+RETURN VALUES]{
6418N/A [0?key is a valid name.]
6418N/A [1?key is a invalid name.]
6418N/A [66?failed to fetch attribute definitions from server.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1).]
6418N/A\n\n\akey\a
6418N/A'
6418N/Afunction check_attrName {
6418N/A typeset KEY=$1
6418N/A
6418N/A if ! getDSattributes ; then
6418N/A Log.fatal 'Unable to fetch attribute definitions from server'
6418N/A return 66
6418N/A fi
6418N/A [[ -z ${KEY} ]] && return 1
6418N/A if [[ ${KEY} =~ ^[0-9]+(\.[0-9]+)*$ ]]; then
6418N/A # OID value
6418N/A [[ -n ${OID2ADEF[${KEY}]} ]] && return 0
6418N/A else
6418N/A # symbol. name
6418N/A KEY=${ANAME2OID[${KEY}]}
6418N/A # if have a mapping, than we also have a definition for it - no need
6418N/A # to double check
6418N/A [[ -n ${KEY} ]] && return 0
6418N/A fi
6418N/A return 1
6418N/A}
6418N/A
6418N/AMan.addFunc check_baseDN '' '[+NAME?check_baseDN - check validity of the baseDN name.]
6418N/A[+DESCRIPTION?Check that \abaseDN\a is a valid base DN.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?baseDN is a valid.]
6418N/A [+>= 1?baseDN is a invalid.]
6418N/A}
6418N/A[+SEE ALSO?\bcheck_attrName()\b.]
6418N/A[+NOTES?This function does not catch all invalid DNs. Its purpose is to reduce the number of invalid DNs to get past the input routine. The invalid DNs will be caught by the LDAP server when they are attempted to be created.]
6418N/A\n\n\abaseDN\a
6418N/A'
6418N/Afunction check_baseDN {
6418N/A # NOTE: we preserve spaces! And try to report all errors instead of just one
6418N/A Log.info 'Checking LDAP Base DN ...'
6418N/A [[ -z $1 ]] && return 0
6418N/A
6418N/A # NOTE: when fancy debug via trap is enabled, splitting via IFS does not
6418N/A # work: IFS=',' PAIRS=( $1 ) - so we do it manually
6418N/A
6418N/A typeset PAIR KEY VAL TAIL="${1},"
6418N/A typeset -A UNIQ_KEYS=( ) # avoid repeated lookup of the same attrName
6418N/A integer ERR=0
6418N/A while [[ -n ${TAIL} ]]; do
6418N/A TAIL=${TAIL#*,}
6418N/A PAIR=${.sh.match%,}
6418N/A VAL=${PAIR#*=}
6418N/A KEY=${.sh.match%=}
6418N/A if [[ -z ${KEY} || -z ${VAL} ]]; then
6418N/A Log.warn "Invalid key=value pair '${PAIR}'"
6418N/A (( ERR++ ))
6418N/A continue
6418N/A fi
6418N/A UNIQ_KEYS[${KEY}]=1
6418N/A done
6418N/A
6418N/A for KEY in "${!UNIQ_KEYS[@]}" ; do
6418N/A if ! check_attrName "${KEY}" ; then
6418N/A Log.warn "Unknown attribute name '${KEY}'"
6418N/A fi
6418N/A done
6418N/A return ${ERR}
6418N/A}
6418N/A
6418N/AMan.addFunc discover_serv_suffix '' '[+NAME?discover_serv_suffix - query the DS to find suffixes available.]
6418N/A[+DESCRIPTION?Query the DS to find suffixes available. All suffixes found are stored into the variable \avname\a which must be an indexed array.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?at least one suffix was found.]
6418N/A [+1?no suffix found.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1).]
6418N/A\n\n\avname\a
6418N/A'
6418N/Afunction discover_serv_suffix {
6418N/A typeset LINE
6418N/A integer NUM_TOP=0
6418N/A typeset -n DST=$1
6418N/A DST=( ); unset DST[0]
6418N/A
6418N/A # Search the server for the TOP of the TREE. Usually none for virgin DS
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b '' -s base 'objectclass=*' namingContexts \
6418N/A 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A if [[ -n ${LINE} && ${LINE} != ~(Ei)NetscapeRoot ]]; then
6418N/A (( NUM_TOP++ ))
6418N/A DST+=( "${LINE#*=}\n" ) # strip off '^namingContexts='
6418N/A fi
6418N/A done
6418N/A
6418N/A if (( NUM_TOP == 0 )); then
6418N/A Log.verbose 'No suffix found in LDAP tree'
6418N/A return 1
6418N/A fi
6418N/A
6418N/A Log.verbose "LDAP_SUFFIX_LIST = ${DST[@]}"
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_backend '' '[+NAME?get_backend - get the relevant database backend for the Base DN.]
6418N/A[+DESCRIPTION?Get the relevant database backend name for the Base DN and store it into \bSTR[DS_DB]]\b.]
6418N/A[+?Prerequisite: \bSTR[LDAP_BASEDN]]\b must be set and valid.]
6418N/A[+?backend is retrieved from suffixes and subsuffixes defined under "cn=mapping tree,cn=config". The nsslapd-state attribute of these suffixes entries is filled with either Backend, Disabled or referrals related values. We only want those that have a true backend database to select the relevant backend.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?an fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1).]
6418N/A'
6418N/Afunction get_backend {
6418N/A typeset CUR_DN=${STR[LDAP_BASEDN]} PREV_DN='' FILTER
6418N/A
6418N/A while [[ ${CUR_DN} != ${PREV_DN} ]]; do
6418N/A typeset -a DB=( )
6418N/A Log.verbose "Testing LDAP suffix: ${CUR_DN} ..."
6418N/A
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A FILTER='(&(&(objectclass=ds-cfg-backend)(ds-cfg-base-dn='"${CUR_DN}"
6418N/A FILTER+='))(objectClass=ds-cfg-local-db-backend))'
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b 'cn=Backends,cn=config' -s one "${FILTER}" 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A [[ ${LINE:0:18} == 'ds-cfg-backend-id=' && \
6418N/A ${LINE: -10} != ',cn=config' ]] && DB+=( "${LINE:18}" )
6418N/A done
6418N/A else
6418N/A
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "cn=${CUR_DN},cn=mapping tree,cn=config" \
6418N/A -s base 'nsslapd-state=Backend' 'nsslapd-backend' 2>/dev/null |\
6418N/A while read LINE ; do
6418N/A [[ ${LINE:0:16} == 'nsslapd-backend=' ]] && DB+=( "${LINE:16}" )
6418N/A done
6418N/A fi
6418N/A
6418N/A if (( ${#DB[@]} == 0 )); then
6418N/A # not a suffix, or suffix not activated; try next
6418N/A PREV_DN=${CUR_DN}
6418N/A CUR_DN="${CUR_DN#*,}"
6418N/A elif (( ${#DB[@]} == 1 )); then
6418N/A break
6418N/A else
6418N/A Log.fatal "More than one database is configured for '${CUR_DN}'!" \
6418N/A "$PROG can not configure suffixes where" \
6418N/A 'more than one database is used for one suffix'
6418N/A return 66
6418N/A fi
6418N/A done
6418N/A
6418N/A if (( ${#DB[@]} == 0 )); then
6418N/A # should not happen, since STR[LDAP_BASEDN] is supposed to be valid
6418N/A Log.fatal "Could not find a valid backend for '${STR[LDAP_BASEDN]}'"
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A Log.fatal 'Check the "Creating a New Database Backend" section in the Administration Guide'
6418N/A fi
6418N/A return 67
6418N/A fi
6418N/A STR[DS_DB]="${DB[0]}"
6418N/A
6418N/A Log.verbose "DB backend '${STR[DS_DB]}' selected"
6418N/A
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc normalizeDN '' '[+NAME?normalizeDN - normalize a [relative]] distinguished name.]
6418N/A[+DESCRIPTION?Strip off unnecessary spaces around \b,\b and \b=\b as well as at the beginning and end of the given \adn\a, optionally convert it to lower or upper case (if either \bl\b or \bu\b is given) and print it to stdout.]
6418N/A\n\n\adn\a [\bl\b|\bu\b]
6418N/A'
6418N/Afunction normalizeDN {
6418N/A [[ -z $1 ]] && return
6418N/A typeset VAL=",${1},"
6418N/A VAL="${VAL//*( ),*( )/,}"
6418N/A VAL="${VAL//*( )=*( )/=}"
6418N/A if [[ $2 == 'l' ]]; then
6418N/A typeset -l LC="${VAL}"
6418N/A VAL="${LC}"
6418N/A elif [[ $2 == 'u' ]]; then
6418N/A typeset -u UC="${VAL}"
6418N/A VAL="${UC}"
6418N/A fi
6418N/A print -- "${VAL:1:${#VAL}-2}"
6418N/A}
6418N/A
6418N/AMan.addFunc check_basedn_suffix '' '[+NAME?check_basedn_suffix - check that there is an existing valid suffix to hold current base DN.]
6418N/A[+DESCRIPTION?Check that there is an existing valid suffix for \bSTR[LDAP_BASEDN]]\b. If one is found, store it into \bSTR[LDAP_SUFFIX]]\b and make a corresponding backend check.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?valid suffix found or new one should be created (\bTMPF[NEED_CREATE_SUFFIX]]\b flag actually indicates that).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bdiscover_serv_suffix()\b, \bldapsearch\b(1), \bnormalizeDN()\b, \bget_backend()\b.]
6418N/A'
6418N/Afunction check_basedn_suffix {
6418N/A Log.info 'Validating LDAP Base DN and Suffix ...'
6418N/A TMPF[NEED_CREATE_SUFFIX]=0
6418N/A
6418N/A # check that LDAP Base DN might be added
6418N/A typeset CUR_DN="${STR[LDAP_BASEDN]}" PREV_DN=''
6418N/A
6418N/A while [[ ${CUR_DN} != ${PREV_DN} ]]; do
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b "${CUR_DN}" -s one 'objectclass=*' \
6418N/A >/dev/null 2>&1 && break
6418N/A PREV_DN=${CUR_DN}
6418N/A CUR_DN="${CUR_DN#*,}" # remove leading component
6418N/A done
6418N/A
6418N/A if [[ ${CUR_DN} == ${PREV_DN} ]]; then
6418N/A Log.info "No valid suffixes were found for Base DN '${STR[LDAP_BASEDN]}'"
6418N/A TMPF[NEED_CREATE_SUFFIX]=1
6418N/A return 0
6418N/A fi
6418N/A
6418N/A # find out existing suffixes
6418N/A typeset -a SUFFIXES=( )
6418N/A discover_serv_suffix SUFFIXES
6418N/A
6418N/A # Now looking for relevant suffix for this entry (using lower case - LC).
6418N/A # STR[LDAP_SUFFIX] will then be used to add necessary base objects via
6418N/A # add_base_objects().
6418N/A typeset LC_DN=,${ normalizeDN "${CUR_DN}" l ; }
6418N/A typeset SFX LC_SFX
6418N/A for SFX in "${SUFFIXES[@]}" ; do
6418N/A Log.verbose "Testing suffix: ${SFX} ..."
6418N/A # LC_DN ends with ,SFX ?
6418N/A LC_SFX=,${ normalizeDN "${SFX}" l ; }
6418N/A if [[ ${LC_DN: -${#LC_SFX}} == ${LC_SFX} ]]; then
6418N/A STR[LDAP_SUFFIX]="${SFX}"
6418N/A break
6418N/A fi
6418N/A done
6418N/A
6418N/A if [[ -z ${STR[LDAP_SUFFIX]} ]]; then
6418N/A # should not happen, since we found the entry
6418N/A Log.fatal "Could not find a valid suffix for '${STR[LDAP_BASEDN]}'"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A # Getting relevant database (backend)
6418N/A # DS_DB will then be used to create indexes.
6418N/A get_backend || return 67
6418N/A
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_objectclass '' '[+NAME?get_objectclass - get the objectclass for the given attribute name.]
6418N/A[+DESCRIPTION?Get the objectclass for the given attribute name \aattrName\a and print it to stdout. Right now ou, dc, o, and c and related aliases/OIDs are supported, only. For all others nothing will be printed.]
6418N/A[+NOTES?An attribute name can be valid but still we might not be able to determine the objectclass from the table. In such cases, the user needs to create the necessary object(s).]
6418N/A\n\n\aattrName\a
6418N/A'
6418N/Afunction get_objectclass {
6418N/A typeset -l ANAME="$1"
6418N/A
6418N/A case "${ANAME}" in
6418N/A ou | organizationalunitname | 2.5.4.11)
6418N/A print 'organizationalUnit'
6418N/A ;;
6418N/A dc | domaincomponent | 0.9.2342.19200300.100.1.25)
6418N/A print 'domain'
6418N/A ;;
6418N/A o | organizationname | 2.5.4.10)
6418N/A print 'organization'
6418N/A ;;
6418N/A c | countryname | 2.5.4.6)
6418N/A print 'country'
6418N/A ;;
6418N/A esac
6418N/A}
6418N/A
6418N/Afunction checkSuffixRDN {
6418N/A typeset RDN="${STR[LDAP_SUFFIX]%%,*}"
6418N/A TMP[SUFFIX_VAL]="${RDN#*=}"
6418N/A TMP[SUFFIX_ATT]="${.sh.match%=}"
6418N/A
6418N/A # find out an objectclass for suffix entry if it is not defined yet
6418N/A TMP[SUFFIX_OBJ]=${ get_objectclass "${TMP[SUFFIX_ATT]}" ; }
6418N/A if [[ -z ${TMP[SUFFIX_OBJ]} ]]; then
6418N/A Log.fatal 'Unable to find an objectclass for' "'${TMP[SUFFIX_ATT]}'" \
6418N/A 'attribute'
6418N/A return 1
6418N/A fi
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc prep_create_sfx_entry '' '[+NAME?prep_create_sfx_entry - prepare for the suffix entry creation.]
6418N/A[+DESCRIPTION?Prepare suffix entry creation based on \bSTR[LDAP_BASEDN|LDAP_SUFFIX]]\b and \bTMP[SUFFIX_OBJ]]\b. If the latter are unset (no config file read), set them to defaults depending on the baseDN. Finally check, whether the suffix entry already exists and if so check for consistency with the current config. This function sets:]{
6418N/A [+TMPF[NEED_CREATE_BACKEND]]?0 .. backend already exists. 1 .. create a backend.]
6418N/A [+TMP[SUFFIX_ATT]]?The attribute name of the leading RDN of the suffix (ID).]
6418N/A [+TMP[SUFFIX_VAL]]?The attribute value of the leading RDN of the suffix (ID).]
6418N/A}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+1?an attribute/consistence related error occured.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bnormalizeDN()\b, \bdisplay_msg()\b, \badd_suffix()\b, \bldapsearch\b(1)]
6418N/A'
6418N/Afunction prep_create_sfx_entry {
6418N/A # check whether suffix corresponds to base dn (i.e. baseDN ends with suffix)
6418N/A typeset X=,${ normalizeDN "${STR[LDAP_BASEDN]}" l ; }
6418N/A typeset SFX=,${STR[LDAP_SUFFIX]}
6418N/A if [[ ${X: -${#SFX}} != ${SFX} ]]; then
6418N/A Log.warn "Sorry, suffix '${STR[LDAP_SUFFIX]}' is not suitable for" \
6418N/A "Base DN '${STR[LDAP_BASEDN]}'"
6418N/A return 1
6418N/A fi
6418N/A
6418N/A checkSuffixRDN || return 66
6418N/A Log.verbose "Suffix entry object: '${TMP[SUFFIX_OBJ]}'"
6418N/A
6418N/A TMPF[NEED_CREATE_BACKEND]=0
6418N/A
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A # 1st just check, whether any backend matches the suffix
6418N/A typeset FILTER='(&(objectClass=ds-cfg-local-db-backend)'
6418N/A FILTER+="(|(ds-cfg-base-dn=${STR[LDAP_SUFFIX]})"
6418N/A FILTER+="(ds-cfg-base-dn=*,${STR[LDAP_SUFFIX]})))"
6418N/A X=${ ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b 'cn=Backends,cn=config' -s one "${FILTER}" 2>/dev/null ; }
6418N/A if [[ -n ${X} ]]; then
6418N/A Log.verbose 'Suffix backend already exists'
6418N/A get_backend || return 66
6418N/A return 0
6418N/A fi
6418N/A else
6418N/A # DSEE: check the suffix mapping tree ...
6418N/A # If mapping exists, suffix should work, otherwise DSEE inconsistent
6418N/A # NOTE: -b 'cn=mapping tree,cn=config' -s one 'cn=\"$1\"' won't work
6418N/A # in case of 'cn' value in LDAP is not quoted by '"',
6418N/A # -b 'cn=\"$1\",cn=mapping tree,cn=config' works in all cases
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "cn=\"${STR[LDAP_SUFFIX]}\",cn=mapping tree,cn=config" \
6418N/A -s base 'objectclass=*' dn 2>/dev/null
6418N/A then
6418N/A Log.verbose 'Suffix mapping already exists'
6418N/A get_backend || return 66
6418N/A return 0
6418N/A fi
6418N/A
6418N/A # no suffix mapping, just in case check ldbm backends consistency -
6418N/A # there are must be NO any databases pointing to STR[LDAP_SUFFIX]
6418N/A X=${ ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b 'cn=ldbm database,cn=plugins,cn=config' \
6418N/A -s one "nsslapd-suffix=${STR[LDAP_SUFFIX]}" dn 2>/dev/null ; }
6418N/A if [[ -n ${X} ]]; then
6418N/A Log.warn 'Sorry, there is no suffix mapping for' \
6418N/A "'${STR[LDAP_SUFFIX]}', while ldbm database exists, server" \
6418N/A 'configuration needs to be fixed manually, look at cn=mapping' \
6418N/A 'tree,cn=config and cn=ldbm database,cn=plugins,cn=config'
6418N/A return 1
6418N/A fi
6418N/A fi
6418N/A
6418N/A Log.verbose 'Backend needs to be created ...'
6418N/A TMPF[NEED_CREATE_BACKEND]=1
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc prep_create_sfx_backend '' '[+NAME?prep_create_sfx_backend - prepare for the suffix backend creation.]
6418N/A[+DESCRIPTION?Prepare for the suffix backend creation by checking available DBs starting with \bSTR[DS_DB]]\b. Sets \bTMP[DS_DB_AVAIL]]\b if not yet set or != \bSTR[DS_DB]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?backend db name is ok.]
6418N/A [+1?\bSTR[DS_DB]]\b exists, so \bTMP[DS_DB_AVAIL]]\b contains available name.]
6418N/A [+2?unable to find any available name.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1).]
6418N/A'
6418N/Afunction prep_create_sfx_backend {
6418N/A # check if requested name available
6418N/A [[ ${STR[DS_DB]} == ${TMP[DS_DBS_AVAIL]} ]] && return 0
6418N/A
6418N/A # get the list of database names start with a requested name
6418N/A typeset -a DBS=( )
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A typeset FILTER='(&(objectclass=ds-cfg-local-db-backend)'
6418N/A FILTER+="(ds-cfg-backend-id=${STR[DS_DB]}*))"
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b 'cn=Backends,cn=config' -s one "${FILTER}" ds-cfg-backend-id \
6418N/A 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A [[ -n ${LINE} && ${LINE: -10} != ',cn=config' ]] && \
6418N/A DBS+=( "${LINE#ds-cfg-backend-id=}" )
6418N/A done
6418N/A else
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b 'cn=ldbm database,cn=plugins,cn=config' \
6418N/A -s one "cn=${STR[DS_DB]}*" cn 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A [[ -n ${LINE} && ${LINE: -10} != ',cn=config' ]] && \
6418N/A DBS+=( "${LINE#cn=}" )
6418N/A done
6418N/A fi
6418N/A if (( ${#DBS[@]} == 0 )); then
6418N/A # no backend name starts with STR[DS_DB]
6418N/A TMP[DS_DBS_AVAIL]="${STR[DS_DB]}"
6418N/A return 0
6418N/A fi
6418N/A
6418N/A # find a non-existing db name based on a requested name
6418N/A integer I FOUND
6418N/A typeset -l NAME DB
6418N/A for (( I=0 ; I < 10; I++ )); do
6418N/A (( I )) && NAME="${STR[DS_DB]}${I}" || NAME="${STR[DS_DB]}"
6418N/A FOUND=0
6418N/A for DB in "${DBS[@]}" ; do
6418N/A [[ ${DB} == ${NAME} ]] && FOUND=1 && break
6418N/A done
6418N/A if (( ! FOUND )); then
6418N/A if (( I == 0 )); then
6418N/A TMP[DS_DBS_AVAIL]="${STR[DS_DB]}"
6418N/A return 0 # requested name is available
6418N/A fi
6418N/A TMP[DS_DBS_AVAIL]="${STR[DS_DB]}${I}"
6418N/A break
6418N/A fi
6418N/A done
6418N/A
6418N/A if [[ -n ${TMP[DS_DBS_AVAIL]} ]]; then
6418N/A Log.warn "Database backend '${STR[DS_DB]}' already exists," \
6418N/A "however '${TMP[DS_DBS_AVAIL]}' is available"
6418N/A return 1
6418N/A fi
6418N/A
6418N/A Log.warn 'Unable to find any available database backend close to' \
6418N/A "'${STR[DS_DB]}'"
6418N/A return 2
6418N/A}
6418N/A
6418N/AMan.addFunc get_suffix '' '[+NAME?get_suffix - Ask user for suffix and related backend.]
6418N/A[+DESCRIPTION?Ask the user for the suffix (default: \bSTR[LDAP_BASEDN]]\b) to create and the db name if it does not yet exist. \bTMP[DS_DBS_AVAIL]]\b gets set to the given db name (if any), \bSTR[DS_DB]]\b to the prepared db name and \bSTR[LDAP_SUFFIX]]\b to the given suffix.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (user gave a correct suffix).]
6418N/A [+1?unable to create suffix given by user.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bget_ans()\b, \bdisplay_msg()\b, \bnormalizeDN()\b, \bprep_create_sfx_entry()\b, \bprep_create_sfx_backend()\b.]
6418N/A'
6418N/Afunction get_suffix {
6418N/A while : ; do
6418N/A get_ans 'Enter suffix to be created (b=back/h=help):' \
6418N/A "${STR[LDAP_BASEDN]}"
6418N/A case "${ANS}" in
6418N/A [Hh?] | Help | help)
6418N/A display_msg 'create_suffix_help'
6418N/A continue
6418N/A ;;
6418N/A [Bb] | '<' | Back | back)
6418N/A return 1
6418N/A ;;
6418N/A esac
6418N/A STR[LDAP_SUFFIX]=${ normalizeDN "${ANS}" l ; }
6418N/A prep_create_sfx_entry
6418N/A integer REDO=$?
6418N/A (( REDO >= 66 )) && return 66
6418N/A (( REDO )) && continue
6418N/A
6418N/A if (( TMPF[NEED_CREATE_BACKEND] )); then
6418N/A TMP[DS_DBS_AVAIL]='' # reset the available db name
6418N/A REDO=0
6418N/A while : ; do
6418N/A X=${TMP[DS_DBS_AVAIL]}
6418N/A # Basically for OpenDJ we could use 'userRoot' as default aka
6418N/A # TMP[SUFFIX_VAL], however, users may use it for trying out
6418N/A # examples from the docs
6418N/A get_ans 'Enter local database backend name (b=back/h=help):' \
6418N/A "${X:-${TMP[SUFFIX_VAL]}}"
6418N/A case "${ANS}" in
6418N/A [Hh?])
6418N/A display_msg 'enter_ldbm_db_help'
6418N/A continue
6418N/A ;;
6418N/A [Bb] | '<')
6418N/A REDO=1
6418N/A break
6418N/A ;;
6418N/A esac
6418N/A STR[DS_DB]="${ANS}"
6418N/A prep_create_sfx_backend && break
6418N/A done
6418N/A
6418N/A (( REDO )) && continue
6418N/A
6418N/A Log.verbose 'Databse backend name for suffix ${STR[LDAP_SUFFIX]}:' \
6418N/A "${DS_DB}"
6418N/A fi
6418N/A # eventually everything is prepared
6418N/A break
6418N/A done
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc domain_2_dc '' '[+NAME?domain_2_dc - Convert a domain name into dc string.]
6418N/A[+DESCRIPTION?Convert a domain name \adomain\a into a dc=...,dc=... string and print it to stdout.]
6418N/A\n\n\adomain\a
6418N/A'
6418N/Afunction domain_2_dc {
6418N/A [[ -z $1 ]] && return
6418N/A typeset DC='' SD
6418N/A for SD in ${1//./ } ; do # removes leading && trailing && double dots
6418N/A DC+=",dc=${SD}"
6418N/A done
6418N/A print -- "${DC:1}"
6418N/A}
6418N/A
6418N/AMan.addFunc get_basedn '' '[+NAME?get_basedn - Ask user for Base DN.]
6418N/A[+DESCRIPTION?Ask the user for the BaseDN to use, check whether to create a suffix and store the value into \bSTR[LDAP_BASEDN]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bget_ans_req()\b, \bdisplay_msg()\b, \bcheck_baseDN()\b, \bcheck_basedn_suffix()\b, \bget_suffix()\b.]
6418N/A'
6418N/Afunction get_basedn {
6418N/A typeset BASEDN=${ domain_2_dc ${STR[LDAP_DOMAIN]} ; }
6418N/A integer RES
6418N/A
6418N/A while : ; do
6418N/A # Get Base DN.
6418N/A while : ; do
6418N/A get_ans_req 'Enter LDAP Base DN (h=help):' "${BASEDN}"
6418N/A case "${ANS}" in
6418N/A [Hh?] | help | Help) display_msg 'basedn_help' ; continue ;;
6418N/A esac
6418N/A check_baseDN "${ANS}" && break
6418N/A Log.warn "Invalid base DN: '${ANS}'"
6418N/A done
6418N/A
6418N/A # Set base DN and check its suffix
6418N/A STR[LDAP_BASEDN]="${ANS}"
6418N/A check_basedn_suffix || return 66
6418N/A
6418N/A # suffix may need to be created, in that case get suffix from user
6418N/A if (( TMPF[NEED_CREATE_SUFFIX] )); then
6418N/A get_suffix
6418N/A RES=$?
6418N/A (( RES >= 66 )) && return 67
6418N/A (( RES )) && continue
6418N/A fi
6418N/A
6418N/A # suffix is ok, break out of the base dn inquire loop
6418N/A break
6418N/A done
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc chk_vlv_indexes '' '[+NAME?chk_vlv_indexes - check if server supports VLV.]
6418N/A[+DESCRIPTION?Checks, whether the DS supports Virtual List Views (VLV).]
6418N/A[+RETURN VALUES]{
6418N/A [+0?if VLVs are supported.]
6418N/A [+>= 66?if VLVs are not supported.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1).]
6418N/A'
6418N/Afunction chk_vlv_indexes {
6418N/A typeset ATTR=''
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b '' -s base 'objectclass=*' \
6418N/A supportedControl 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A if [[ ${LINE#*=} == '2.16.840.1.113730.3.4.9' ]]; then
6418N/A ATTR=${.sh.match%=}
6418N/A break
6418N/A fi
6418N/A done
6418N/A if [[ -z ${ATTR} ]]; then
6419N/A if (( TMPF[IS_OPENDJ] )); then
6419N/A # If the BDB backend is not yet loaded, related controls are not
6419N/A # shown. Because we know, that it supports VLVs we just check, that
6419N/A # this is true (no BDB configured/enabled)
6419N/A ATTR=${ ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6419N/A -b 'cn=Backends,cn=config' -s sub \
6419N/A '(&(objectclass=ds-cfg-local-db-backend)(ds-cfg-enabled=true))';
6419N/A }
6419N/A [[ -z ${ATTR} ]] && return 0
6419N/A fi
6418N/A Log.fatal 'VLV is not supported on LDAP server'
6418N/A return 66
6418N/A fi
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc validate_suffix '' '[+NAME?validate_suffix - validate suffix obtained via config file.]
6418N/A[+DESCRIPTION?This function validates STR[LDAP_SUFFIX]] AFTER THE LOAD OF A CONFIG FILE (should not be used for interactive use). Also does a consistency check wrt. \bSTR[LDAP_BASEDN]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bnormalizeDN()\b, \bldapsearch\b(1), \bprep_create_sfx_entry()\b, \bprep_create_sfx_backend()\b.]
6418N/A'
6418N/Afunction validate_suffix {
6418N/A # Check STR[LDAP_SUFFIX] is not null
6418N/A if [[ -z ${STR[LDAP_SUFFIX]} ]]; then
6418N/A Log.fatal 'Invalid suffix (null suffix)'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A # STR[LDAP_SUFFIX] and STR[LDAP_BASEDN] are consistent ?
6418N/A typeset X=,${ normalizeDN "${STR[LDAP_BASEDN]}" l ; }
6418N/A typeset SFX=,${ normalizeDN "${STR[LDAP_SUFFIX]}" l ; }
6418N/A if [[ ${X: -${#SFX}} != ${SFX} ]]; then
6418N/A Log.fatal "Invalid suffix '${SFX}' for Base DN '${X}'"
6418N/A return 67
6418N/A fi
6418N/A
6418N/A # STR[LDAP_SUFFIX] does exist ?
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${STR[LDAP_SUFFIX]}" \
6418N/A -s base 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A checkSuffixRDN && return 0 || return 68
6418N/A fi
6418N/A
6418N/A # Well, suffix does not exist, try to prepare create it ...
6418N/A TMPF[NEED_CREATE_SUFFIX]=1
6418N/A prep_create_sfx_entry || return 69
6418N/A if (( TMPF[NEED_CREATE_BACKEND] )); then
6418N/A if [[ -z ${STR[DS_DB]} ]]; then
6418N/A Log.fatal 'Database backend name is not set. Either set SIN[DS_DB]'\
6418N/A 'in the input file to a valid, i.e. non-existing DB name, or' \
6418N/A 'create the backend with the default DS tools'
6418N/A return 70
6418N/A fi
6418N/A # too risky, even if a available backend name could be found
6418N/A prep_create_sfx_backend || return 71
6418N/A fi
6418N/A
6418N/A Log.verbose "Suffix: '${STR[LDAP_SUFFIX]}' Database: '${STR[DS_DB]}'"
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc validate_info '' '[+NAME?validate_info - validate basic info obtained via config file.]
6418N/A[+DESCRIPTION?This function updates \bCON_ARGS\b as well as \bAUTH_ARGS\b, checks, whether they work so that some problems are caught right away AFTER THE LOAD OF A CONFIG FILE (should not be used for interactive use). It also validates the obtained suffix and whether the DS supports VLVs.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bchk_vlv_indexes()\b, \bvalidate_suffix()\b.]
6418N/A'
6418N/Afunction validate_info {
6418N/A # Set CON_ARGS and AUTH_ARGS for the config file.
6418N/A CON_ARGS="-h ${STR[DS_HOST]} -p ${INT[DS_PORT]}"
6418N/A AUTH_ARGS=( '-D' "${STR[LDAP_ROOTDN]}" '-j' "${TMP[LDAP_ROOTPWF]}" )
6418N/A chk_ids_version || return 1 # Check DSEE version for compatibility
6418N/A
6418N/A # Check the Root DN and Root DN passwd.o Same as for get_dirmgr_pw()
6418N/A RES=${ ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b '' -s base \
6418N/A 'objectclass=*' supportedLDAPVersion 2>&1 ; }
6418N/A if (( $? )); then
6418N/A if [[ ${RES} =~ credential ]]; then
6418N/A Log.fatal 'Root DN passwd is invalid'
6418N/A else
6418N/A Log.fatal "Invalid Root DN '${STR[LDAP_ROOTDN]}'"
6418N/A fi
6418N/A return 66
6418N/A fi
6418N/A Log.verbose 'RootDN: ok RootDN passwd: ok'
6418N/A
6418N/A # Check if the server supports the VLV
6418N/A chk_vlv_indexes || return 67
6418N/A Log.verbose 'VLV indexes ... ok'
6418N/A
6418N/A # Check LDAP suffix
6418N/A validate_suffix || return 66
6418N/A Log.verbose 'LDAP suffix ... ok'
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc gssapi_setup '' '[+NAME?gssapi_setup - set up GSSAPI if necessary.]
6418N/A[+DESCRIPTION?Check, whether the DS supports the SASL mechanism \bGSSAPI\b. If so, ask the user whether it should be enabled and depending on the answer ask for related Kerberos realm info. \bINT[GSSAPI_ENABLE]]\b and \bTMPF[GSSAPI_AUTH_MAY_BE_USED]]\b and optionally \bSTR[LDAP_KRB_REALM]]\b are set accordingly.]
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bget_ans_req()\b.]
6418N/A'
6418N/Afunction gssapi_setup {
6418N/A INT[GSSAPI_ENABLE]=0
6418N/A TMPF[GSSAPI_AUTH_MAY_BE_USED]=0
6418N/A
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b '' -s base 'objectclass=*' \
6418N/A supportedSASLMechanisms 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A if [[ ${LINE:0:24} == 'supportedSASLMechanisms=' && \
6418N/A ${LINE:24} == 'GSSAPI' ]]
6418N/A then
6418N/A TMPF[GSSAPI_AUTH_MAY_BE_USED]=1
6418N/A break
6418N/A fi
6418N/A done
6418N/A if (( ! TMPF[GSSAPI_AUTH_MAY_BE_USED] )); then
6418N/A Log.info 'sasl/GSSAPI is not supported by this LDAP server'
6418N/A return
6418N/A fi
6418N/A
6418N/A get_confirm 'GSSAPI is supported. Do you want to set up GSSAPI:(y/n)' 'n'
6418N/A if (( $? )); then
6418N/A INT[GSSAPI_ENABLE]=1
6418N/A # get kerberos realm
6418N/A typeset -u REALM=${STR[LDAP_DOMAIN]}
6418N/A get_ans_req "Enter Kerberos Realm:" "${REALM}"
6418N/A REALM="${ANS}" # make sure, it is upper case
6418N/A STR[LDAP_KRB_REALM]="${REALM}"
6418N/A else
6418N/A Log.info 'GSSAPI is not set up - ' \
6418N/A 'sasl/GSSAPI bind may not work if it is not set up first'
6418N/A fi
6418N/A}
6418N/A
6418N/AMan.addFunc get_profile_name '' '[+NAME?get_profile_name - Ask user for client profile name.]
6418N/A[+DESCRIPTION?Ask the user for the name of the client profile to create, check whether it already exists, and if so ask whether it should be overwritten. Sets \bSTR[LDAP_PROFILE_NAME]]\b, \bTMPF[DEL_OLD_PROFILE]]\b and if the user wants to just enable shadow update \bINT[LDAP_ENABLE_SHADOW_UPDATE]]\b and \bINT[EXISTING_PROFILE]]\b.]
6418N/A[+SEE ALSO?\bget_ans()\b, \bldapsearch\b(1), \bget_confirm()\b, \bget_confirm_nodef()\b, \bdisplay_msg()\b.]
6418N/A'
6418N/Afunction get_profile_name {
6418N/A TMPF[DEL_OLD_PROFILE]=0 # Reset since getting new profile name
6418N/A
6418N/A typeset PNAME="${STR[LDAP_PROFILE_NAME]}"
6418N/A # Loop until valid profile name, or replace.
6418N/A while : ; do
6418N/A get_ans 'Enter the client profile name (h=help):' "${PNAME}"
6418N/A case "${ANS}" in
6418N/A [Hh] | help | Help | '?') display_msg 'profile_help' ; continue ;;
6418N/A esac
6418N/A
6418N/A # Search to see if profile name already exists.
6418N/A if ! ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "cn=${ANS},ou=profile,${STR[LDAP_BASEDN]}" -s base \
6418N/A 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A break # Unique profile name (does not yet exist)
6418N/A fi
6418N/A
6418N/A Log.info 'Profile "'"${ANS}"'" already exists, it is possible to' \
6418N/A 'enable shadow update now.' "${PROG}" 'will exit after shadow' \
6418N/A 'update is enabled. You can also continue to overwrite the' \
6418N/A 'profile or create a new one and be given the chance to enable' \
6418N/A 'shadow update later.'
6418N/A
6418N/A get_confirm 'Just enable shadow update (y/n/h)?' 'n' \
6418N/A 'enable_shadow_update_help'
6418N/A if (( $? )); then
6418N/A # set up credentials for shadow update
6418N/A INT[LDAP_ENABLE_SHADOW_UPDATE]=1
6418N/A # display alternate messages
6418N/A INT[EXISTING_PROFILE]=1
6418N/A break
6418N/A fi
6418N/A
6418N/A get_confirm_nodef \
6418N/A "Are you sure you want to overwrite profile 'cn=${ANS}'?"
6418N/A if (( $? )); then
6418N/A TMPF[DEL_OLD_PROFILE]=1 # Replace old profile name
6418N/A break
6418N/A fi
6418N/A done
6418N/A
6418N/A STR[LDAP_PROFILE_NAME]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc getACIs '' '[+NAME?getACIs - get ACIs for the current base DN.]
6418N/A[+DESCRIPTION?Get all ACIs for \abaseDN\a and append them to the indexed array of strings \avname\a. If \abaseDN\a is not given, \bSTR[LDAP_BASEDN]]\b will be used instead. If \ascope\a is set to \bGlobal\b this method queries for "ds-cfg-global-aci" instead of "aci" unless \bTMPF[IS_OPENDJ]]\b is \b0\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+-1?invalid function usage.]
6418N/A [+0?on success.]
6418N/A [+1?an error occured when executing the ldapsearch operation.]
6418N/A}
6418N/A\n\n\avname\a [\abaseDN\a] [\ascope\a]
6418N/A'
6418N/Afunction getACIs {
6418N/A set -o pipefail # wanna have the exit code of ldapsearch
6418N/A [[ -z $1 ]] && Log.warn "${.sh.fun}(): invalid function usage" && \
6418N/A return -1
6418N/A typeset -n ACILIST=$1
6418N/A typeset LINE
6418N/A typeset DN="$2" ACI='aci'
6418N/A [[ -z ${DN} ]] && DN="${STR[LDAP_BASEDN]}"
6418N/A [[ $3 == 'Global' ]] && (( TMPF[IS_OPENDJ] )) && ACI='ds-cfg-global-aci'
6418N/A
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${DN}" -s base \
6418N/A 'objectclass=*' ${ACI} 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A # NOTE: the || : is required to always get success (pipe doesn't break)
6418N/A [[ ${LINE:0:${#ACI}+1} == "${ACI}=" ]] && \
6418N/A ACILIST+=( "${LINE:${#ACI}+1}" ) || :
6418N/A done
6418N/A if (( $? )); then
6418N/A Log.fatal "Unable to get aci list for '${STR[LDAP_BASEDN]}'"
6418N/A return 1
6418N/A fi
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc findACI '' '[+NAME?findACI - find an ACI in the given list.]
6418N/A[+DESCRIPTION?Find the first ACI which matches \aregex\a in the indexed array of ACIs \avname\a. If a match occurs, print out a message using the given \aaciName\a prefixed with \ascope\a. If \ascope\a is not given or empty, \bBaseDN\b will be used instead.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?no ACI matched.]
6418N/A [+>=1?the index+1 of the ACI matched.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bfindACI()\b, \bfind_and_delete_ACI\b()]
6418N/A\n\n\avname\a \aaciName\a \aregex\a [\ascope\a]
6418N/A'
6418N/Afunction findACI {
6418N/A typeset -n LIST=$1
6418N/A typeset NAME="$2" REGEX="$3" SCOPE="$4"
6418N/A integer MAX=${#LIST[@]} I
6418N/A [[ -z ${SCOPE} ]] && SCOPE='BaseDN'
6418N/A for (( I=0; I < MAX; I++ )); do
6418N/A if [[ ${LIST[${I}]} =~ ${REGEX} ]]; then
6418N/A showProgress "${SCOPE} ACI '${NAME}' exists."
6418N/A return $((I+1))
6418N/A fi
6418N/A done
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc allow_proxy_read_pw '' '[+NAME?allow_proxy_read_pw - add Proxy Agent read permission for password.]
6418N/A[+DESCRIPTION?Add the ACI \bPROXY_ACI_NAME\b for \bSTR[LDAP_PROXYAGENT]]\b to \bSTR[LDAP_BASEDN]]\b if it not already exists.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage PROXY_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (ACI already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction allow_proxy_read_pw {
6418N/A typeset ACI PATTERN TARGET
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A PATTERN='acl[ ]+"?('"${PROXY_ACI_NAME}|${PROXY_ACI_NAME// /_}"')"?'
6418N/A findACI LIST "${PROXY_ACI_NAME}" "${PATTERN}" || return 0
6418N/A
6418N/A PATTERN='userPassword'
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A PATTERN+=' || authPassword'
6418N/A # At least in OpenDJ specifying the same target as where the ACI gets
6418N/A # attached is redundant wrt. the result and causes minimal overhead
6418N/A TARGET=''
6418N/A else
6418N/A TARGET='(target = "ldap:///'"${STR[LDAP_BASEDN]}"'")'
6418N/A fi
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/Aaci: '"${TARGET}"'(targetattr = "'"${PATTERN}"'")
6418N/A (
6418N/A version 3.0; acl "'"${PROXY_ACI_NAME}"'";
6418N/A allow (compare,read,search) userdn = "ldap:///'"${STR[LDAP_PROXYAGENT]}"'";
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${PROXY_ACI_NAME}' ACI failed"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "ACI '${PROXY_ACI_NAME}' added."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc delete_proxy_read_pw '' '[+NAME?delete_proxy_read_pw - delete Proxy Agent read permission for password.]
6418N/A[+DESCRIPTION?Remove the ACI \bPROXY_ACI_NAME\b from \bSTR[LDAP_BASEDN]]\b if such an ACI exists.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage PROXY_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (no delete required or ACI deleted).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bget_menu_choice()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction delete_proxy_read_pw {
6418N/A typeset PROXY_ACI='' ACI PATTERN X
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A # Search for ACI_NAME - no findACI() because we need ALL matching ACIs
6418N/A typeset -a ACILIST=( )
6418N/A PATTERN='acl[ ]+"?('"${PROXY_ACI_NAME}|${PROXY_ACI_NAME// /_}"')"?'
6418N/A for ACI in "${LIST[@]}" ; do
6418N/A [[ ${ACI} =~ ${PATTERN} ]] && ACILIST+=( "${ACI#*=}" )
6418N/A done
6418N/A
6418N/A # We need to remove proxy agent's read access to user passwords,
6418N/A # but We do not know the value of the ${LDAP_PROXYAGENT} here, so
6418N/A # 1. if only one match found, delete it
6418N/A # 2. if more than one matches found, ask the user which one to delete
6418N/A if (( ${#ACILIST[@]} == 0 )); then
6418N/A Log.warn "ACI '${PROXY_ACI_NAME}' does not exist for" \
6418N/A "'${STR[LDAP_BASEDN]}'"
6418N/A return 0
6418N/A fi
6418N/A if (( ${#ACILIST[@]} == 1 ));then
6418N/A PROXY_ACI="${ACI[0]}"
6418N/A else
6418N/A X='
6418N/AProxy agent is not allowed to read user passwords when shadow
6418N/Aupdate is enabled. There are more than one proxy agents found.
6418N/APlease select the proxy agent currently being used, so that
6418N/A'"${PROG}"' can remove its read access to user passwords.
6418N/A
6418N/AThe proxy agents are:
6418N/A'
6418N/A # print the list of ACIs for selection
6418N/A integer I MAX
6418N/A MAX=${#ACILIST[@]}
6418N/A for (( I=0; I < MAX; I++ )) ; do
6418N/A ACI="${ACILIST[${I}]}"
6418N/A if (( ! Log.VERBOSE )); then
6418N/A # older versions used
6418N/A # sed -e 's|.*ldap:///.*ldap:///||' -e 's|";)||'
6418N/A ACI=${ACI##*ldap:///}
6418N/A ACI=${ACI%\"*}
6418N/A fi
6418N/A X+=${ printf '%2d: %s\n' $((I+1)) "${ACI}" ; }
6418N/A done
6418N/A Log.warn "${X}"
6418N/A
6418N/A # ask the user to pick one
6418N/A get_menu_choice "Select the proxy agent (1-${MAX}): " 1 ${MAX}
6418N/A I=$(( $? - 1 ))
6418N/A PROXY_ACI="${ACILIST[$I]}"
6418N/A fi
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Adelete: aci
6418N/Aaci: '"${PROXY_ACI}"'
6418N/A' >${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Remove of '${PROXY_ACI_NAME}' ACI failed"
6418N/A cat ${TMP[FILE]}
6418N/A return 66
6418N/A fi
6418N/A
6418N/A Log.info "Removed '${PROXY_ACI_NAME}' ACI"
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc allow_host_read_write_shadow '' '[+NAME?allow_host_read_write_shadow - add host principal read/write permission for shadow data.]
6418N/A[+DESCRIPTION?Add the ACI \bHOST_ACI_NAME\b to \bSTR[LDAP_BASEDN]]\b unless it already exists.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage HOST_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (ACI already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction allow_host_read_write_shadow {
6418N/A typeset ACI PATTERN TARGET=''
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A PATTERN='acl[ ]+"?('"${HOST_ACI_NAME}|${HOST_ACI_NAME// /_}"')"?'
6418N/A findACI LIST "${HOST_ACI_NAME}" "${PATTERN}" || return 0
6418N/A
6418N/A (( ! TMPF[IS_OPENDJ] )) && \
6418N/A TARGET='(target = "ldap:///'"${STR[LDAP_BASEDN]}"'")' # OD: redundant
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/Aaci: '"${TARGET}"'(targetattr = "shadowLastChange || shadowMin || shadowMax || shadowWarning || shadowInactive || shadowExpire || shadowFlag || userPassword || loginShell || homeDirectory || gecos")
6418N/A (
6418N/A version 3.0; acl '"${HOST_ACI_NAME}"';
6418N/A allow (write,compare,read,search) authmethod = "sasl GSSAPI" and userdn = "ldap:///cn=*+ipHostNumber=*,ou=Hosts,'"${STR[LDAP_BASEDN]}"';
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Remove of '${ACI_NAME}' ACI failed'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "ACI '${ACI_NAME}' added."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc find_and_delete_ACI '' '[+NAME?find_and_delete_ACI - find and delete an ACI in the given list.]
6418N/A[+DESCRIPTION?Find the first ACI which matches \aregex\a in the indexed array of ACIs \avname\a and delete it. If no ACI matches, the function does nothing and returns. Otherwise it tries to delete it from \bSTR[LDAP_BASEDN]]\b and prints out a message using \aaciName\a.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (no ACI matched or ACI removed successfully).]
6418N/A [+66?an error occured when removing the matched ACI.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bldapmodify\b(1)]
6418N/A\n\n\avname\a \aaciName\a \aregex\a
6418N/A'
6418N/Afunction find_and_delete_ACI {
6418N/A typeset -n LIST=$1
6418N/A typeset ACI_NAME="$2" REGEX="$3" DEL='' ACI
6418N/A
6418N/A for ACI in "${LIST[@]}" ; do
6418N/A [[ ${ACI} =~ ${REGEX} ]] && DEL="${ACI}" && break
6418N/A done
6418N/A [[ -z ${DEL} ]] && return 0
6418N/A
6418N/A nextFile modify "${0}-${ACI_NAME}"
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Adelete: aci
6418N/Aaci: '"${DEL}"'
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Remove of '${ACI_NAME}' ACI failed"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "ACI '${ACI_NAME}' deleted."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc deny_non_host_shadow_access '' '[+NAME?deny_non_host_shadow_access - add a deny non-host access to shadow data.]
6418N/A[+DESCRIPTION?Add the ACI \bNON_HOST_ACI_NAME\b to \bSTR[LDAP_BASEDN]]\b unless it already exists. If it does not exists the ACI \bNON_ADMIN_ACI_NAME\b gets deleted first if available.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage NON_HOST_ACI_NAME NON_ADMIN_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (ACI already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bfind_and_delete_ACI()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction deny_non_host_shadow_access {
6418N/A typeset ACI PATTERN TARGET=''
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A # If an ACI with ${NON_HOST_ACI_NAME} already exists, we are done
6418N/A PATTERN='acl[ ]+"?('"${NON_HOST_ACI_NAME}|${NON_HOST_ACI_NAME// /_}"')"?'
6418N/A findACI LIST "${NON_HOST_ACI_NAME}" "${PATTERN}" || return 0
6418N/A
6418N/A # The deny_non_admin_shadow_access and deny_non_host_shadow_access ACIs
6418N/A # should be mutually exclusive, so if the former exists, delete it
6418N/A PATTERN='acl[ ]+"?('"${NON_ADMIN_ACI_NAME}|${NON_ADMIN_ACI_NAME// /_}"')"?'
6418N/A find_and_delete_ACI LIST "${NON_ADMIN_ACI_NAME}" "${PATTERN}" || return 67
6418N/A
6418N/A (( ! TMPF[IS_OPENDJ] )) && \
6418N/A TARGET='(target = "ldap:///'"${STR[LDAP_BASEDN]}"'")' # OD: redundant
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/Aaci: '"${TARGET}"'(targetattr = "shadowLastChange || shadowMin || shadowMax ||shadowWarning || shadowInactive || shadowExpire || shadowFlag || userPassword")
6418N/A (
6418N/A version 3.0; acl "'"${NON_HOST_ACI_NAME}"'";
6418N/A deny (write,read,search,compare) userdn != "ldap:///cn=*+ipHostNumber=*,ou=Hosts,'"${STR[LDAP_BASEDN]}"'";
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding ACI '${NON_HOST_ACI_NAME}' failed"
6418N/A return 67
6418N/A fi
6418N/A
6418N/A showProgress "ACI '${NON_HOST_ACI_NAME}' added."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_adminDN '' '[+NAME?get_adminDN - ask user for Admin DN.]
6418N/A[+DESCRIPTION?Ask the user for the Admin DN and store it into \bSTR[LDAP_BASEDN]]\b.]
6418N/A[+SEE ALSO?\bget_ans()\b.]
6418N/A'
6418N/Afunction get_adminDN {
6418N/A get_ans 'Enter DN for the administrator:' \
6418N/A "cn=admin,ou=profile,${STR[LDAP_BASEDN]}"
6418N/A STR[LDAP_ADMINDN]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc get_admin_pw '' '[+NAME?get_admin_pw - ask user for Admin password]
6418N/A[+DESCRIPTION?Ask the user for the Admin password and store it into \bSTR[LDAP_ADMIN_CRED]]\b.]
6418N/A[+SEE ALSO?\bget_passwd()\b.]
6418N/A'
6418N/Afunction get_admin_pw {
6418N/A get_passwd 'Enter passwd for the administrator:'
6418N/A STR[LDAP_ADMIN_CRED]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc add_admin '' '[+NAME?add_admin - Add administrator identity.]
6418N/A[+DESCRIPTION?Add the \bSTR[LDAP_ADMINDN]]\b entry with the password \bSTR[LDAP_ADMIN_CRED]]\b unless it already exists.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (entry already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_admin {
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${STR[LDAP_ADMINDN]}" \
6418N/A -s base 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A showProgress "Administrator identity exists."
6418N/A return 0
6418N/A fi
6418N/A
6418N/A typeset CN="${STR[LDAP_ADMINDN]%%,*}"
6418N/A CN="${CN#*=}"
6418N/A
6418N/A nextFile add $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_ADMINDN]}"'
6418N/Acn: '"${CN}"'
6418N/Asn: '"${CN}"'
6418N/Aobjectclass: top
6418N/Aobjectclass: person
6418N/Auserpassword: '"${STR[LDAP_ADMIN_CRED]}"'
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Adding administrator identity failed'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress 'Administrator identity added.'
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc allow_admin_read_write_shadow '' '[+NAME?allow_admin_read_write_shadow - add Admin read/write permission for shadow, rbac and mount data.]
6418N/A[+DESCRIPTION?Add the ACI \bADMIN_ACI_NAME\b to \bSTR[LDAP_BASEDN]]\b unless it already exists. Also tries to remove old similar ACIs if they exist.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage ADMIN_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (aci already exists or addition was successfull).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bfind_and_delete_ACI()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction allow_admin_read_write_shadow {
6418N/A typeset PERMS='write,compare,read,search,add,delete' \
6418N/A ACI RBAC PATTERN TARGET=''
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A # If the ACI already exists, we are done
6418N/A PATTERN='acl[ ]+"?('"${ADMIN_ACI_NAME}|${ADMIN_ACI_NAME// /_}"')"?'
6418N/A PATTERN+='.*\('"${PERMS}"'\).*'"${STR[LDAP_ADMINDN]}"
6418N/A findACI LIST "${ADMIN_ACI_NAME}" "${PATTERN}" || return 0
6418N/A
6418N/A # If an ACI with ${ADMIN_ACI_NAME} and "(write|write,compare,read,search)"
6418N/A # and ${LDAP_ADMINDN} exists, delete it
6418N/A PATTERN='acl[ ]+"?('"${ADMIN_ACI_NAME}|${ADMIN_ACI_NAME// /_}"')"?'
6418N/A PATTERN+='.*\(write\).*'"${STR[LDAP_ADMINDN]}"
6418N/A find_and_delete_ACI LIST "${ADMIN_ACI_NAME}" "${PATTERN}" || return 67
6418N/A
6418N/A PATTERN='acl[ ]+"?('"${ADMIN_ACI_NAME}|${ADMIN_ACI_NAME// /_}"')"?'
6418N/A PATTERN+='.*\(write,compare,read,search\).*'"${STR[LDAP_ADMINDN]}"
6418N/A find_and_delete_ACI LIST "${ADMIN_ACI_NAME}" "${PATTERN}" || return 68
6418N/A
6418N/A RBAC='objectClass || uid || uidNumber || gidNumber || cn'
6418N/A RBAC+=' || SolarisAttrKeyValue || SolarisAttrShortDesc'
6418N/A RBAC+=' || SolarisAttrLongDesc || SolarisKernelSecurityPolicy'
6418N/A RBAC+=' || SolarisProfileType || SolarisProfileId || SolarisUserQualifier'
6418N/A RBAC+=' || SolarisReserved1 || SolarisReserved2'
6418N/A RBAC+=' || SolarisAttrReserved1 || SolarisAttrReserved2'
6418N/A RBAC+=' || SolarisProjectID || SolarisProjectName'
6418N/A RBAC+=' || SolarisProjectAttr || memberUid || memberGid || description'
6418N/A RBAC+=' || automountKey || automountMapName || automountInformation'
6418N/A RBAC+=' || ipTnetTemplateName || ipTnetNumber'
6418N/A
6418N/A (( ! TMPF[IS_OPENDJ] )) && \
6418N/A TARGET='(target = "ldap:///'"${STR[LDAP_BASEDN]}"'")' # OD: redundant
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/Aaci: '"${TARGET}"'(targetattr = "shadowLastChange || shadowMin || shadowMax || shadowWarning || shadowInactive || shadowExpire || shadowFlag || userPassword || loginShell || homeDirectory || gecos || '"${RBAC}"'")
6418N/A (
6418N/A version 3.0; acl "'${ADMIN_ACI_NAME}'";
6418N/A allow ('"${PERMS}"') userdn = "ldap:///'"${STR[LDAP_ADMINDN]}"'";
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${ADMIN_ACI_NAME}' ACI failed"
6418N/A return 69
6418N/A fi
6418N/A
6418N/A showProgress "ACI '${ADMIN_ACI_NAME}' added."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc deny_non_admin_shadow_access '' '[+NAME?deny_non_admin_shadow_access - add a deny Admin access to shadow data.]
6418N/A[+DESCRIPTION?Add the ACI \bNON_ADMIN_ACI_NAME\b to \bSTR[LDAP_BASEDN]]\b unless it already exists. If it does not exists the ACI \bNON_HOST_ACI_NAME\b gets deleted first if available.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage NON_ADMIN_ACI_NAME NON_HOST_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (ACI already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bfind_and_delete_ACI()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction deny_non_admin_shadow_access {
6418N/A typeset TARGET=''
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A # If the ACI already exists, we are done
6418N/A PATTERN='acl[ ]+"?('"${NON_ADMIN_ACI_NAME}|${NON_ADMIN_ACI_NAME// /_}"')"?'
6418N/A findACI LIST "${NON_ADMIN_ACI_NAME}" "${PATTERN}" || return 0
6418N/A
6418N/A # The deny_non_admin_shadow_access and deny_non_host_shadow_access ACIs
6418N/A # should be mutually exclusive, so if the latter exists, delete it
6418N/A PATTERN='acl[ ]+"?('"${NON_HOST_ACI_NAME}|${NON_HOST_ACI_NAME// /_}"')"?'
6418N/A find_and_delete_ACI LIST "${NON_HOST_ACI_NAME}" "${PATTERN}" || return 67
6418N/A
6418N/A (( ! TMPF[IS_OPENDJ] )) && \
6418N/A TARGET='(target = "ldap:///'"${STR[LDAP_BASEDN]}"'")' # OD: redundant
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/Aaci: '"${TARGET}"'(targetattr = "shadowLastChange || shadowMin || shadowMax || shadowWarning || shadowInactive || shadowExpire || shadowFlag || userPassword")
6418N/A (
6418N/A version 3.0; acl "'"${NON_ADMIN_ACI_NAME}"'";
6418N/A deny (write,read,search,compare,add,delete) userdn != "ldap:///'"${STR[LDAP_ADMINDN]}"'";
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${NON_ADMIN_ACI_NAME}' ACI failed"
6418N/A ${CAT} ${TMP[FILE]}
6418N/A return 68
6418N/A fi
6418N/A
6418N/A showProgress "ACI '${NON_ADMIN_ACI_NAME}' added."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc setup_shadow_update '' '[+NAME?setup_shadow_update - set up shadow update.]
6418N/A[+DESCRIPTION?Check whether the profile \bSTR[LDAP_PROFILE_NAME]]\b for \bSTR[LDAP_BASEDN]]\b exists. If not simply notify the user and return. Otherwise check whether the profile uses authenticationMethod "GSSAPI" and credentialLevel "self". If so ask the user whether to use host or "Admin" user principal for shadow updates and collect the related info. Sets \bINT[NEED_HOSTACL]]\b if the host principal should be used for shadow update (requires that \bTMPF[GSSAPI_AUTH_MAY_BE_USED]]\b is already set).]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66? a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bget_confirm()\b, \bdelete_proxy_read_pw()\b, \ballow_host_read_write_shadow()\b, \bdeny_non_host_shadow_access()\b, \bget_adminDN()\b, \bget_admin_pw()\b, \badd_admin()\b, \ballow_admin_read_write_shadow()\b, \bdeny_non_admin_shadow_access()\b.]
6418N/A'
6418N/Afunction setup_shadow_update {
6418N/A # get content of the profile
6418N/A integer CN=0 GSSAPI=0 SELF=0
6418N/A typeset -l LINE
6418N/A
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "cn=${STR[LDAP_PROFILE_NAME]},ou=profile,${STR[LDAP_BASEDN]}" \
6418N/A -s base 'objectclass=*' 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A [[ ${LINE:0:3} == 'cn=' ]] && CN=1
6418N/A [[ ${LINE:0:21} == 'authenticationmethod=' && ${LINE:21} == 'GSSAPI' ]]\
6418N/A && GSSAPI=1
6418N/A [[ ${LINE:0:16} == 'credentiallevel=' && ${LINE:16} == 'self' ]] \
6418N/A && SELF=1
6418N/A done
6418N/A if (( ! CN )); then
6418N/A Log.verbose "Profile '${STR[LDAP_PROFILE_NAME]}' does not exist"
6418N/A return 0
6418N/A fi
6418N/A
6418N/A # If authenticationMethod has 'GSSAPI' and credentialLevel
6418N/A # has 'self', ask to use the host principal for shadow update
6418N/A if (( TMPF[GSSAPI_AUTH_MAY_BE_USED] && GSSAPI && SELF )); then
6418N/A INT[NEED_HOSTACL]=1
6418N/A fi
6418N/A Log.verbose "NEED_HOSTACL = ${INT[NEED_HOSTACL]}"
6418N/A
6418N/A if (( INT[NEED_HOSTACL] )); then
6418N/A get_confirm 'Use host principal for shadow data update (y/n/h)?' 'y' \
6418N/A 'use_host_principal_help'
6418N/A if (( $? )); then
6418N/A delete_proxy_read_pw || return 66
6418N/A allow_host_read_write_shadow || return 67
6418N/A deny_non_host_shadow_access || return 68
6418N/A Log.info 'Shadow update has been enabled'
6418N/A else
6418N/A Log.warn 'Shadow update may not work'
6418N/A fi
6418N/A return 0
6418N/A fi
6418N/A
6418N/A get_confirm 'Add the administrator identity (y/n/h)?' 'y' \
6418N/A 'add_admin_cred_help'
6418N/A if (( $? )); then
6418N/A get_adminDN
6418N/A get_admin_pw
6418N/A add_admin || return 69
6418N/A delete_proxy_read_pw || return 66
6418N/A allow_admin_read_write_shadow || return 70
6418N/A deny_non_admin_shadow_access || return 71
6418N/A Log.info 'Shadow update has been enabled'
6418N/A else
6418N/A Log.warn 'No administrator identity specified, shadow update may not' \
6418N/A 'work'
6418N/A fi
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_srv_list '' '[+NAME?get_srv_list - Ask user for default server list.]
6418N/A[+DESCRIPTION?Ask the user for the default server list and store it into \bSTR[LDAP_SERVER_LIST]]\b.]
6418N/A[+SEE ALSO?\bget_ans()\b, \bdisplay_msg()\b.]
6418N/A'
6418N/Afunction get_srv_list {
6418N/A # If LDAP_SERVER_LIST is NULL, then set, otherwise leave alone
6418N/A if [[ -z ${STR[LDAP_SERVER_LIST]} ]]; then
6418N/A ANS=${ ${GETENT} hosts ${STR[DS_HOST]} ; }
6418N/A STR[LDAP_SERVER_LIST]=${ANS%%[[:space:]]*}
6418N/A if (( INT[DS_PORT] != 389 )); then
6418N/A STR[LDAP_SERVER_LIST]="${STR[LDAP_SERVER_LIST]}:${INT[DS_PORT]}"
6418N/A fi
6418N/A fi
6418N/A
6418N/A while : ; do
6418N/A get_ans 'Default server list (h=help):' "${STR[LDAP_SERVER_LIST]}"
6418N/A case "${ANS}" in
6418N/A [Hh] | help | Help | '?') display_msg 'def_srvlist_help' ;;
6418N/A * ) break ;;
6418N/A esac
6418N/A done
6418N/A STR[LDAP_SERVER_LIST]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc get_pref_srv '' '[+NAME?get_pref_srv - Ask user for preferred server list.]
6418N/A[+DESCRIPTION?Ask the user for the preferred server list and store it into \bSTR[LDAP_PREF_SRVLIST]]\b (overrides the server list).]
6418N/A[+SEE ALSO?\bget_ans()\b, \bdisplay_msg()\b.]
6418N/A'
6418N/Afunction get_pref_srv {
6418N/A while : ; do
6418N/A get_ans 'Preferred server list (h=help):' "${STR[LDAP_PREF_SRVLIST]}"
6418N/A case "${ANS}" in
6418N/A [Hh] | help | Help | '?') display_msg 'pref_srvlist_help' ;;
6418N/A * ) break ;;
6418N/A esac
6418N/A done
6418N/A STR[LDAP_PREF_SRVLIST]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc get_search_scope '' '[+NAME?get_search_scope - Ask user for search scope.]
6418N/A[+DESCRIPTION?Ask the user for the search scope and store it into \bSTR[LDAP_SEARCH_SCOPE]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+1?search scope "one" selected.]
6418N/A [+2?search scope "sub" selected.]
6418N/A}
6418N/A[+SEE ALSO?\bget_ans()\b, \bdisplay_msg()\b.]
6418N/A'
6418N/Afunction get_search_scope {
6418N/A integer RES
6418N/A get_menu_choice 'Choose desired search scope (1=one, 2=sub, h=help): ' \
6418N/A 1 2 1 srch_scope_help
6418N/A (( $? == 2 )) && { STR[LDAP_SEARCH_SCOPE]='sub' ; return 2 ; }
6418N/A STR[LDAP_SEARCH_SCOPE]='one'
6418N/A return 1
6418N/A}
6418N/A
6418N/AMan.addFunc get_cred_level '' '[+NAME?get_cred_level - Ask user for credential level.]
6418N/A[+DESCRIPTION?Ask the user for the client credential level to use and store it into \bSTR[LDAP_CRED_LEVEL]]\b.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage CRED_LEVELS STR ; }" '}
6418N/A[+RETURN VALUES?The index wrt. \bCRED_LEVELS\b of the selected credential level \b+1\b.]
6418N/A[+SEE ALSO?\bget_ans()\b, \bdisplay_msg()\b.]
6418N/A'
6418N/Afunction get_cred_level {
6418N/A integer RES
6418N/A typeset PROMPT=''
6418N/A (( INT[GSSAPI_ENABLE] )) && PROMPT='"self" is needed for GSSAPI profile.\n'
6418N/A PROMPT+='Choose Credential level (identity) [h=help]:'
6418N/A
6418N/A get_menu_choice "${PROMPT}" 1 4 1 'cred_lvl_help' 'cred_level_menu'
6418N/A RES=$?
6418N/A STR[LDAP_CRED_LEVEL]="${CRED_LEVELS[RES-1]}"
6418N/A return ${RES}
6418N/A}
6418N/A
6418N/AMan.addFunc get_auth '' '[+NAME?get_auth - ask user for authentication methods.]
6418N/A[+DESCRIPTION?Ask the user for authentication methods to enable and store them as a semicolon separated list into \bSTR[LDAP_AUTHMETHOD | LDAP_SRV_AUTHMETHOD_{PAM|KEY|CMD}}]]\b and set \bINT[NEED_SRVAUTH_{PAM|KEY|CMD}]]\b to 0 depending on the given \atype\a (either "client", "pam_ldap", "keyserv", or "passwd-cmd") and selected methods.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage AUTH_METHODS STR ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+-1?if an invalid \atype\a was given.]
6418N/A}
6418N/A[+SEE ALSO?\bget_menu_choice()\b, \bget_confirm_nodef()\b.]
6418N/A\n\n\atype\a
6418N/A'
6418N/Afunction get_auth {
6418N/A typeset TYPE=$1 VNAME HELPTAG MENU
6418N/A integer RES MAX=${#AUTH_METHODS[@]} OFFSET=0
6418N/A typeset -a SELECTED=( )
6418N/A typeset -u UTYPE=${TYPE}
6418N/A
6418N/A case "${TYPE}" in
6418N/A client) VNAME=LDAP_AUTHMETHOD ; OFFSET=1 ; UTYPE='DEFAULT' ;;
6418N/A pam_ldap) VNAME=LDAP_SRV_AUTHMETHOD_PAM ;;
6418N/A keyserv) VNAME=LDAP_SRV_AUTHMETHOD_KEY ;;
6418N/A passwd-cmd) VNAME=LDAP_SRV_AUTHMETHOD_CMD ;;
6418N/A *) print -u2 "${.sh.fun}() bug: invalid type argument" && return -1 ;;
6418N/A esac
6418N/A
6418N/A typeset ASK='' VAL='' M=''
6418N/A if (( OFFSET )); then
6418N/A # client
6418N/A (( INT[GSSAPI_ENABLE] )) && \
6418N/A ASK='"sasl/GSSAPI" is needed for GSSAPI profile.\n'
6418N/A ASK+='Choose DEFAULT authentication (bind) method (0=reset, h=help):'
6418N/A MENU='auth_method_menu'
6418N/A HELPTAG='auth_help'
6418N/A else
6418N/A ASK="Choose ${UTYPE} authentication (bind) method (0=reset, h=help):"
6418N/A (( MAX-- ))
6418N/A MENU='srvauth_method_menu'
6418N/A HELPTAG='srvauth_help'
6418N/A fi
6418N/A
6418N/A while : ; do
6418N/A get_menu_choice "${ASK}" 0 ${MAX} 1 ${HELPTAG} ${MENU}
6418N/A RES=$?
6418N/A if (( RES )); then
6418N/A M=${AUTH_METHODS[RES - OFFSET]}
6418N/A # avoid doubles
6418N/A [[ ${VAL} != ~(E)[ ]${M}[ ] ]] && SELECTED+=( ${M} )
6418N/A VAL=" ${SELECTED[@]} "
6418N/A M=${VAL// /\;}
6418N/A M=${M#\;}
6418N/A else
6418N/A typeset -a SELECTED=( ) # reset
6418N/A VAL=''
6418N/A M=''
6418N/A fi
6418N/A print && Log.info "Current authentication method(s): ${M%\;}\n"
6418N/A
6418N/A get_confirm_nodef "Do you want to add another ${UTYPE} authentication method (y/n)?" \
6418N/A && break
6418N/A done
6418N/A M=${M%\;}
6418N/A if (( ! OFFSET )); then
6418N/A M=${M//\;/\;${TYPE}:}
6418N/A if [[ -n ${M} ]]; then
6418N/A STR[${VNAME}]="${TYPE}:${M}"
6418N/A else
6418N/A STR[${VNAME}]=''
6418N/A INT[NEED_SRVAUTH_${TYPE##*_}]=0
6418N/A fi
6418N/A else
6418N/A STR[${VNAME}]="${M}"
6418N/A fi
6418N/A Log.verbose "Selected ${UTYPE} authentication methods: '${STR[${VNAME}]}'"
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_followref '' '[+NAME?get_followref - Ask user whether or not to follow referrals.]
6418N/A[+DESCRIPTION?Ask the user whether the client should follow referrals. Result gets stored into \bINT[LDAP_FOLLOWREF]]\b.]
6418N/A[+SEE ALSO?\bget_confirm()\b, \bldapclient\b(1M).]
6418N/A'
6418N/Afunction get_followref {
6418N/A get_confirm 'Do you want the clients to follow referrals (y/n/h)?' 'n' \
6418N/A 'referrals_help'
6418N/A INT[LDAP_FOLLOWREF]=$?
6418N/A}
6418N/A
6418N/AMan.addFunc get_timelimit '' '[+NAME?get_timelimit - Ask user for search time limit.]
6418N/A[+DESCRIPTION?Ask the user for the max. time allowed to process a search operation and store it into \bINT[DS_TIMELIMIT]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bis_numeric()\b, \bget_negone_num()\b.]
6418N/A'
6418N/Afunction get_timelimit {
6418N/A typeset NAME='nsslapd-timelimit' VAL=''
6418N/A (( TMPF[IS_OPENDJ] )) && NAME='ds-cfg-time-limit' # min val = 0
6418N/A
6418N/A # Get current timeout value from cn=config
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b 'cn=config' -s base \
6418N/A 'objectclass=*' "${NAME}" 2>/dev/null | \
6418N/A while read LINE; do
6418N/A if [[ ${LINE%%=*} == ${NAME} ]]; then
6418N/A VAL=${LINE#*=}
6418N/A break
6418N/A fi
6418N/A done
6418N/A if [[ -z ${VAL} ]]; then
6418N/A Log.fatal 'Unable to check current search processing timeout of the DS'
6418N/A return 66
6418N/A fi
6418N/A VAL=${VAL%%[[:space:]]*}
6418N/A is_numeric ${VAL} && NUM=${VAL} || NUM=INT[DS_TIMELIMIT]
6418N/A
6418N/A get_negone_num "Enter the DS search processing time limit in seconds (current=${NUM})" \
6418N/A '30'
6418N/A (( TMPF[IS_OPENDJ] && NUM < 0 )) && NUM=0 # unlimited
6418N/A
6418N/A INT[DS_TIMELIMIT]=${NUM}
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_sizelimit '' '[+NAME?get_sizelimit - Ask user for search size limit.]
6418N/A[+DESCRIPTION?Ask the user for the max. number of entries to return for a single search operation and store it into \bINT[DS_SIZELIMIT]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bis_numeric()\b, \bget_negone_num()\b.]
6418N/A'
6418N/Afunction get_sizelimit {
6418N/A typeset NAME='nsslapd-sizelimit' VAL=''
6418N/A (( TMPF[IS_OPENDJ] )) && NAME='ds-cfg-size-limit' # min val = 0
6418N/A
6418N/A # Get current search sizelimit
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b 'cn=config' -s base \
6418N/A 'objectclass=*' "${NAME}" 2>/dev/null | \
6418N/A while read LINE; do
6418N/A if [[ ${LINE%%=*} == ${NAME} ]]; then
6418N/A VAL=${LINE#*=}
6418N/A break
6418N/A fi
6418N/A done
6418N/A if [[ -z ${VAL} ]]; then
6418N/A Log.fatal 'Unable to check current search entry result limit of the DS'
6418N/A return 66
6418N/A fi
6418N/A is_numeric ${VAL} && NUM=${VAL} || NUM=INT[DS_SIZELIMIT]
6418N/A
6418N/A get_negone_num "Enter max. entries per search the DS returns (current=${NUM})" '1000'
6418N/A (( TMPF[IS_OPENDJ] && NUM < 0 )) && NUM=0 # unlimited
6418N/A INT[DS_SIZELIMIT]=${NUM}
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc get_want_crypt '' '[+NAME?get_want_crypt - Ask user whether to store passwords in crypt.]
6418N/A[+DESCRIPTION?Ask the user whether the default password storage scheme should be set to "CRYPT" and stores the result into \bINT[NEED_CRYPT]]\b.]
6418N/A[+SEE ALSO?\bget_confirm()\b.]
6418N/A'
6418N/Afunction get_want_crypt {
6418N/A get_confirm 'Do you want to store passwords in "CRYPT" formats (y/n/h)?' \
6418N/A 'n' 'crypt_help'
6418N/A INT[NEED_CRYPT]=$?
6418N/A}
6418N/A
6418N/AMan.addFunc get_srch_time '' '[+NAME?get_srch_time - Ask user for client search time limit.]
6418N/A[+DESCRIPTION?Ask the user for the max. time in seconds a client waits for a search result and store it into \bINT[LDAP_SEARCH_TIME_LIMIT]]\b.]
6418N/A[+SEE ALSO?\bget_negone_num()\b, \bldapclient\b(1M).]
6418N/A'
6418N/Afunction get_srch_time {
6418N/A get_negone_num 'Client search time limit in seconds (h=help):' \
6418N/A ${INT[LDAP_SEARCH_TIME_LIMIT]} 'srchtime_help'
6418N/A INT[LDAP_SEARCH_TIME_LIMIT]=${NUM}
6418N/A}
6418N/A
6418N/AMan.addFunc get_prof_ttl '' '[+NAME?get_prof_ttl - Ask user for client profile time to live (TTL).]
6418N/A[+DESCRIPTION?Ask the user for the max. time in seconds a client may cache its profile before refreshing again and store it into \bINT[LDAP_PROFILE_TTL]]\b.]
6418N/A[+SEE ALSO?\bget_negone_num()\b, \bldapclient\b(1M).]
6418N/A'
6418N/Afunction get_prof_ttl {
6418N/A get_negone_num 'Client Profile Time To Live in seconds (h=help):' \
6418N/A ${INT[LDAP_PROFILE_TTL]} 'profttl_help'
6418N/A INT[LDAP_PROFILE_TTL]=${NUM}
6418N/A}
6418N/A
6418N/AMan.addFunc get_bind_limit '' '[+NAME?get_bind_limit - Ask user for client bind time limit.]
6418N/A[+DESCRIPTION?Ask the user for the max. time in seconds a client may try to bind to the server and store it into \bINT[LDAP_BIND_LIMIT]]\b.]
6418N/A[+SEE ALSO?\bget_negone_num()\b, \bldapclient\b(1M).]
6418N/A'
6418N/Afunction get_bind_limit {
6418N/A get_negone_num 'Client bind time limit in seconds (h=help):' \
6418N/A ${INT[LDAP_BIND_LIMIT]} 'bindlim_help'
6418N/A INT[LDAP_BIND_LIMIT]=${NUM}
6418N/A}
6418N/A
6418N/AMan.addFunc get_want_shadow_update '' '[+NAME?get_want_shadow_update - Ask user whether to enable shadow update.]
6418N/A[+DESCRIPTION?Ask the user whether to enable shadow update. Set \bINT[LDAP_ENABLE_SHADOW_UPDATE]]\b to 0 if not desired, to 1 otherwise.]
6418N/A[+SEE ALSO?\bget_confirm()\b.]
6418N/A'
6418N/Afunction get_want_shadow_update {
6418N/A get_confirm 'Do you want to enable shadow update (y/n/h)?' 'n' \
6418N/A 'enable_shadow_update_help'
6418N/A INT[LDAP_ENABLE_SHADOW_UPDATE]=$?
6418N/A}
6418N/A
6418N/A ######################################################################
6418N/A # FUNCTIONS FOR Service Search Descriptor's START HERE.
6418N/A ######################################################################
6418N/AMan.addFunc add_ssd '' '[+NAME?add_ssd - Ask user for SSD to add.]
6418N/A[+DESCRIPTION?Ask the user for the ID:BASE:SCOPE and add it to \bSSD\b list.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage SSD ; }" '}
6418N/A[+SEE ALSO?\bget_ans\b, \bget_ans_req()\b.]
6418N/A'
6418N/Afunction add_ssd {
6418N/A typeset ID='' BASE='' X
6418N/A typeset -l SCOPE=''
6418N/A integer FOUND
6418N/A
6418N/A while : ; do
6418N/A get_ans 'Enter the service name (e.g. passwd):'
6418N/A [[ -z ${ANS} ]] && return
6418N/A [[ ${ANS} =~ [:] ]] && print 'Invalid service name' && continue
6418N/A
6418N/A FOUND=0
6418N/A for X in "${SSD[@]}" ; do
6418N/A [[ ${X%%:*} == ${ANS} ]] && FOUND=1 && break
6418N/A done
6418N/A (( ! FOUND )) && break
6418N/A Log.warn "An SSD for '${ANS}' already exists:\n${X}\n"
6418N/A done
6418N/A ID="${ANS}"
6418N/A
6418N/A while : ; do
6418N/A get_ans_req 'Enter the search base (e.g. ou=people,o=inet):'
6418N/A [[ ${ANS} != ~(E)[:] ]] && break
6418N/A Log.warn 'Invalid search base' && continue
6418N/A done
6418N/A BASE="${ANS}"
6418N/A
6418N/A while : ; do
6418N/A get_ans_req "Enter the search scope (one|sub):"
6418N/A SCOPE=${ANS}
6418N/A [[ ${SCOPE} == 'one' || ${SCOPE} == 'sub' ]] && break
6418N/A Log.warn "'${ANS}' is NOT valid - Enter 'one' or 'sub'"
6418N/A done
6418N/A
6418N/A SSD+=( "${ID}:${BASE}?${SCOPE}" )
6418N/A}
6418N/A
6418N/AMan.addFunc delete_ssd '' '[+NAME?delete_ssd - Ask user which SSD to delete.]
6418N/A[+DESCRIPTION?Ask the user for the ID of the SSD to delete and remove it from \bSSD\b list.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage SSD ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b.]
6418N/A'
6418N/Afunction delete_ssd {
6418N/A get_ans 'Enter the service name of the SSD to delete (e.g. passwd):'
6418N/A [[ -z ${ANS} ]] && return
6418N/A
6418N/A typeset X
6418N/A integer I FOUND=-1 MAX=${#SSD[@]}
6418N/A
6418N/A for (( I=0; I < MAX ; I++ )); do
6418N/A X=${SSD[I]}
6418N/A [[ ${X%%:*} == ${ANS} ]] && FOUND=$I && break
6418N/A done
6418N/A if (( FOUND == -1 )); then
6418N/A Log.warn "Invalid service name: '${ANS}' not present in list"
6418N/A return
6418N/A fi
6418N/A (( FOUND == 0 )) && unset SSD[0] && return
6418N/A
6418N/A # need to do a little bit more, since ksh allows to remove the 1st entry,
6418N/A # only (i.e. like "shift 1" for positional params)
6418N/A for (( I=FOUND; I > 0; I-- )); do
6418N/A SSD[${I}]="${SSD[I-1]}"
6418N/A done
6418N/A unset SSD[0]
6418N/A}
6418N/A
6418N/AMan.addFunc modify_ssd '' '[+NAME?modify_ssd - Allow user to modify an SSD.]
6418N/A[+DESCRIPTION?Ask the user for the ID of the SSD to modify, let the user modify it and finally save changes back to the \bSSD\b list.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage SSD ; }" '}
6418N/A[+SEE ALSO?\bget_ans()\b, \bread\b(1).]
6418N/A'
6418N/Afunction modify_ssd {
6418N/A get_ans 'Enter the service name of the SSD to modify:'
6418N/A [[ -z ${ANS} ]] && return
6418N/A
6418N/A typeset ID BASE
6418N/A typeset -l SCOPE
6418N/A integer I FOUND=-1 MAX=${#SSD[@]}
6418N/A for (( I=0; I < MAX ; I++ )); do
6418N/A X=${SSD[I]}
6418N/A [[ ${X%%:*} == ${ANS} ]] && FOUND=$I && break
6418N/A done
6418N/A if (( FOUND == -1 )); then
6418N/A Log.warn "Invalid service name: '${ANS}'"
6418N/A return 0
6418N/A fi
6418N/A
6418N/A # most users expect emacs edit behavior (don't have a proper profile)
6418N/A set -o emacs
6418N/A read -v X?'Current SSD: '
6418N/A
6418N/A # now verify
6418N/A ID=${X%%:*}
6418N/A BASE=${.sh.match#:}
6418N/A SCOPE=${BASE#*$'?'}
6418N/A BASE=${.sh.match%$'?'}
6418N/A if [[ -z ${ID} || -z ${BASE} || -z ${SCOPE} ]] || \
6418N/A [[ ${SCOPE} != 'one' && ${SCOPE} != 'sub' ]]
6418N/A then
6418N/A Log.warn 'SSD is invalid. Change skipped'
6418N/A return
6418N/A fi
6418N/A SSD[${FOUND}]="${ID}:${BASE}?${SCOPE}"
6418N/A}
6418N/A
6418N/AMan.addFunc reset_ssd '' '[+NAME?reset_ssd - Blank out current list of SSDs.]
6418N/A[+DESCRIPTION?Clear the \bSSD\b array.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage SSD ; }" '}
6418N/A'
6418N/Afunction reset_ssd {
6418N/A SSD=( )
6418N/A unset SSD[0] # required otherwise it would contain a single '\n'. Bug?
6418N/A}
6418N/A
6418N/AMan.addFunc display_ssd '' '[+NAME?display_ssd - Display current SSD list.]
6418N/A[+DESCRIPTION?Display the current \bSSD\b list and return, when the user hit the enter key.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage SSD ; }" '}
6418N/A'
6418N/Afunction display_ssd {
6418N/A typeset X
6418N/A print '
6418N/ACurrent Service Search Descriptors:
6418N/A=================================='
6418N/A for X in "${SSD[@]}" ; do
6418N/A print " ${X}"
6418N/A done
6418N/A print '\nHit return to continue.'
6418N/A read
6418N/A}
6418N/A
6418N/AMan.addFunc prompt_ssd '' '[+NAME?prompt_ssd - Get SSDs from user.]
6418N/A[+DESCRIPTION?Ask the user whether to add/delete/modify/display one or more SSDs currently set and execute the corresponding action.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage ANS ; }" '}
6418N/A[+SEE ALSO?\bdisplay_msg()\b, \bget_ans()\b, \badd_ssd()\b, \bdelete_ssd()\b, \bmodify_ssd()\b, \bdisplay_ssd()\b, \breset_ssd()\b.]
6418N/A'
6418N/Afunction prompt_ssd {
6418N/A if get_confirm 'Do you wish to setup Service Search Descriptors (y/n/h)?' \
6418N/A 'n' 'ssd_help'
6418N/A then
6418N/A return
6418N/A fi
6418N/A
6418N/A # Display menu for SSD choices
6418N/A while : ; do
6418N/A display_msg prompt_ssd_menu
6418N/A get_ans 'Enter menu choice:' 'Quit'
6418N/A case "${ANS}" in
6418N/A [Qq] | Quit | quit) return ;;
6418N/A [Aa] | add) add_ssd ;;
6418N/A [Dd] | delete) delete_ssd ;;
6418N/A [Mm] | modify) modify_ssd ;;
6418N/A [Pp] | print | display) display_ssd ;;
6418N/A [Xx] | reset | clear) reset_ssd ;;
6418N/A [Hh] | Help | help)
6418N/A display_msg 'ssd_menu_help '
6418N/A print ' Press return to continue.'
6418N/A read
6418N/A ;;
6418N/A *) Log.warn "Invalid choice: '${ANS}' please re-enter from menu!" ;;
6418N/A esac
6418N/A done
6418N/A}
6418N/A
6418N/A ######################################################################
6418N/A # End Of FUNCTIONS FOR Service Search Descriptor's
6418N/A ######################################################################
6418N/AMan.addFunc prompt_config_info '' '[+NAME?prompt_config_info - Ask user for missing config info.]
6418N/A[+DESCRIPTION?Ask the user for the config info not yet available/read from an '"${PROG}"' config file.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage INT STR SSD ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (all info aquired).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A'
6418N/Afunction prompt_config_info {
6418N/A # Prompt for DS server name
6418N/A get_ids_server
6418N/A
6418N/A # Prompt for DS port number
6418N/A get_ids_port
6418N/A
6418N/A # Check DS version for compatibility
6418N/A chk_ids_version || return 66
6418N/A
6418N/A # Get the Directory manager DN and passwd
6418N/A get_dirmgr_dn
6418N/A get_dirmgr_pw
6418N/A
6419N/A # Check if the DS supports the VLV
6419N/A chk_vlv_indexes || return 67
6419N/A
6418N/A get_confirm 'Do you want to modify the DS timelimit for processing searches (y/n/h)?' 'n' 'tlim_help'
6418N/A INT[NEED_TIME]=$?
6418N/A if (( INT[NEED_TIME] )); then
6418N/A get_timelimit || return 70
6418N/A fi
6418N/A
6418N/A get_confirm 'Do you want to modify the DS sizelimit - max. entries to return (y/n/h)?' 'n' 'slim_help'
6418N/A INT[NEED_SIZE]=$?
6418N/A if (( INT[NEED_SIZE] )); then
6418N/A get_sizelimit || return 71
6418N/A fi
6418N/A
6418N/A
6418N/A # LDAP CLIENT PROFILE SPECIFIC INFORMATION
6418N/A # (i.e. the fields that show up in the profile)
6418N/A get_domain
6418N/A get_basedn || return 68
6418N/A
6418N/A # Check/Get Kerberos infos
6418N/A gssapi_setup
6418N/A
6418N/A get_profile_name
6418N/A
6418N/A if (( INT[LDAP_ENABLE_SHADOW_UPDATE] ));then
6418N/A setup_shadow_update || return 69
6418N/A return 0
6418N/A fi
6418N/A
6418N/A get_srv_list
6418N/A get_pref_srv
6418N/A get_search_scope
6418N/A get_followref
6418N/A
6418N/A # Store passwords in crypt format?
6418N/A get_want_crypt
6418N/A
6418N/A # If cred is "anonymous", make auth == "none"
6418N/A get_cred_level
6418N/A [[ ${STR[LDAP_CRED_LEVEL]} != anonymous ]] && get_auth 'client'
6418N/A
6418N/A get_confirm 'Do you want to setup any non-default Authentication Methods (y/n/h)?' 'n' 'srvauth_help'
6418N/A if (( $? )); then
6418N/A get_confirm 'Do you want to setup Authentication Methods for "pam_ldap" (y/n/h)?' 'n' 'pam_ldap_help'
6418N/A INT[NEED_SRVAUTH_PAM]=$?
6418N/A (( INT[NEED_SRVAUTH_PAM] )) && get_auth 'pam_ldap'
6418N/A
6418N/A get_confirm 'Do you want to setup Authentication Methods for "keyserv" (y/n/h)?' 'n' 'keyserv_help'
6418N/A INT[NEED_SRVAUTH_KEY]=$?
6418N/A (( INT[NEED_SRVAUTH_KEY] )) && get_auth 'keyserv'
6418N/A
6418N/A get_confirm 'Do you want to setup Authentication Methods for "passwd-cmd (y/n/h)?' 'n' 'passwd-cmd_help'
6418N/A INT[NEED_SRVAUTH_CMD]=$?
6418N/A (( INT[NEED_SRVAUTH_CMD] )) && get_auth 'passwd-cmd'
6418N/A fi
6418N/A
6418N/A # Get client timeouts
6418N/A get_srch_time
6418N/A get_prof_ttl
6418N/A get_bind_limit
6418N/A
6418N/A get_want_shadow_update
6418N/A
6418N/A reset_ssd
6418N/A prompt_ssd
6418N/A
6418N/A show_vars
6418N/A
6418N/A Log.printMarker
6418N/A return 0
6418N/A}
6418N/A######################################################################
6418N/A# End Of FUNCTIONS FOR prompt_config_info()
6418N/A######################################################################
6418N/A
6418N/A
6418N/A######################################################################
6418N/A# FUNCTIONS FOR display_summary() START HERE.
6418N/A######################################################################
6418N/AMan.addFunc get_proxyagent '' '[+NAME?get_proxyagent - Ask user for the proxy agent DN and password.]
6418N/A[+DESCRIPTION?Ask the user for the proxy agent DN and password to use and store it into \bSTR[LDAP_PROXYAGENT]]\b, \bSTR[LDAP_PROXYAGENT_CRED]]\b.]
6418N/A[+SEE ALSO?\bget_ans()\b.]
6418N/A'
6418N/Afunction get_proxyagent {
6418N/A STR[LDAP_PROXYAGENT]="cn=proxyagent,ou=profile,${STR[LDAP_BASEDN]}"
6418N/A get_ans 'Enter DN for proxy agent:' "${STR[LDAP_PROXYAGENT]}"
6418N/A STR[LDAP_PROXYAGENT]="${ANS}"
6418N/A get_passwd 'Enter passwd for proxyagent:'
6418N/A STR[LDAP_PROXYAGENT_CRED]="${ANS}"
6418N/A}
6418N/A
6418N/AMan.addFunc display_summary '' '[+NAME?display_summary - Display a summary of values entered and let the user modify values at will.]
6418N/A[+DESCRIPTION?Display a summary of all configuration relevant info and let the user re-enter data if needed.]
6418N/A'
6418N/Afunction display_summary {
6418N/A # Create lookup table for function names. Needs to be in sync with
6418N/A # helpTag 'summary_menu' in display_msg()!
6418N/A typeset -a FN=( 'dummy' ) # dummy for commit and quit
6418N/A FN+=( 'get_domain' 'get_basedn' 'get_profile_name' )
6418N/A FN+=( 'get_srv_list' 'get_pref_srv' 'get_search_scope' 'get_cred_level' )
6418N/A FN+=( 'get_auth client' 'get_followref' )
6418N/A FN+=( 'get_timelimit' 'get_sizelimit' 'get_want_crypt' )
6418N/A FN+=( 'get_auth pam_ldap' 'get_auth keyserv' 'get_auth passwd-cmd' )
6418N/A FN+=( 'get_srch_time' 'get_prof_ttl' 'get_bind_limit' )
6418N/A FN+=( 'get_want_shadow_update' )
6418N/A FN+=( 'prompt_ssd' )
6418N/A
6418N/A # Since menu prompt string is long, set here
6418N/A typeset PROMPT='Enter config value to change: (1-20 0=commit changes)'
6418N/A integer RES MAX=${#FN[@]}
6418N/A (( MAX-- ))
6418N/A
6418N/A while : ; do
6418N/A # Display menu and get value in range
6418N/A get_menu_choice "${PROMPT}" '0' ${MAX} '0' '' 'summary_menu'
6418N/A RES=$?
6418N/A
6418N/A # Make sure where not exiting
6418N/A (( RES == 0 )) && break # quit selected
6418N/A
6418N/A # Call appropriate function from function table
6418N/A ${FN[RES]}
6418N/A done
6418N/A
6418N/A # If credlevel is still proxy see if user wants a change?
6418N/A if [[ ${STR[LDAP_CRED_LEVEL]:0:5} == 'proxy' ]]; then
6418N/A if [[ ${STR[LDAP_AUTHMETHOD]} != none ]]; then
6418N/A INT[NEED_PROXY]=1
6418N/A get_proxyagent
6418N/A else
6418N/A Log.warn 'Since Authentication method is "none",' \
6418N/A 'credential level will be set to "anonymous"'
6418N/A STR[LDAP_CRED_LEVEL]='anonymous'
6418N/A fi
6418N/A fi
6418N/A
6418N/A # If shadow update is enabled, set up administrator credential
6418N/A if (( INT[LDAP_ENABLE_SHADOW_UPDATE] )); then
6418N/A INT[NEED_ADMIN]=1
6418N/A if [[ ${STR[LDAP_CRED_LEVEL]} == 'self' && \
6418N/A ${STR[LDAP_AUTHMETHOD]} == 'sasl/GSSAPI' ]];
6418N/A then
6418N/A INT[NEED_HOSTACL]=1
6418N/A INT[NEED_ADMIN]=0
6418N/A fi
6418N/A if (( INT[NEED_ADMIN] )); then
6418N/A get_adminDN
6418N/A get_admin_pw
6418N/A fi
6418N/A fi
6418N/A
6418N/A show_vars
6418N/A
6418N/A get_confirm_nodef '
6418N/AWARNING: About to start committing changes. (y=continue, n=EXIT)'
6418N/A if (( ! $? )); then
6418N/A Log.info 'Terminating setup without making changes at users request'
6418N/A return 1
6418N/A fi
6418N/A
6418N/A Log.printMarker
6418N/A return 0
6418N/A}
6418N/A######################################################################
6418N/A# End Of FUNCTIONS FOR display_summary()
6418N/A######################################################################
6418N/A
6418N/AMan.addFunc modify_cn '' '[+NAME?modify_cn - modify objectclass "ipNetwork" to RFC 2307bis.]
6418N/A[+DESCRIPTION?Change the cn from MUST to MAY in ipNetwork objectclass.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occurred.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1).]
6418N/A'
6418N/Afunction modify_cn {
6418N/A getDSobjectclasses || return 66
6418N/A typeset NEWDEF="'ipNetwork' SUP top STRUCTURAL DESC 'Abstraction of a network. The distinguished value of the cn attribute denotes the canonical name of the network' MUST ipNetworkNumber MAY "'( cn $ ipNetmaskNumber $ l $ description $ manager )'" X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A # bis-delta: MUST ( -cn ) MAY ( +cn )
6418N/A typeset DEF=${OID2ODEF['1.3.6.1.1.1.2.7']}
6418N/A if [[ -n ${DEF} ]]; then
6418N/A DEF=${DEF##*MUST*([[:space:]])}
6418N/A if [[ ${DEF:0:9} == 'ipNetwork' ]]; then
6418N/A # assume no need to fix, old definition would start with a '('
6418N/A showProgress 'Schema definition of ipNetwork ok (RFC2307bis).'
6418N/A return 0
6418N/A fi
6418N/A fi
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: cn=schema
6418N/Achangetype: modify
6418N/Aadd: objectclasses
6418N/Aobjectclasses: ( 1.3.6.1.1.1.2.7 NAME '"${NEWDEF}"')
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Schema update of ipNetwork to RFC2307bis failed'
6418N/A return 67
6418N/A fi
6418N/A showProgress 'Schema update of ipNetwork to RFC2307bis done.'
6418N/A OID2ODEF['1.3.6.1.1.1.2.7']="${NEWDEF}"
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc modify_timelimit '' '[+NAME?modify_timelimit - Set the DS timelimit.]
6418N/A[+DESCRIPTION?Set the DS timelimit to \bINT[DS_TIMELIMIT]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occurred.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1).]
6418N/A'
6418N/Afunction modify_timelimit {
6418N/A typeset NAME='nsslapd-timelimit'
6418N/A (( TMPF[IS_OPENDJ] )) && NAME='ds-cfg-time-limit'
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: cn=config
6418N/Achangetype: modify
6418N/Areplace: '"${NAME}"'
6418N/A'"${NAME}"': '"${INT[DS_TIMELIMIT]}"' s
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Update of ${NAME} failed'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "Changed ${NAME} to ${INT[DS_TIMELIMIT]} in 'cn=config'."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc modify_sizelimit '' '[+NAME?modify_sizelimit - Set the DS sizelimit.]
6418N/A[+DESCRIPTION?Set the DS sizelimit to \bINT[DS_SIZELIMIT]]\b.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occurred.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1).]
6418N/A'
6418N/Afunction modify_sizelimit {
6418N/A typeset NAME='nsslapd-sizelimit'
6418N/A (( TMPF[IS_OPENDJ] )) && NAME='ds-cfg-size-limit'
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: cn=config
6418N/Achangetype: modify
6418N/Areplace: '"${NAME}"'
6418N/A'"${NAME}"': '"${INT[DS_SIZELIMIT]}"'
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Update of ${NAME} failed"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "Changed ${NAME} to ${INT[DS_SIZELIMIT]} in 'cn=config'."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc modify_pwd_crypt '' '[+NAME?modify_pwd_crypt - modify the passwd storage scheme to use CRYPT.]
6418N/A[+DESCRIPTION?Set the default password policy of the DS to CRYPT.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occurred.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1).]
6418N/A'
6418N/Afunction modify_pwd_crypt {
6418N/A # DS 5.2 moved passwordchangescheme off to a new data structure
6418N/A typeset -a INFO=( ${TMP[DS_INFO]} )
6418N/A typeset DN='cn=config' TARGET='passwordStorageScheme' VALUE='CRYPT' MSG=''
6418N/A typeset FMT='dn: %s\nchangetype: modify\nreplace: %s\n%s: %s\n\n'
6418N/A nextFile modify $0
6418N/A
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A DN='cn=Default Password Policy,cn=Password Policies,cn=config'
6418N/A TARGET='ds-cfg-default-password-storage-scheme'
6418N/A VALUE='cn=CRYPT,cn=Password Storage Schemes,cn=config'
6418N/A else
6418N/A # DSEE
6418N/A integer VER=$(( ${INFO[1]} * 1000 + ${INFO[2]} ))
6418N/A (( VER >= 5002 )) && DN='cn=Password Policy,cn=config'
6418N/A fi
6418N/A printf "${FMT}" "${DN}" "${TARGET}" "${TARGET}" "${VALUE}" >${TMP[FILE]}
6418N/A MSG="Changed '${TARGET}' to 'CRYPT'"
6418N/A
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A if (( INT[NEED_CRYPT_IMPORT] )); then
6418N/A TARGET='ds-cfg-allow-pre-encoded-passwords'
6418N/A printf "${FMT}" "${DN}" "${TARGET}" "${TARGET}" 'true'>>${TMP[FILE]}
6418N/A MSG+="and '${TARGET}' to 'true'"
6418N/A fi
6418N/A DN='cn=Password Policy Import,cn=Plugins,cn=config'
6418N/A TARGET='ds-cfg-default-user-password-storage-scheme'
6418N/A printf "${FMT}" "${DN}" "${TARGET}" "${TARGET}" "${VALUE}">>${TMP[FILE]}
6418N/A fi
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Update of passwordStorageScheme failed'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "${MSG}."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc update_schema_attr '' '[+NAME?update_schema_attr - Update DS schema to support Naming Services.]
6418N/A[+DESCRIPTION?Update the schema of the DS with the attribute types required for the Solaris Naming Services. It just checks, whether the OID is defined in the server schema. If already defined, it is left as is, otherwise added.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occurred.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1), \bgetDSattributes()\b.]
6418N/A'
6418N/Afunction update_schema_attr {
6418N/A
6418N/A # incorporate former 'keep_backward_compatibility()'
6418N/A getDSattributes || return 66
6418N/A typeset MEMBERGID_OID='1.3.6.1.4.1.42.2.27.5.1.30'
6418N/A typeset DEF=${ANAME2OID['membergid-oid']}
6418N/A [[ -n ${DEF} ]] && MEMBERGID_OID='memberGid-oid'
6418N/A typeset RFC822MAILMEMBER_OID='1.3.6.1.4.1.42.2.27.2.1.15'
6418N/A DEF=${ANAME2OID['rfc822mailmember-oid']}
6418N/A [[ -n ${DEF} ]] && RFC822MAILMEMBER_OID='rfc822mailMember-oid'
6418N/A
6418N/A # EE and OD definitions seem to be compatible wrt. to Solaris. However, the
6418N/A # OD defs usually specifies explicitly the server behavior (what happens, if
6418N/A # EQUALITY|SUBSTR is not specified => caseIgnore[Substring]Match)) and
6418N/A # sometimes a different kind of String to use (see RFC 4517):
6418N/A # IA5 String: ASCII character in the range of 0..127
6418N/A # Octet String: byte collection (0..255), usually not human readable,
6418N/A # bytewise comparision
6418N/A # Directory String: an UTF-8 string
6418N/A # DN: basically an UTF-8 string, but with some constraints wrt. backslash
6418N/A # escaping '\0', '"', '+', ',', ';', '<', '>', and '\'
6418N/A # Boolean String: TRUE|FALSE
6418N/A typeset -A EE=( )
6418N/A typeset -A OD=( )
6418N/A EE['1.3.6.1.1.1.1.28']="'nisPublickey' DESC 'NIS public key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.1.1.1.28']="'nisPublicKey' DESC 'NIS public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'draft-howard-rfc2307bis'" # Directory vs. Octet String
6418N/A
6418N/A EE['1.3.6.1.1.1.1.29']="'nisSecretkey' DESC 'NIS secret key' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.1.1.1.29']="'nisSecretKey' DESC 'NIS secret key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'draft-howard-rfc2307bis'" # Directory vs. Octet String
6418N/A
6418N/A EE['1.3.6.1.1.1.1.30']="'nisDomain' DESC 'NIS domain' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.1.1.1.30']="'nisDomain' DESC 'NIS domain' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'draft-howard-rfc2307bis'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.1.1.1.31']="'automountMapName' DESC 'automount Map Name' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.1.1.1.31']="'automountMapName' DESC 'automount Map Name' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.1.1.1.32']="'automountKey' DESC 'automount Key Value' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.1.1.1.32']="'automountKey' DESC 'Automount Key value' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.1.1.1.33']="'automountInformation' DESC 'automount information' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.1.1.1.33']="'automountInformation' DESC 'Automount information' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.1.1.12']="'nisNetIdUser' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD['1.3.6.1.4.1.42.2.27.1.1.12']="'nisNetIdUser' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.1.1.13']="'nisNetIdGroup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD['1.3.6.1.4.1.42.2.27.1.1.13']="'nisNetIdGroup' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.1.1.14']="'nisNetIdHost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD['1.3.6.1.4.1.42.2.27.1.1.14']="'nisNetIdHost' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE[${RFC822MAILMEMBER_OID}]="'rfc822mailMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD[${RFC822MAILMEMBER_OID}]="'rfc822mailMember' DESC 'rfc822 mail addresss of group member' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['2.16.840.1.113730.3.1.30']="'mgrpRFC822MailMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['2.16.840.1.113730.3.1.30']="'mgrpRFC822MailMember' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.15']="'SolarisLDAPServers' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.15']="'SolarisLDAPServers' DESC 'LDAP Server address eg. 76.234.3.1:389' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.16']="'SolarisSearchBaseDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.16']="'SolarisSearchBaseDN' DESC 'Search Base Distinguished Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # DN vs. Directory String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.17']="'SolarisCacheTTL' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.17']="'SolarisCacheTTL' DESC 'TTL value for the Domain information eg. 1w, 2d, 3h, 10m, or 5s' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.18']="'SolarisBindDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.18']="'SolarisBindDN' DESC 'DN to be used to bind to the directory as proxy' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # DN vs. Directory String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.19']="'SolarisBindPassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.19']="'SolarisBindPassword' DESC 'Password for bindDN to authenticate to the directory' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # IA5 vs. Octet String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.20']="'SolarisAuthMethod' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.20']="'SolarisAuthMethod' DESC 'Authentication method to be used eg. \"NS_LDAP_AUTH_NONE\", \"NS_LDAP_AUTH_SIMPLE\" or \"NS_LDAP_AUTH_SASL_CRAM_MD5\"' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.21']="'SolarisTransportSecurity' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.21']="'SolarisTransportSecurity' DESC 'Transport Level Security method to be used eg. \"NS_LDAP_SEC_NONE\" or \"NS_LDAP_SEC_SASL_TLS\"' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.22']="'SolarisCertificatePath' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.22']="'SolarisCertificatePath' DESC 'Path to certificate file/device' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.23']="'SolarisCertificatePassword' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.23']="'SolarisCertificatePassword' DESC 'Password or PIN that grants access to certificate.' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # IA5 vs. Octet String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.24']="'SolarisDataSearchDN' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.24']="'SolarisDataSearchDN' DESC 'Search DN for data lookup in \":(DN0),(DN1),...\" format' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.25']="'SolarisSearchScope' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.25']="'SolarisSearchScope' DESC 'Scope to be used for search operations eg. \"NS_LDAP_SCOPE_BASE\", \"NS_LDAP_SCOPE_ONELEVEL\" or \"NS_LDAP_SCOPE_SUBTREE\"' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.26']="'SolarisSearchTimeLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.26']="'SolarisSearchTimeLimit' DESC 'Time Limit in seconds for search operations' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.27']="'SolarisPreferredServer' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.27']="'SolarisPreferredServer' DESC 'Preferred LDAP Server address or network number' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.28']="'SolarisPreferredServerOnly' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.28']="'SolarisPreferredServerOnly' DESC 'Boolean flag for use of preferredServer or not' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. Boolean String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.29']="'SolarisSearchReferral' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.29']="'SolarisSearchReferral' DESC 'referral chasing option eg. \"NS_LDAP_NOREF\" or \"NS_LDAP_FOLLOWREF\"' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.4']="'SolarisAttrKeyValue' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.4']="'SolarisAttrKeyValue' DESC 'Semi-colon separated key=value pairs of attributes' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.5']="'SolarisAuditAlways' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.5']="'SolarisAuditAlways' DESC 'Always audited attributes per-user' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.6']="'SolarisAuditNever' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.6']="'SolarisAuditNever' DESC 'Never audited attributes per-user' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.7']="'SolarisAttrShortDesc' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.7']="'SolarisAttrShortDesc' DESC 'Short description about an entry, used by GUIs' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.8']="'SolarisAttrLongDesc' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.8']="'SolarisAttrLongDesc' DESC 'Detail description about an entry' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.9']="'SolarisKernelSecurityPolicy' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.9']="'SolarisKernelSecurityPolicy' DESC 'Solaris kernel security policy' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.10']="'SolarisProfileType' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.10']="'SolarisProfileType' DESC 'Type of object defined in profile'EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.11']="'SolarisProfileId' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.11']="'SolarisProfileId' DESC 'Identifier of object defined in profile' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.12']="'SolarisUserQualifier' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.12']="'SolarisUserQualifier' DESC 'Per-user login attributes' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.13']="'SolarisAttrReserved1' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.13']="'SolarisAttrReserved1' DESC 'Reserved for future use' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.14']="'SolarisAttrReserved2' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.14']="'SolarisAttrReserved2' DESC 'Reserved for future use' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.1']="'SolarisProjectID' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.1']="'SolarisProjectID' DESC 'Unique ID for a Solaris Project entry' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.2']="'SolarisProjectName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.2']="'SolarisProjectName' DESC 'Name of a Solaris Project Entry' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.3']="'SolarisProjectAttr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.3']="'SolarisProjectAttr' DESC 'Attributes of a Solaris Project entry' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE[${MEMBERGID_OID}]="'memberGid' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD[${MEMBERGID_OID}]="'memberGid' DESC 'Posix Group Name' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.0']="'defaultServerList' DESC 'Default LDAP server host address used by a DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.0']="'defaultServerList' DESC 'List of default servers' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.1']="'defaultSearchBase' DESC 'Default LDAP base DN used by a DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.1']="'defaultSearchBase' DESC 'Default base for searches' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.2']="'preferredServerList' DESC 'Preferred LDAP server host addresses to be used by a DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.2']="'preferredServerList' DESC 'List of preferred servers' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.3']="'searchTimeLimit' DESC 'Maximum time in seconds a DUA should allow for a search to complete' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.3']="'searchTimeLimit' DESC 'Maximum time an agent or service allows for a search to complete' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.4']="'bindTimeLimit' DESC 'Maximum time in seconds a DUA should allow for the bind operation to complete' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.4']="'bindTimeLimit' DESC 'Maximum time an agent or service allows for a bind operation to complete' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.5']="'followReferrals' DESC 'Tells DUA if it should follow referrals returned by a DSA search result' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.5']="'followReferrals' DESC 'An agent or service does or should follow referrals' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'RFC 4876'" # Directory vs. Boolean String
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.6']="'authenticationMethod' DESC 'A keystring which identifies the type of authentication method used to contact the DSA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.6']="'authenticationMethod' DESC 'Identifies the types of authentication methods either used, required, or provided by a service or peer' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.7']="'profileTTL' DESC 'Time to live before a client DUA should re-read this configuration profile' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.7']="'profileTTL' DESC 'Time to live, in seconds, before a profile is considered stale' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.14']="'serviceSearchDescriptor' DESC 'LDAP search descriptor list used by Naming-DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.14']="'serviceSearchDescriptor' DESC 'Specifies search descriptors required, used, or supported by a particular service or agent' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4876'" # IA5 vs. Directory String
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.9']="'attributeMap' DESC 'Attribute mappings used by a Naming-DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.9']="'attributeMap' DESC 'Attribute mappings used, required, or supported by an agent or service' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 4876'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.10']="'credentialLevel' DESC 'Identifies type of credentials a DUA should use when binding to the LDAP server' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.10']="'credentialLevel' DESC 'Identifies type of credentials either used, required, or supported by an agent or service' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 4876'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.11']="'objectclassMap' DESC 'Objectclass mappings used by a Naming-DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.11']="'objectclassMap' DESC 'Object class mappings used, required, or supported by an agent or service' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 4876'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.12']="'defaultSearchScope' DESC 'Default search scope used by a DUA' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.12']="'defaultSearchScope' DESC 'Default scope used when performing a search' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'RFC 4876'" # Directory vs. IA5 String
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.13']="'serviceCredentialLevel' DESC 'Search scope used by a service of the DUA' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.13']="'serviceCredentialLevel' DESC 'Specifies the type of credentials either used, required, or supported by a specific service' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.1.15']="'serviceAuthenticationMethod' DESC 'Authentication Method used by a service of the DUA' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.11.1.3.1.1.15']="'serviceAuthenticationMethod' DESC 'Specifies types authentication methods either used, required, or supported by a particular service' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1140']="'printer-uri' DESC 'A URI supported by this printer. This URI SHOULD be used as a relative distinguished name (RDN). If printer-xri-supported is implemented, then this URI value MUST be listed in a member value of printer-xri-supported.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1140']="'printer-uri' DESC 'A URI supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1107']="'printer-xri-supported' DESC 'The unordered list of XRI (extended resource identifiers) supported by this printer. Each member of the list consists of a URI (uniform resource identifier) followed by optional authentication and security metaparameters.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.18.0.2.4.1107']="'printer-xri-supported' DESC 'The unordered list of XRI (extended resource identifiers) supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1135']="'printer-name' DESC 'The site-specific administrative name of this printer, more end-user friendly than a URI.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1135']="'printer-name' DESC 'The site-specific administrative name of this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1119']="'printer-natural-language-configured' DESC 'The configured language in which error and status messages will be generated (by default) by this printer. Also, a possible language for printer string attributes set by operator, system administrator, or manufacturer. Also, the (declared) language of the \"printer-name\", \"printer-location\", \"printer-info\", and \"printer-make-and-model\" attributes of this printer. For example: \"en-us\" (US English) or \"fr-fr\" (French in France) Legal values of language tags conform to [RFC3066] \"Tags for the Identification of Languages\".' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1119']="'printer-natural-language-configured' DESC 'The configured natural language in which error and status messages will be generated (by default) by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1136']="'printer-location' DESC 'Identifies the location of the printer. This could include things like: \"in Room 123A\", \"second floor of building XYZ\".' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1136']="'printer-location' DESC 'The physical location of this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1139']="'printer-info' DESC 'Identifies the descriptive information about this printer. This could include things like: \"This printer can be used for printing color transparencies for HR presentations\", or \"Out of courtesy for others, please print only small (1-5 page) jobs at this printer\", or even \"This printer is going away on July 1, 1997, please find a new printer\".' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1139']="'printer-info' DESC 'Descriptive information about this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1134']="'printer-more-info' DESC 'A URI used to obtain more information about this specific printer. For example, this could be an HTTP type URI referencing an HTML page accessible to a Web Browser. The information obtained from this URI is intended for end user consumption.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1134']="'printer-more-info' DESC 'A URI for more information about this specific printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1138']="'printer-make-and-model' DESC 'Identifies the make and model of the device. The device manufacturer MAY initially populate this attribute.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1138']="'printer-make-and-model' DESC 'Make and model of this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1133']="'printer-ipp-versions-supported' DESC 'Identifies the IPP protocol version(s) that this printer supports, including major and minor versions, i.e., the version numbers for which this Printer implementation meets the conformance requirements.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1133']="'printer-ipp-versions-supported' DESC 'IPP protocol version(s) that this printer supports.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1132']="'printer-multiple-document-jobs-supported' DESC 'Indicates whether or not the printer supports more than one document per job, i.e., more than one Send-Document or Send-Data operation with document data.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1132']="'printer-multiple-document-jobs-supported' DESC 'Indicates whether or not this printer supports more than one document per job.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1109']="'printer-charset-configured' DESC 'The configured charset in which error and status messages will be generated (by default) by this printer. Also, a possible charset for printer string attributes set by operator, system administrator, or manufacturer. For example: \"utf-8\" (ISO 10646/Unicode) or \"iso-8859-1\" (Latin1). Legal values are defined by the IANA Registry of Coded Character Sets and the \"(preferred MIME name)\" SHALL be used as the tag. For coherence with IPP Model, charset tags in this attribute SHALL be lowercase normalized. This attribute SHOULD be static (time of registration) and SHOULD NOT be dynamically refreshed attributetypes: (subsequently).' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1109']="'printer-charset-configured' DESC 'The configured charset in which error and status messages will be generated (by default) by this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1131']="'printer-charset-supported' DESC 'Identifies the set of charsets supported for attribute type values of type Directory String for this directory entry. For example: \"utf-8\" (ISO 10646/Unicode) or \"iso-8859-1\" (Latin1). Legal values are defined by the IANA Registry of Coded Character Sets and the preferred MIME name.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63}"
6418N/A OD['1.3.18.0.2.4.1131']="'printer-charset-supported' DESC 'Set of charsets supported for the attribute values of syntax DirectoryString for this directory entry.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1137']="'printer-generated-natural-language-supported' DESC 'Identifies the natural language(s) supported for this directory entry. For example: \"en-us\" (US English) or \"fr-fr\" (French in France). Legal values conform to [RFC3066], Tags for the Identification of Languages.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63}"
6418N/A OD['1.3.18.0.2.4.1137']="'printer-generated-natural-language-supported' DESC 'Natural language(s) supported for this directory entry.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{63} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1130']="'printer-document-format-supported' DESC 'The possible document formats in which data may be interpreted and printed by this printer. Legal values are MIME types come from the IANA Registry of Internet Media Types.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1130']="'printer-document-format-supported' DESC 'The possible source document formats which may be interpreted and printed by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1129']="'printer-color-supported' DESC 'Indicates whether this printer is capable of any type of color printing at all, including highlight color.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1129']="'printer-color-supported' DESC 'Indicates whether this printer is capable of any type of color printing at all, including highlight color.' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1128']="'printer-compression-supported' DESC 'Compression algorithms supported by this printer. For example: \"deflate, gzip\". Legal values include; \"none\", \"deflate\" attributetypes: (public domain ZIP), \"gzip\" (GNU ZIP), \"compress\" (UNIX).' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}"
6418N/A OD['1.3.18.0.2.4.1128']="'printer-compression-supported' DESC 'Compression algorithms supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1127']="'printer-pages-per-minute' DESC 'The nominal number of pages per minute which may be output by this printer (e.g., a simplex or black-and-white printer). This attribute is informative, NOT a service guarantee. Typically, it is the value used in marketing literature to describe this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1127']="'printer-pages-per-minute' DESC 'The nominal number of pages per minute which may be output by this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1126']="'printer-pages-per-minute-color' DESC 'The nominal number of color pages per minute which may be output by this printer (e.g., a simplex or color printer). This attribute is informative, NOT a service guarantee. Typically, it is the value used in marketing literature to describe this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1126']="'printer-pages-per-minute-color' DESC 'The nominal number of color pages per minute which may be output by this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1125']="'printer-finishings-supported' DESC 'The possible finishing operations supported by this printer. Legal values include; \"none\", \"staple\", \"punch\", \"cover\", \"bind\", \"saddle-stitch\", \"edge-stitch\", \"staple-top-left\", \"staple-bottom-left\", \"staple-top-right\", \"staple-bottom-right\", \"edge-stitch-left\", \"edge-stitch-top\", \"edge-stitch-right\", \"edge-stitch-bottom\", \"staple-dual-left\", \"staple-dual-top\", \"staple-dual-right\", \"staple-dual-bottom\".' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}"
6418N/A OD['1.3.18.0.2.4.1125']="'printer-finishings-supported' DESC 'The possible finishing operations supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1124']="'printer-number-up-supported' DESC 'The possible numbers of print-stream pages to impose upon a single side of an instance of a selected medium. Legal values include; 1, 2, and 4. Implementations may support other values.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27"
6418N/A OD['1.3.18.0.2.4.1124']="'printer-number-up-supported' DESC 'The possible numbers of print-stream pages to impose upon a single side of an instance of a selected medium.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1123']="'printer-sides-supported' DESC 'The number of impression sides (one or two) and the two-sided impression rotations supported by this printer. Legal values include; \"one-sided\", \"two-sided-long-edge\", \"two-sided-short-edge\".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1123']="'printer-sides-supported' DESC 'The number of impression sides (one or two) and the two-sided impression rotations supported by this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1122']="'printer-media-supported' DESC 'The standard names/types/sizes (and optional color suffixes) of the media supported by this printer. For example: \"iso-a4\", \"envelope\", or \"na-letter-white\". Legal values conform to ISO 10175, Document Printing Application (DPA), and any IANA registered extensions.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}"
6418N/A OD['1.3.18.0.2.4.1122']="'printer-media-supported' DESC 'The standard names/types/sizes (and optional color suffixes) of the media supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1117']="'printer-media-local-supported' DESC 'Site-specific names of media supported by this printer, in the language in \"printer-natural-language-configured\". For example: \"purchasing-form\" (site-specific name) as opposed to (in \"printer-media-supported\"): \"na-letter\" (standard keyword from ISO 10175).' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}"
6418N/A OD['1.3.18.0.2.4.1117']="'printer-media-local-supported' DESC 'Site-specific names of media supported by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1121']="'printer-resolution-supported' DESC 'List of resolutions supported for printing documents by this printer. Each resolution value is a string with 3 fields: 1) Cross feed direction resolution (positive integer), 2) Feed direction resolution (positive integer), 3) Resolution unit. Legal values are \"dpi\" (dots per inch) and \"dpcm\" (dots per centimeter). Each resolution field is delimited by \">\". For example: \"300> 300> dpi>\".' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255}"
6418N/A OD['1.3.18.0.2.4.1121']="'printer-resolution-supported' DESC 'List of resolutions supported for printing documents by this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1120']="'printer-print-quality-supported' DESC 'List of print qualities supported for printing documents on this printer. For example: \"draft, normal\". Legal values include; \"unknown\", \"draft\", \"normal\", \"high\".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1120']="'printer-print-quality-supported' DESC 'List of print qualities supported for printing documents on this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1110']="'printer-job-priority-supported' DESC 'Indicates the number of job priority levels supported. An IPP conformant printer which supports job priority must always support a full range of priorities from \"1\" to \"100\" (to ensure consistent behavior), therefore this attribute describes the \"granularity\". Legal values of this attribute are from \"1\" to \"100\".' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1110']="'printer-job-priority-supported' DESC 'Indicates the number of job priority levels supported by this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1118']="'printer-copies-supported' DESC 'The maximum number of copies of a document that may be printed as a single job. A value of \"0\" indicates no maximum limit. A value of \"-1\" indicates unknown.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1118']="'printer-copies-supported' DESC 'The maximum number of copies of a document that may be printed as a single job on this printer.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1111']="'printer-job-k-octets-supported' DESC 'The maximum size in kilobytes (1,024 octets actually) incoming print job that this printer will accept. A value of \"0\" indicates no maximum limit. A value of \"-1\" indicates unknown.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1111']="'printer-job-k-octets-supported' DESC 'The maximum size in kilobytes (1,024 octets actually) incoming print job that this printer will accept.' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1112']="'printer-current-operator' DESC 'The name of the current human operator responsible for operating this printer. It is suggested that this string include information that would enable other humans to reach the operator, such as a phone number.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1112']="'printer-current-operator' DESC 'The identity of the current human operator responsible for operating this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1113']="'printer-service-person' DESC 'The name of the current human service person responsible for servicing this printer. It is suggested that this string include information that would enable other humans to reach the service person, such as a phone number.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE"
6418N/A OD['1.3.18.0.2.4.1113']="'printer-service-person' DESC 'The identity of the current human service person responsible for servicing this printer.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} SINGLE-VALUE X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1114']="'printer-delivery-orientation-supported' DESC 'The possible delivery orientations of pages as they are printed and ejected from this printer. Legal values include; \"unknown\", \"face-up\", and \"face-down\".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1114']="'printer-delivery-orientation-supported' DESC 'The possible delivery orientations of pages as they are printed and ejected from this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1115']="'printer-stacking-order-supported' DESC 'The possible stacking order of pages as they are printed and ejected from this printer. Legal values include; \"unknown\", \"first-to-last\", \"last-to-first\".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1115']="'printer-stacking-order-supported' DESC 'The possible stacking order of pages as they are printed and ejected from this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1116']="'printer-output-features-supported' DESC 'The possible output features supported by this printer. Legal values include; \"unknown\", \"bursting\", \"decollating\", \"page-collating\", \"offset-stacking\".' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1116']="'printer-output-features-supported' DESC 'The possible output features supported by this printer.' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.4.1108']="'printer-aliases' DESC 'Site-specific administrative names of this printer in addition the printer name specified for printer-name.' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127}"
6418N/A OD['1.3.18.0.2.4.1108']="'printer-aliases' DESC 'List of site-specific administrative names of this printer in addition to the value specified for printer-name.' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{127} X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.63']="'sun-printer-bsdaddr' DESC 'Sets the server, print queue destination name and whether the client generates protocol extensions. \"Solaris\" specifies a Solaris print server extension. The value is represented by the following value: server \",\" destination \", Solaris\".' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.63']="'sun-printer-bsdaddr' DESC 'Sets the server, print queue destination name and whether the client generates protocol extensions. \"Solaris\" specifies a Solaris print server extension. The value is represented by the following value: server \",\" destination \", Solaris\".' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.64']="'sun-printer-kvp' DESC 'This attribute contains a set of key value pairs which may have meaning to the print subsystem or may be user defined. Each value is represented by the following: key \"=\" value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.64']="'sun-printer-kvp' DESC 'This attribute contains a set of key value pairs which may have meaning to the print subsystem or may be user defined. Each value is represented by the following: key \"=\" value.' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.57']="'nisplusTimeZone' DESC 'tzone column from NIS+ timezone table' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.57']="'nisplusTimeZone' DESC 'tzone column from NIS+ timezone table' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.67']="'ipTnetTemplateName' DESC 'Trusted Solaris network template template_name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.67']="'ipTnetTemplateName' DESC 'Trusted Solaris network template template_name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.1.68']="'ipTnetNumber' DESC 'Trusted Solaris network template ip_address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.1.68']="'ipTnetNumber' DESC 'Trusted Solaris network template ip_address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A # obey CLI syntax force option (if any)
6418N/A if (( TMPF[SYNTAX] == 1 )); then
6418N/A typeset -n MAP=OD
6418N/A elif (( TMPF[SYNTAX] == 2 )); then
6418N/A typeset -n MAP=EE
6418N/A elif (( TMPF[IS_OPENDJ] )); then
6418N/A typeset -n MAP=OD
6418N/A else
6418N/A typeset -n MAP=EE
6418N/A fi
6418N/A
6418N/A typeset TODO='' OID X
6418N/A for OID in ${!MAP[@]}; do
6418N/A [[ -n ${OID2ADEF[${OID}]} ]] && continue
6418N/A X="${MAP[${OID}]}"
6418N/A TODO+='attributetypes: ( '"${OID} NAME ${X}"' )\n'
6418N/A OID2ADEF["${OID}"]="${X}"
6418N/A X=${X:1}
6418N/A X=${X%%"'"*} # we have no aliases above
6418N/A ANAME2OID["${X}"]="${OID}"
6418N/A done
6418N/A
6418N/A if [[ -z ${TODO} ]]; then
6418N/A X='Schema contains all required attribute definitions'
6418N/A else
6418N/A nextFile add $0
6418N/A print 'dn: cn=schema\nchangetype: modify\nadd: attributetypes' \
6418N/A "\n${TODO}" >${TMP[FILE]}
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Adding attribute definitions to schema failed'
6418N/A return 67
6418N/A fi
6418N/A X='Schema attribute definitions added'
6418N/A fi
6418N/A showProgress "${X}."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc update_schema_obj '' '[+NAME?update_schema_obj - Update DS schema to support Naming Services.]
6418N/A[+DESCRIPTION?Update the schema of the DS with the objectclasses required for the Solaris Naming Services. It just checks, whether the OID is already defined on the server. If already defined, it is left as is, otherwise added.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occurred.]
6418N/A}
6418N/A[+SEE ALSO?\bupdate_schema_attr()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction update_schema_obj {
6418N/A getDSobjectclasses || return 66
6418N/A
6418N/A typeset -A EE=( )
6418N/A typeset -A OD=( )
6418N/A EE['1.3.6.1.1.1.2.14']="'NisKeyObject' SUP top MUST "'( cn $ nisPublickey $ nisSecretkey ) MAY ( uidNumber $ description )'
6418N/A OD['1.3.6.1.1.1.2.14']="'nisKeyObject' SUP top AUXILIARY DESC 'An object with a public and secret key' MUST "'( cn $ nisPublicKey $ nisSecretKey ) MAY ( uidNumber $ description )'" X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.1.1.2.15']="'nisDomainObject' SUP top MUST nisDomain"
6418N/A OD['1.3.6.1.1.1.2.15']="'nisDomainObject' SUP top AUXILIARY DESC 'Associates a NIS domain with a naming context' MUST nisDomain X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.1.1.2.16']="'automountMap' SUP top MUST automountMapName MAY description"
6418N/A OD['1.3.6.1.1.1.2.16']="'automountMap' SUP top STRUCTURAL MUST ( automountMapName ) MAY description X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.1.1.2.17']="'automount' SUP top MUST "'( automountKey $ automountInformation ) MAY description'
6418N/A OD['1.3.6.1.1.1.2.17']="'automount' SUP top STRUCTURAL DESC 'Automount information' MUST "'( automountKey $ automountInformation )'" MAY description X-ORIGIN 'draft-howard-rfc2307bis'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.7']="'SolarisNamingProfile' SUP top MUST "'( cn $ SolarisLDAPservers $ SolarisSearchBaseDN ) MAY ( SolarisBindDN $ SolarisBindPassword $ SolarisAuthMethod $ SolarisTransportSecurity $ SolarisCertificatePath $ SolarisCertificatePassword $ SolarisDataSearchDN $ SolarisSearchScope $ SolarisSearchTimeLimit $ SolarisPreferredServer $ SolarisPreferredServerOnly $ SolarisCacheTTL $ SolarisSearchReferral )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.7']="'SolarisNamingProfile' SUP top STRUCTURAL DESC 'Solaris LDAP Naming client profile objectClass' MUST "'( cn $ SolarisLDAPServers $ SolarisSearchBaseDN ) MAY ( SolarisBindDN $ SolarisBindPassword $ SolarisAuthMethod $ SolarisTransportSecurity $ SolarisCertificatePath $ SolarisCertificatePassword $ SolarisDataSearchDN $ SolarisSearchScope $ SolarisSearchTimeLimit $ SolarisPreferredServer $ SolarisPreferredServerOnly $ SolarisCacheTTL $ SolarisSearchReferral $ SolarisBindTimeLimit )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['2.16.840.1.113730.3.2.4']="'mailGroup' SUP top MUST mail MAY "'( cn $ mgrpRFC822MailMember )'
6418N/A OD['2.16.840.1.113730.3.2.4']="'mailGroup' SUP top STRUCTURAL MUST mail MAY "'( cn $ mgrpRFC822MailMember )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.1.2.5']="'nisMailAlias' SUP top MUST cn MAY rfc822mailMember"
6418N/A OD['1.3.6.1.4.1.42.2.27.1.2.5']="'nisMailAlias' SUP top MUST cn MAY rfc822mailMember X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.1.2.6']="'nisNetId' SUP top MUST cn MAY "'( nisNetIdUser $ nisNetIdGroup $ nisNetIdHost )'
6418N/A OD['1.3.6.1.4.1.42.2.27.1.2.6']="'nisNetId' SUP top MUST cn MAY "'( nisNetIdUser $ nisNetIdGroup $ nisNetIdHost )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.2']="'SolarisAuditUser' SUP top AUXILIARY MAY "'( SolarisAuditAlways $ SolarisAuditNever )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.2']="'SolarisAuditUser' SUP top AUXILIARY MAY "'( SolarisAuditAlways $ SolarisAuditNever )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.3']="'SolarisUserAttr' SUP top AUXILIARY MAY "'( SolarisUserQualifier $ SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrKeyValue )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.3']="'SolarisUserAttr' SUP top AUXILIARY DESC 'User attributes' MAY "'( SolarisUserQualifier $ SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrKeyValue )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.4']="'SolarisAuthAttr' SUP top MUST cn MAY "'( SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrShortDesc $ SolarisAttrLongDesc $ SolarisAttrKeyValue )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.4']="'SolarisAuthAttr' SUP top STRUCTURAL DESC 'Authorizations data' MUST cn MAY "'( SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrShortDesc $ SolarisAttrLongDesc $ SolarisAttrKeyValue )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.5']="'SolarisProfAttr' SUP top MUST cn MAY "'( SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrLongDesc $ SolarisAttrKeyValue )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.5']="'SolarisProfAttr' SUP top STRUCTURAL DESC 'Profiles data' MUST cn MAY "'( SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisAttrLongDesc $ SolarisAttrKeyValue )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.6']="'SolarisExecAttr' SUP top AUXILIARY MAY "'( SolarisKernelSecurityPolicy $ SolarisProfileType $ SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisProfileID $ SolarisAttrKeyValue )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.6']="'SolarisExecAttr' SUP top AUXILIARY DESC 'Profiles execution attributes' MAY "'( SolarisKernelSecurityPolicy $ SolarisProfileType $ SolarisAttrReserved1 $ SolarisAttrReserved2 $ SolarisProfileId $ SolarisAttrKeyValue )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.1']="'SolarisProject' SUP top MUST "'( SolarisProjectID $ SolarisProjectName ) MAY ( memberUid $ memberGid $ description $ SolarisProjectAttr )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.1']="'SolarisProject' SUP top STRUCTURAL MUST "'( SolarisProjectID $ SolarisProjectName ) MAY ( memberUid $ memberGid $ description $ SolarisProjectAttr )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.11.1.3.1.2.4']="'DUAConfigProfile' SUP top DESC 'Abstraction of a base configuration for a DUA' MUST cn MAY "'( defaultServerList $ preferredServerList $ defaultSearchBase $ defaultSearchScope $ searchTimeLimit $ bindTimeLimit $ credentialLevel $ authenticationMethod $ followReferrals $ serviceSearchDescriptor $ serviceCredentialLevel $ serviceAuthenticationMethod $ objectclassMap $ attributeMap $ profileTTL )'
6421N/A OD['1.3.6.1.4.1.11.1.3.1.2.5']="'DUAConfigProfile' SUP top STRUCTURAL DESC 'Abstraction of a base configuration for a DUA' MUST "'( cn ) MAY ( defaultServerList $ preferredServerList $ defaultSearchBase $ defaultSearchScope $ searchTimeLimit $ bindTimeLimit $ credentialLevel $ authenticationMethod $ followReferrals $ dereferenceAliases $ serviceSearchDescriptor $ serviceCredentialLevel $ serviceAuthenticationMethod $ objectclassMap $ attributeMap $ profileTTL )'" X-ORIGIN 'RFC 4876'"
6418N/A
6418N/A EE['1.3.18.0.2.6.2549']="'slpService' DESC 'DUMMY definition' SUP top MUST objectclass"
6421N/A OD['1.3.6.1.4.1.6252.2.27.6.2.1']="'slpService' DESC 'parent superclass for SLP services' SUP top ABSTRACT MUST "'( template-major-version-number $ template-minor-version-number $ description $ template-url-syntax $ service-advert-service-type $ service-advert-scopes ) MAY ( service-advert-url-authenticator $ service-advert-attribute-authenticator )'" X-ORIGIN 'RFC 2926'"
6418N/A
6418N/A EE['1.3.18.0.2.6.254']="'slpServicePrinter' DESC 'Service Location Protocol (SLP) information.' SUP slpService AUXILIARY"
6418N/A OD['1.3.18.0.2.6.254']="'slpServicePrinter' DESC 'Service Location Protocol (SLP) information.' SUP slpService AUXILIARY X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.6.258']="'printerAbstract' DESC 'Printer related information.' SUP top ABSTRACT MAY "'( printer-name $ printer-natural-language-configured $ printer-location $ printer-info $ printer-more-info $ printer-make-and-model $ printer-multiple-document-jobs-supported $ printer-charset-configured $ printer-charset-supported $ printer-generated-natural-language-supported $ printer-document-format-supported $ printer-color-supported $ printer-compression-supported $ printer-pages-per-minute $ printer-pages-per-minute-color $ printer-finishings-supported $ printer-number-up-supported $ printer-sides-supported $ printer-media-supported $ printer-media-local-supported $ printer-resolution-supported $ printer-print-quality-supported $ printer-job-priority-supported $ printer-copies-supported $ printer-job-k-octets-supported $ printer-current-operator $ printer-service-person $ printer-delivery-orientation-supported $ printer-stacking-order-supported $ printer-output-features-supported )'
6418N/A OD['1.3.18.0.2.6.258']="'printerAbstract' DESC 'Printer related information.' SUP top ABSTRACT MAY "'( printer-name $ printer-natural-language-configured $ printer-location $ printer-info $ printer-more-info $ printer-make-and-model $ printer-multiple-document-jobs-supported $ printer-charset-configured $ printer-charset-supported $ printer-generated-natural-language-supported $ printer-document-format-supported $ printer-color-supported $ printer-compression-supported $ printer-pages-per-minute $ printer-pages-per-minute-color $ printer-finishings-supported $ printer-number-up-supported $ printer-sides-supported $ printer-media-supported $ printer-media-local-supported $ printer-resolution-supported $ printer-print-quality-supported $ printer-job-priority-supported $ printer-copies-supported $ printer-job-k-octets-supported $ printer-current-operator $ printer-service-person $ printer-delivery-orientation-supported $ printer-stacking-order-supported $ printer-output-features-supported )'" X-ORIGIN 'RFC 3712' )"
6418N/A
6418N/A EE['1.3.18.0.2.6.255']="'printerService' DESC 'Printer information.' SUP printerAbstract STRUCTURAL MAY "'( printer-uri $ printer-xri-supported )'
6418N/A OD['1.3.18.0.2.6.255']="'printerService' DESC 'Printer information.' SUP printerAbstract STRUCTURAL MAY "'( printer-uri $ printer-xri-supported )'" X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.6.257']="'printerServiceAuxClass' DESC 'Printer information.' SUP printerAbstract AUXILIARY MAY "'( printer-uri $ printer-xri-supported )'
6418N/A OD['1.3.18.0.2.6.257']="'printerServiceAuxClass' DESC 'Printer information.' SUP printerAbstract AUXILIARY MAY "'( printer-uri $ printer-xri-supported )'" X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.6.256']="'printerIPP' DESC 'Internet Printing Protocol (IPP) information.' SUP top AUXILIARY MAY "'( printer-ipp-versions-supported $ printer-multiple-document-jobs-supported )'
6418N/A OD['1.3.18.0.2.6.256']="'printerIPP' DESC 'Internet Printing Protocol (IPP) information.' SUP top AUXILIARY MAY "'( printer-ipp-versions-supported $ printer-multiple-document-jobs-supported )'" X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.18.0.2.6.253']="'printerLPR' DESC 'LPR information.' SUP top AUXILIARY MUST printer-name MAY printer-aliases"
6418N/A OD['1.3.18.0.2.6.253']="'printerLPR' DESC 'LPR information.' SUP top AUXILIARY MUST ( printer-name ) MAY ( printer-aliases ) X-ORIGIN 'RFC 3712'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.14']="'sunPrinter' DESC 'Sun printer information' SUP top AUXILIARY MUST printer-name MAY "'( sun-printer-bsdaddr $ sun-printer-kvp )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.14']="'sunPrinter' DESC 'Sun printer information' SUP top AUXILIARY MUST printer-name MAY "'(sun-printer-bsdaddr $ sun-printer-kvp)'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.12']="'nisplusTimeZoneData' DESC 'NIS+ timezone table data' SUP top STRUCTURAL MUST cn MAY "'( nisplusTimeZone $ description )'
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.12']="'nisplusTimeZoneData' DESC 'NIS+ timezone table data' SUP top STRUCTURAL MUST cn MAY "'( nisplusTimeZone $ description )'" X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.8']="'ipTnetTemplate' DESC 'Object class for TSOL network templates' SUP top MUST ipTnetTemplateName MAY SolarisAttrKeyValue"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.8']="'ipTnetTemplate' DESC 'Object class for TSOL network templates' SUP top STRUCTURAL MUST ipTnetTemplateName MAY SolarisAttrKeyValue X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A EE['1.3.6.1.4.1.42.2.27.5.2.9']="'ipTnetHost' DESC 'Associates an IP address or wildcard with a TSOL template_name' SUP top AUXILIARY MUST ipTnetNumber"
6418N/A OD['1.3.6.1.4.1.42.2.27.5.2.9']="'ipTnetHost' DESC 'Associates an IP address or wildcard with a TSOL template_name' SUP top AUXILIARY MUST ipTnetNumber X-ORIGIN 'Solaris Specific'"
6418N/A
6418N/A # obey CLI syntax force option (if any)
6418N/A if (( TMPF[SYNTAX] == 1 )); then
6418N/A typeset -n MAP=OD
6418N/A elif (( TMPF[SYNTAX] == 2 )); then
6418N/A typeset -n MAP=EE
6418N/A elif (( TMPF[IS_OPENDJ] )); then
6418N/A typeset -n MAP=OD
6418N/A else
6418N/A typeset -n MAP=EE
6418N/A fi
6418N/A
6418N/A # we need to preserve order, so 2 passes
6418N/A typeset TODO='' OID
6418N/A for OID in ${!MAP[@]}; do
6418N/A [[ -n ${OID2ODEF[${OID}]} ]] && continue
6418N/A TODO+="${OID} "
6418N/A done
6418N/A
6418N/A if [[ -z ${TODO} ]]; then
6418N/A X='Schema contains all required objectclass defintions'
6418N/A else
6418N/A # 2nd pass
6418N/A typeset X SORTED
6418N/A SORTED=${ print ${TODO// /$'\n'} | sort -n -t. ; }
6418N/A TODO='' TODO2=''
6418N/A for OID in ${SORTED} ; do
6418N/A X="${MAP[${OID}]}"
6418N/A OID2ODEF["${OID}"]="${X}"
6418N/A # 1.3.18.0.2.6.254 requires 1.3.18.0.2.6.2549
6418N/A # 1.3.18.0.2.6.255,1.3.18.0.2.6.257 require 1.3.18.0.2.6.258
6418N/A [[ ${OID} == '1.3.18.0.2.6.254' \
6418N/A || ${OID} == '1.3.18.0.2.6.255' \
6418N/A || ${OID} == '1.3.18.0.2.6.257' ]] \
6418N/A && TODO2+='objectclasses: ( '"${OID} NAME ${X}"' )\n' \
6418N/A || TODO+='objectclasses: ( '"${OID} NAME ${X}"' )\n'
6418N/A done
6418N/A
6418N/A nextFile modify $0
6418N/A print 'dn: cn=schema\nchangetype: modify\nadd: objectclasses' \
6418N/A "\n${TODO}${TODO2}" >${TMP[FILE]}
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Adding objectclass definitions to schema failed'
6418N/A return 67
6418N/A fi
6418N/A X='Schema objectclass definitions added'
6418N/A fi
6418N/A
6418N/A showProgress "${X}."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_suffix '' '[+NAME?add_suffix - add suffix to DS if needed.]
6418N/A[+DESCRIPTION?Add a suffix to the DS if needed (\bTMPF[NEED_CREATE_SUFFIX]]\b is set) and optionally create the backend for it (\bTMPF[NEED_CREATE_BACKEND]]\b is set). Suffix entry and backend MUST be prepared by \bprep_create_sfx_entry()\b and \bprep_create_sfx_backend()\b correspondingly to have the following vars set:]{
6418N/A [+STR[LDAP_SUFFIX]] ]
6418N/A [+STR[DS_DB]] ]
6418N/A [+TMP[SUFFIX_OBJ]] ]
6418N/A [+TMP[SUFFIX_ATT]] ]
6418N/A [+TMP[SUFFIX_VAL]] ]
6418N/A}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (suffix not needed or created successfully).]
6418N/A [+1?otherwise (unable to create suffix).]
6418N/A}
6418N/A[+SEE ALSO?\bldapadd\b(1), \bdisplay_msg()\b.]
6418N/A'
6418N/Afunction add_suffix {
6418N/A if (( ! TMPF[NEED_CREATE_BACKEND] )); then
6418N/A showProgress "Database backend exists."
6418N/A else
6418N/A nextFile add "${0}-backend"
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A print '
6418N/Adn: ds-cfg-backend-id='"${STR[DS_DB]}"',cn=Backends,cn=config
6418N/Ads-cfg-backend-id: '"${STR[DS_DB]}"'
6418N/Ads-cfg-base-dn: '"${STR[LDAP_SUFFIX]}"'
6418N/Aobjectclass: top
6418N/Aobjectclass: ds-cfg-backend
6418N/Aobjectclass: ds-cfg-local-db-backend
6418N/Ads-cfg-java-class: org.opends.server.backends.jeb.BackendImpl
6418N/Ads-cfg-enabled: true
6418N/Ads-cfg-writability-mode: enabled
6418N/Ads-cfg-preload-time-limit: 0 ms
6418N/Ads-cfg-compact-encoding: true
6418N/Ads-cfg-entries-compressed: false
6418N/Ads-cfg-index-entry-limit: 4000
6418N/Ads-cfg-db-directory: db
6418N/Ads-cfg-db-directory-permissions: 700
6418N/Ads-cfg-disk-low-threshold: 100 mb
6418N/Ads-cfg-disk-full-threshold: 20 mb
6418N/Ads-cfg-db-run-cleaner: true
6418N/Ads-cfg-db-cleaner-min-utilization: 50
6418N/Ads-cfg-db-logging-file-handler-on: true
6418N/Ads-cfg-db-logging-level: CONFIG
6418N/Ads-cfg-db-log-filecache-size: 100
6418N/Ads-cfg-db-log-file-max: 10 mb
6418N/Ads-cfg-db-cache-size: 0 b
6418N/Ads-cfg-db-cache-percent: 50
6418N/Ads-cfg-db-evictor-core-threads: 1
6418N/Ads-cfg-db-evictor-max-threads: 10
6418N/Ads-cfg-db-evictor-nodes-per-scan: 10
6418N/Ads-cfg-db-evictor-lru-only: true
6418N/Ads-cfg-db-evictor-keep-alive: 600 s
6418N/Ads-cfg-db-txn-no-sync: false
6418N/Ads-cfg-db-txn-write-no-sync: true
6418N/Ads-cfg-db-checkpointer-wakeup-interval: 30 s
6418N/Ads-cfg-db-checkpointer-bytes-interval: 20 mb
6418N/A' >${TMP[FILE]}
6418N/A else
6418N/A print '
6418N/Adn: cn="'"${STR[LDAP_SUFFIX]}"'",cn=mapping tree,cn=config
6418N/Aobjectclass: top
6418N/Aobjectclass: extensibleObject
6418N/Aobjectclass: nsMappingTree
6418N/Acn: '"${STR[LDAP_SUFFIX]}"'
6418N/Ansslapd-state: backend
6418N/Ansslapd-backend: '"${STR[DS_DB]}"'
6418N/A
6418N/Adn: cn='"${STR[DS_DB]}"',cn=ldbm database,cn=plugins,cn=config
6418N/Aobjectclass: top
6418N/Aobjectclass: extensibleObject
6418N/Aobjectclass: nsBackendInstance
6418N/Acn: '"${STR[DS_DB]}"'
6418N/Ansslapd-suffix: '"${STR[LDAP_SUFFIX]}"'
6418N/A' >${TMP[FILE]}
6418N/A fi
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Unable to create backend' "'${STR[DS_DB]}'" \
6418N/A 'with suffix' "'${STR[LDAP_SUFFIX]}'" 'due to server error.'
6418N/A return 1
6418N/A fi
6418N/A showProgress "Database backend created."
6418N/A fi
6418N/A
6418N/A if (( ! TMPF[NEED_CREATE_SUFFIX] )); then
6418N/A showProgress "Suffix exists."
6418N/A else
6418N/A nextFile add $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_SUFFIX]}"'
6418N/Aobjectclass: top
6418N/Aobjectclass: '"${TMP[SUFFIX_OBJ]}"'
6418N/A'"${TMP[SUFFIX_ATT]}: ${TMP[SUFFIX_VAL]}"'
6418N/A' >${TMP[FILE]}
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.warn 'Unable to create entry' "'${STR[LDAP_SUFFIX]}'" 'of' \
6418N/A "'${TMP[SUFFIX_OBJ]}'" 'class'
6418N/A return 1
6418N/A fi
6418N/A showProgress "Suffix added."
6418N/A fi
6418N/A return 0
6418N/A}
6418N/A
6418N/Afunction add_suffix_aci {
6418N/A typeset PW_STATE PW_STATE_RO ANY_NO_READ SELF_NO_WRITE
6418N/A typeset ADMIN_DN ADMIN_GROUP_DN
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A # TBD: include Password Policy State extended ops ?
6418N/A
6418N/A # password state information aka ds-pwp-*, pwd* and ds-pta-* WITHOUT
6418N/A # attrs, which are schema flagged with NO-USER-MODIFICATION
6418N/A PW_STATE=' ds-pwp-account-disabled || ds-pwp-account-expiration-time
6418N/A || ds-pwp-last-login-time || ds-pwp-password-changed-by-required-time
6418N/A || ds-pwp-password-policy-dn || ds-pwp-reset-time || ds-pwp-warned-time
6418N/A || ds-privilege-name || pwdReset'
6418N/A # password state information flagged with NO-USER-MODIFICATION
6418N/A # ds-pwp-password-expiration-time is the same as pwdExpirationTime
6418N/A # so save some parse time ;-)
6418N/A PW_STATE_RO=' pwdExpirationTime || pwdChangedTime || pwdGraceUseTime
6418N/A || pwdFailureTime || pwdHistory || pwdAccountLockedTime'
6418N/A # People using PassThroughAuthentication probably wish that too:
6418N/A #PW_STATE_RO+='|| ds-pta-cached-password || ds-pta-cached-password-time'
6418N/A
6418N/A # passwords + password state
6418N/A ANY_NO_READ="userPassword || authPassword ||${PW_STATE}||${PW_STATE_RO}"
6418N/A # aci + search limits aka ds-rlim-* + RW password state/policy
6418N/A SELF_NO_WRITE='aci || ds-rlim-idle-time-limit
6418N/A || ds-rlim-lookthrough-limit || ds-rlim-size-limit || ds-rlim-time-limit
6418N/A || pwdPolicySubentry ||'"${PW_STATE}"
6418N/A ADMIN_DN='uid=admin,cn=Administrators'
6418N/A ADMIN_GROUP_DN='cn=Administrators'
6418N/A ADMIN_DN+=',cn=admin data'
6418N/A ADMIN_GROUP_DN+=',cn=admin data'
6418N/A else
6418N/A # DSEE
6418N/A # password state information aka passwordObject
6418N/A PW_STATE=' accountUnlockTime || passwordAllowChangeTime
6418N/A || passwordExpWarned || passwordExpirationTime || passwordHistory
6418N/A || passwordRetryCount || retryCountResetTime'
6418N/A
6418N/A # passwords + password state
6418N/A ANY_NO_READ="userPassword ||${PW_STATE}"
6418N/A # aci + search limits + password state/policy
6418N/A SELF_NO_WRITE='aci || nsIdleTimeout || nsLookThroughLimit
6418N/A || nsSizeLimit || nsTimeLimit || nsroledn || passwordPolicySubentry
6418N/A ||'"${PW_STATE}"
6418N/A ADMIN_DN='uid=admin,ou=Administrators'
6418N/A ADMIN_GROUP_DN='cn=Configuration Administrators,ou=Groups'
6418N/A ADMIN_DN+=',ou=TopologyManagement,o=NetscapeRoot'
6418N/A ADMIN_GROUP_DN+=',ou=TopologyManagement,o=NetscapeRoot"'
6418N/A fi
6418N/A
6418N/A typeset -A RULES=(
6418N/A [SFX_ANYONE_ACI_NAME]='aci: (targetattr != "'"${ANY_NO_READ//$'\n'}"'")
6418N/A (
6418N/A version 3.0; acl "'"${SFX_ANYONE_ACI_NAME}"'";
6418N/A allow (read, search, compare) userdn = "ldap:///anyone";
6418N/A )'
6418N/A [SFX_SELF_ACI_NAME]='aci: (targetattr != "'"${SELF_NO_WRITE//$'\n'}"'")
6418N/A (
6418N/A version 3.0; acl "'"${SFX_SELF_ACI_NAME}"'";
6418N/A allow (write) userdn = "ldap:///self";
6418N/A )'
6418N/A [SFX_ADMIN_ACI_NAME]='aci: (targetattr = "*")
6418N/A (
6418N/A version 3.0; acl "'"${SFX_ADMIN_ACI_NAME}"'";
6418N/A allow (all) userdn = "ldap:///'"${ADMIN_DN}"'";
6418N/A )'
6418N/A [SFX_ADMINGRP_ACI_NAME]='aci: (targetattr ="*")
6418N/A (
6418N/A version 3.0; acl "'"${SFX_ADMINGRP_ACI_NAME}"'";
6418N/A allow (all) groupdn = "ldap:///'"${ADMIN_GROUP_DN}"'";
6418N/A )'
6418N/A )
6418N/A
6418N/A # Check and set if doesn't already exist
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST "${STR[LDAP_SUFFIX]}"
6418N/A
6418N/A for ACI in "${!RULES[@]}" ; do
6418N/A typeset -n NAME=${ACI}
6418N/A [[ -z ${NAME} ]] && continue # if it has no name, ignore it
6418N/A PATTERN='acl[ ]+"?'"${NAME}"'"?'
6418N/A findACI LIST "${NAME}" "${PATTERN}" 'Suffix' || continue # exists
6418N/A nextFile add "${0}-${NAME}"
6418N/A print '
6418N/Adn: '"${STR[LDAP_SUFFIX]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/A'"${RULES[${ACI}]}"'
6418N/A' >${TMP[FILE]}
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.warn "Adding '${NAME}' suffix ACI failed"
6418N/A return 1
6418N/A fi
6418N/A showProgress "Suffix ACI '${NAME}' added."
6418N/A done
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_base_objects '' '[+NAME?add_base_objects - add possibly missing, necessary base objects.]
6418N/A[+DESCRIPTION?Determine all RDNs required to form the \bSTR[LDAP_BASEDN]]\b using the suffix \bSTR[LDAP_SUFFIX]]\b (RDN1,RDN2,...,suffix == baseDN) and create the missing entries.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (all entries available or created successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bnormalizeDN()\b, \bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_base_objects {
6418N/A # typeset -A STR
6418N/A # STR[LDAP_BASEDN]=dc=x,dc=my,dc=do,dc=main,dc=de
6418N/A # STR[LDAP_SUFFIX]=dc=do,dc=main,dc=de
6418N/A
6418N/A # Convert to lower case for basename.
6418N/A typeset LC_DN=','${ normalizeDN "${STR[LDAP_BASEDN]}" l ; }
6418N/A typeset LC_SFX=','${ normalizeDN "${STR[LDAP_SUFFIX]}" l ; }
6418N/A
6418N/A # first, test that baseDN ends with suffix
6418N/A if [[ ${LC_DN: -${#LC_SFX}} != ${LC_SFX} ]]; then
6418N/A # should not happen since check_basedn_suffix() succeeded
6418N/A Log.fatal "Invalid suffix '${LC_SFX}' for Base DN '${LC_DN}'"
6418N/A return 66
6418N/A fi
6418N/A # Save the stuff before LC_SFX w/o leading ',' -> further called prefix
6418N/A LC_DN=${LC_DN:1:${#LC_DN}-${#LC_SFX}-1}
6418N/A
6418N/A # Remove redundant spaces around ',' and '=' first from LDAP_BASEDN
6418N/A typeset DN=${ normalizeDN ${STR[LDAP_BASEDN]} ; }
6418N/A
6418N/A # Now LC_DN and DN differ at most in lower vs. uppercase character and
6418N/A # we can get the prefix of the baseDN by just copying corresponding chars
6418N/A DN=",${DN:0:${#LC_DN}}"
6418N/A
6418N/A if [[ ${DN} == ',' ]]; then
6418N/A X='No need to create a DN component (baseDN equals suffix)'
6418N/A else
6418N/A typeset LAST=${ normalizeDN ${STR[LDAP_SUFFIX]} ; } DC KEY VAL CLASS
6418N/A X="Created DN components for ${DN#,}"
6418N/A while [[ -n ${DN} ]]; do
6418N/A # Get trailing key=val (DC) from DN and strip it off
6418N/A DN=${DN%,*}
6418N/A DC="${.sh.match#,}"
6418N/A LAST="${DC},${LAST}"
6418N/A
6418N/A # Check if entry exists first, if so, skip to next.
6418N/A ${LDAPSEARCH} ${CON_ARGS} -b "${LAST}" -s base \
6418N/A 'objectclass=*' >/dev/null 2>&1 && continue
6418N/A
6418N/A VAL=${DC#*=}
6418N/A KEY=${.sh.match%=}
6418N/A # Determine the objectclass for the entry.
6418N/A CLASS=${ get_objectclass ${KEY} ; }
6418N/A if [[ -z ${CLASS} ]]; then
6418N/A Log.fatal "Unable to determine objectClass for '${KEY}'." \
6418N/A "Please create the following entry and re-run ${PROG}:" \
6418N/A "${KEY}=${VAL},${LAST}"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-${LAST}"
6418N/A print '
6418N/Adn: '"${LAST}"'
6418N/A'"${KEY}: ${VAL}"'
6418N/AobjectClass: top
6418N/AobjectClass: '"${CLASS}"'
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]}\
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Update of base objects '${DC}' failed"
6418N/A return 66
6418N/A fi
6418N/A done
6418N/A fi
6418N/A showProgress "${X}."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc set_nisdomain '' '[+NAME?set_nisdomain - Add the NisDomainObject to the Base DN.]
6418N/A[+DESCRIPTION?Add a NisDomainObject with nisdomain \bSTR[LDAP_DOMAIN]]\b to the \bSTR[LDAP_BASEDN]]\b unless there is already one.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction set_nisdomain {
6418N/A # Check if nisDomain is already set
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${STR[LDAP_BASEDN]}" \
6418N/A -s base 'objectclass=*' 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A if [[ ${LINE} == ~(Ei)^nisDomain= ]]; then
6418N/A showProgress 'NisDomainObject was already set for' \
6418N/A "'${STR[LDAP_BASEDN]}'."
6418N/A return 0
6418N/A fi
6418N/A done
6418N/A
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aobjectclass: nisDomainObject
6418N/Anisdomain: '"${STR[LDAP_DOMAIN]}"'
6418N/A' >${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Update of NisDomainObject in '${STR[LDAP_BASEDN]}' failed"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "NisDomainObject added to '${STR[LDAP_BASEDN]}'."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_new_containers '' '[+NAME?add_new_containers - Add top level containers to the base DN.]
6418N/A[+DESCRIPTION?Add the Name Service Switch top level containers to the \bSTR[LDAP_BASEDN]]\b unless they already exist.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\b/etc/nsswitch.ldap\b, \bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_new_containers {
6418N/A typeset OU
6418N/A
6418N/A for OU in people group rpc protocols networks netgroup \
6418N/A aliases hosts services ethers profile printers projects \
6418N/A SolarisAuthAttr SolarisProfAttr Timezone ipTnet
6418N/A do
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "ou=${OU},${STR[LDAP_BASEDN]}" -s base 'objectclass=*' \
6418N/A >/dev/null 2>&1
6418N/A then
6418N/A showProgress "'ou=${OU}' exists."
6418N/A continue
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-${OU}"
6418N/A print '
6418N/Adn: ou='"${OU},${STR[LDAP_BASEDN]}"'
6418N/Aou: '"${OU}"'
6418N/AobjectClass: top
6418N/AobjectClass: organizationalUnit
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding 'ou=${OU}' failed"
6418N/A return 66
6418N/A fi
6418N/A showProgress "'ou=${OU}' added."
6418N/A done
6418N/A
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_auto_maps '' '[+NAME?add_auto_maps - Add the automount map entries.]
6418N/A[+DESCRIPTION?Add the automount maps \bauto_home\b, \bauto_direct\b, \bauto_master\b, \bauto_shared\b to \bSTR[LDAP_BASEDN]]\b unless they already exist.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_auto_maps {
6418N/A # AUTO_MAPS for maps to create
6418N/A typeset AUTO_MAPS="auto_home auto_direct auto_master auto_shared" MAP
6418N/A
6418N/A for MAP in ${AUTO_MAPS}; do
6418N/A # Check if automap already exist
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "automountMapName=${MAP},${STR[LDAP_BASEDN]}" -s base \
6418N/A 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A showProgress "'${MAP}' automount exists."
6418N/A continue
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-${MAP}"
6418N/A print '
6418N/Adn: automountMapName='"${MAP},${STR[LDAP_BASEDN]}"'
6418N/AautomountMapName: '"${MAP}"'
6418N/AobjectClass: top
6418N/AobjectClass: automountMap
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${MAP}' automount map failed"
6418N/A return 66
6418N/A fi
6418N/A showProgress "'${MAP}' automount added."
6418N/A done
6418N/A
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc modify_top_aci '' '[+NAME?modify_top_aci - add a deny self modify ACI.]
6418N/A[+DESCRIPTION?Add the ACI \bUSER_ACI_NAME\b to \bSTR[LDAP_BASEDN]]\b to disable self modify of user attributes like uid, uidNumber, gidNumber, shadowExpire, etc. This does nothing if an ACI with the same name already exists for this entry.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage USER_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (ACI already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bgetACIs()\b, \bfindACI()\b, \bldapmodify\b(1).]
6418N/A'
6418N/Afunction modify_top_aci {
6418N/A typeset PATTERN
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST || return 66
6418N/A
6418N/A # check, whether ACI already exists
6418N/A PATTERN='acl[ ]+"?('"${USER_ACI_NAME}|${USER_ACI_NAME// /_}"')"?'
6418N/A findACI LIST "${USER_ACI_NAME}" "${PATTERN}" || return 0 # exists
6418N/A
6418N/A # Create LDIF for top level ACI
6418N/A nextFile modify $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_BASEDN]}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/Aaci: (targetattr = "cn || uid || uidNumber || gidNumber || homeDirectory || shadowLastChange || shadowMin || shadowMax || shadowWarning || shadowInactive || shadowExpire || shadowFlag || memberUid || SolarisAttrKeyValue || SolarisAttrReserved1 || SolarisAttrReserved2 || SolarisUserQualifier")
6418N/A (
6418N/A version 3.0; acl "'"${USER_ACI_NAME}"'";
6418N/A deny (write) userdn = "ldap:///self";
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Deny user to change non-password attributes failed'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "Self modify for non-password attributes disabled."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_vlv_aci '' '[+NAME?add_vlv_aci - Add ACI for VLV.]
6418N/A[+DESCRIPTION?Add the global ACI to allow everyone read-only access to VLVs.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage VLV_ACI_NAME ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (ACI added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_vlv_aci {
6418N/A # VLV Request = 2.16.840.1.113730.3.4.9
6418N/A typeset RULE='version 3.0; acl "'"${VLV_ACI_NAME}"'";\n\t'
6418N/A RULE+='allow (read,search,compare) userdn = "ldap:///anyone";'
6418N/A typeset DN='oid=2.16.840.1.113730.3.4.9,cn=features,cn=config'
6418N/A (( TMPF[IS_OPENDJ] )) && DN='cn=Access Control Handler,cn=config'
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST "${DN}" 'Global' || return 66
6418N/A
6418N/A PATTERN='acl[ ]+"?('"${VLV_ACI_NAME}|${VLV_ACI_NAME// /_}"')"?'
6418N/A findACI LIST "${VLV_ACI_NAME}" "${PATTERN}" 'Global' || return 0
6418N/A
6418N/A nextFile modify $0
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A print '
6418N/Adn: '"${DN}"'
6418N/Achangetype: modify
6418N/Aadd: ds-cfg-global-aci
6418N/Ads-cfg-global-aci: (targetcontrol = "2.16.840.1.113730.3.4.9")(targetattr != "aci")
6418N/A (
6418N/A '"${RULE}"'
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A else
6418N/A print '
6418N/Adn: '"${DN}"'
6418N/Achangetype: modify
6418N/Areplace: aci
6418N/Aaci: (targetattr != "aci")
6418N/A (
6418N/A '"${RULE}"'
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A fi
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${VLV_ACI_NAME}' global ACI failed"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress "Global ACI '${VLV_ACI_NAME}' added."
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_proxyagent '' '[+NAME?add_proxyagent - Add proxy agent user to DS.]
6418N/A[+DESCRIPTION?Add the proxy agent user \bSTR[LDAP_PROXYAGENT]]\b to the DS unless it already exists to allow nameservice access to the server.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (entry already exists or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_proxyagent {
6418N/A # Check if proxy agent already exists
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "${STR[LDAP_PROXYAGENT]}" -s base 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A showProgress "Proxyagent identity exists."
6418N/A return 0
6418N/A fi
6418N/A
6418N/A # Get cn and sn names from LDAP_PROXYAGENT.
6418N/A typeset NAME="${STR[LDAP_PROXYAGENT]%%,*}"
6418N/A NAME=${NAME#*=}
6418N/A
6418N/A # Add the entry
6418N/A nextFile add $0
6418N/A print '
6418N/Adn: '"${STR[LDAP_PROXYAGENT]}"'
6418N/Acn: '"${NAME}"'
6418N/Asn: '"${NAME}"'
6418N/Aobjectclass: top
6418N/Aobjectclass: person
6418N/Auserpassword: '"${STR[LDAP_PROXYAGENT_CRED]}"'
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Adding proxyagent identity failed'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A showProgress 'Proxyagent identity added.'
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_entry_by_DN '' '[+NAME?add_entry_by_DN - Add an ldif file by DN.]
6418N/A[+DESCRIPTION?Add the entries in the given LDIF \afile\a to the DS unless a base entry for \aDN\a already exists.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (\aDN\a already exists or added successfully).]
6418N/A [+1?on error (failed to add entries).]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bldapadd\b(1).]
6418N/A\n\n\aDN\a \afile\a
6418N/A'
6418N/Afunction add_entry_by_DN {
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "$1" -s base \
6418N/A 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A showProgress "'${1}' exists."
6418N/A return 0
6418N/A fi
6418N/A if ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f "$2" >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A showProgress "'${1}' added."
6418N/A return 0
6418N/A fi
6418N/A Log.fatal "Adding '${1}' failed"
6418N/A return 1
6418N/A}
6418N/A
6418N/AMan.addFunc add_id_mapping_rules '' '[+NAME?add_id_mapping_rules - Add Kerberos principal to DN mapping rules to the DS.]
6418N/A[+DESCRIPTION?Add GSSAPI identity mapping rules for host credentails and user credentials to the DS config unless they already exists. Hosts are matched against \b*.STR[LDAP_DOMAIN]]@STR[LDAP_KRB_REALM]]\b and ou=hosts in \bSTR[LDAP_BASEDN]]\b, users against \b*.@STR[LDAP_KRB_REALM]]\b and uid=$1,ou=People in \bSTR[LDAP_BASEDN]]\b.]
6418N/A[+SEE ALSO?\badd_entry_by_DN()\b.]
6418N/A'
6418N/Afunction add_id_mapping_rules {
6418N/A Log.info 'Adding Kerberos principal to DN mapping rules ...'
6418N/A typeset C_DN='cn=GSSAPI,cn=identity mapping,cn=config' OC='nsContainer'
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A # we create a new branch instead of reusing the default, possibly unused
6418N/A # 'cn=Regular Expression,cn=Identity Mappers,cn=config' GSSAPI ID mapper
6418N/A C_DN='cn=GSSAPI,cn=Identity Mappers,cn=config'
6418N/A OC='ds-cfg-branch'
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-krbPrincipal"
6418N/A print '
6418N/Adn: cn='"${C_DN}"'
6418N/AobjectClass: top
6418N/AobjectClass: '"${OC}"'
6418N/Acn: GSSAPI
6418N/A' > ${TMP[FILE]}
6418N/A add_entry_by_DN "${C_DN}" ${TMP[FILE]} || return
6418N/A
6418N/A typeset H_CN="host_auth_${STR[LDAP_KRB_REALM]}"
6418N/A typeset H_DN="cn=${H_CN}, ${C_DN}"
6418N/A nextFile add "${0}-krbHostAuth"
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A print '
6418N/A# For now (2.6.0) OpenDJ supports a single-valued ds-cfg-identity-mapper, only.
6418N/A# So either you merge this and the next Identity Mapper to something more useful
6418N/A# together or just enable one of them until it gets fixed. For more information
6418N/A# see https://bugster.forgerock.org/jira/browse/OPENDJ-521
6418N/Adn: '"${H_DN}"'
6418N/Acn: '"${H_CN}"'
6418N/AobjectClass: top
6418N/AobjectClass=ds-cfg-identity-mapper
6418N/AobjectClass=ds-cfg-regular-expression-identity-mapper
6418N/Ads-cfg-java-class=org.opends.server.extensions.RegularExpressionIdentityMapper
6418N/Ads-cfg-enabled=false
6418N/Ads-cfg-match-base-dn=ou=hosts,'"${STR[LDAP_BASEDN]}"'
6418N/Ads-cfg-match-pattern=host\/(.*).'"${STR[LDAP_DOMAIN]}@${STR[LDAP_KRB_REALM]}"'
6418N/Ads-cfg-replace-pattern=$1
6418N/Ads-cfg-match-attribute=cn
6418N/A' > ${TMP[FILE]}
6418N/A else
6418N/A print '
6418N/Adn: '"${H_DN}"'
6418N/AobjectClass: top
6418N/AobjectClass: nsContainer
6418N/AobjectClass: dsIdentityMapping
6418N/AobjectClass: dsPatternMatching
6418N/Acn: '"${H_CN}"'
6418N/AdsMatching-pattern: ${Principal}
6418N/AdsMatching-regexp: host\/(.*).'"${STR[LDAP_DOMAIN]}@${STR[LDAP_KRB_REALM]}"'
6418N/AdsSearchBaseDN: ou=hosts,'"${STR[LDAP_BASEDN]}"'
6418N/AdsSearchFilter: (&(objectClass=ipHost)(cn=$1))
6418N/AdsSearchScope: one
6418N/A' > ${TMP[FILE]}
6418N/A fi
6418N/A add_entry_by_DN "${H_DN}" ${TMP[FILE]}
6418N/A
6418N/A typeset U_CN="user_auth_${STR[LDAP_KRB_REALM]}"
6418N/A typeset U_DN="cn=${U_CN}, ${C_DN}"
6418N/A nextFile add "${0}-krbUserAuth"
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A print '
6418N/Adn: '"${U_DN}"'
6418N/Acn: '"${U_CN}"'
6418N/AobjectClass: top
6418N/AobjectClass=ds-cfg-identity-mapper
6418N/AobjectClass=ds-cfg-regular-expression-identity-mapper
6418N/Ads-cfg-java-class=org.opends.server.extensions.RegularExpressionIdentityMapper
6418N/Ads-cfg-enabled=true
6418N/Ads-cfg-match-base-dn=ou=People,'"${STR[LDAP_BASEDN]}"'
6418N/Ads-cfg-match-pattern=(.*)@'"${STR[LDAP_KRB_REALM]}"'
6418N/Ads-cfg-replace-pattern=$1
6418N/Ads-cfg-match-attribute=uid
6418N/A' > ${TMP[FILE]}
6418N/A else
6418N/A print '
6418N/Adn: '"${U_DN}"'
6418N/AobjectClass: top
6418N/AobjectClass: nsContainer
6418N/AobjectClass: dsIdentityMapping
6418N/AobjectClass: dsPatternMatching
6418N/Acn: '"${U_CN}"'
6418N/AdsMatching-pattern: ${Principal}
6418N/AdsMatching-regexp: (.*)@'"${STR[LDAP_KRB_REALM]}"'
6418N/AdsMappedDN: uid=$1,ou=People,'"${STR[LDAP_BASEDN]}"'
6418N/A' > ${TMP[FILE]}
6418N/A fi
6418N/A add_entry_by_DN "${U_DN}" ${TMP[FILE]}
6418N/A}
6418N/A
6418N/AMan.addFunc modify_userpassword_acl_for_gssapi '' '[+NAME?modify_userpassword_acl_for_gssapi - Allow hosts and user to read password(s).]
6418N/A[+DESCRIPTION?Modify ACL to allow hosts to read all and a user to read its own password only, when sasl/GSSAPI bind is used.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success (entries already exist or added successfully).]
6418N/A [+>= 66?a fatal error occured.]
6418N/A}
6418N/A[+SEE ALSO?\badd_entry_by_DN()\b.]
6418N/A'
6418N/Afunction modify_userpassword_acl_for_gssapi {
6418N/A typeset P_DN="ou=People,${STR[LDAP_BASEDN]}"
6418N/A typeset H_DN="ou=Hosts,${STR[LDAP_BASEDN]}"
6418N/A
6418N/A if ! ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${P_DN}" -s base \
6418N/A 'objectclass=*' > /dev/null 2>&1
6418N/A then
6418N/A Log.verbose "'${P_DN}' does not exist"
6418N/A
6418N/A nextFile add $0
6418N/A print '
6418N/Adn: '"${P_DN}"'
6418N/Aou: People
6418N/AobjectClass: top
6418N/AobjectClass: organizationalUnit
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A add_entry_by_DN "${P_DN}" ${TMP[FILE]}
6418N/A else
6418N/A Log.verbose "'${P_DN}' already exists"
6418N/A fi
6418N/A typeset TARGET='userPassword' PATTERN
6418N/A (( TMPF[IS_OPENDJ] )) && TARGET+=' || authPassword'
6418N/A
6418N/A typeset -A RULES=(
6418N/A [SELF_GSS_ACI_NAME]='aci: (targetattr = "'"${TARGET}"'")
6418N/A (
6418N/A version 3.0; acl self-read-pwd;
6418N/A allow (read,search) userdn="ldap:///self" and authmethod="sasl GSSAPI";
6418N/A )'
6418N/A [HOST_GSS_ACI_NAME]='aci: (targetattr = "'"${TARGET}"'")
6418N/A (
6418N/A version 3.0; acl host-read-pwd;
6418N/A allow (read,search) userdn="ldap:///cn=*+ipHostNumber=*,ou=Hosts,'"${STR[LDAP_BASEDN]}"'" and authmethod="sasl GSSAPI";
6418N/A )'
6418N/A )
6418N/A
6418N/A typeset -a LIST=( )
6418N/A getACIs LIST "${P_DN}" || return 66
6418N/A
6418N/A for ACI in "${!RULES[@]}" ; do
6418N/A typeset -n NAME=${ACI}
6418N/A [[ -z ${NAME} ]] && continue # if it has no name, ignore it
6418N/A PATTERN='acl[ ]+"?'"${NAME}"'"?'
6418N/A findACI LIST "${NAME}" "${PATTERN}" 'ou=people' || continue # exists
6418N/A nextFile add "${0}-${NAME}"
6418N/A print '
6418N/Adn: '"${P_DN}"'
6418N/Achangetype: modify
6418N/Aadd: aci
6418N/A'"${RULES[${ACI}]}"'
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.warn "Adding '${NAME}' ou=people ACI failed."
6418N/A return 67
6418N/A fi
6418N/A showProgress "ou=people ACI '${NAME}' added."
6418N/A done
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_profile '' '[+NAME?add_profile - Add client profile to server.]
6418N/A[+DESCRIPTION?Generates a client profile and adds it to the DS as "\bcn=STR[LDAP_PROFILE_NAME]],ou=profile,STR[LDAP_BASEDN]]\b" unless it already exists and \bTMPF[DEL_OLD_PROFILE]]\b is not set. Other profile related variables are:]{
6418N/A [+?STR[LDAP_SERVER_LIST]] ]
6418N/A [+?STR[LDAP_SEARCH_SCOPE]] ]
6418N/A [+?STR[LDAP_CRED_LEVEL]] ]
6418N/A [+?STR[LDAP_AUTHMETHOD]] ]
6418N/A [+?INT[LDAP_FOLLOWREF]] ]
6418N/A [+?INT[LDAP_SEARCH_TIME_LIMIT]] ]
6418N/A [+?INT[LDAP_PROFILE_TTL]] ]
6418N/A [+?INT[LDAP_BIND_LIMIT]] ]
6418N/A [+?STR[LDAP_PREF_SRVLIST]] ]
6418N/A [+?STR[LDAP_SRV_AUTHMETHOD_PAM]] ]
6418N/A [+?STR[LDAP_SRV_AUTHMETHOD_KEY]] ]
6418N/A [+?STR[LDAP_SRV_AUTHMETHOD_CMD]] ]
6418N/A [+?SSD]
6418N/A}
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage INT STR SSD ; }" '}
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?fatal error.]
6418N/A}
6418N/A[+SEE ALSO?\bldapclient\b(1M), \bldapdelete\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_profile {
6418N/A # If profile name already exists, DELETE it, and add new one
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "cn=${STR[LDAP_PROFILE_NAME]},ou=profile,${STR[LDAP_BASEDN]}" \
6418N/A -s base 'objectclass=*' >/dev/null 2>&1
6418N/A then
6418N/A if (( ! TMPF[DEL_OLD_PROFILE] )); then
6418N/A Log.fatal "Adding client profile name '${STR[LDAP_PROFILE_NAME]}'" \
6418N/A 'failed (entry already exists)'
6418N/A return 66
6418N/A fi
6418N/A
6418N/A nextFile delete $0
6418N/A print "cn=${STR[LDAP_PROFILE_NAME]},ou=profile,${STR[LDAP_BASEDN]}" \
6418N/A >${TMP[FILE]}
6418N/A if ! ${LDAPDELETE} ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Attempt to DELETE old client profile' \
6418N/A "'${STR[LDAP_PROFILE_NAME]}' failed"
6418N/A return 67
6418N/A fi
6418N/A fi
6418N/A
6418N/A # Build the "ldapclient genprofile" command string to execute
6418N/A typeset -a ARG=( )
6418N/A ARG+=( genprofile '-a' "profileName=${STR[LDAP_PROFILE_NAME]}" )
6418N/A
6418N/A # Add required argument defaultSearchBase
6418N/A ARG+=( -a "defaultSearchBase=${STR[LDAP_BASEDN]}" )
6418N/A
6418N/A # Add optional parameters
6418N/A [[ -n ${STR[LDAP_SERVER_LIST]} ]] && \
6418N/A ARG+=( -a "defaultServerList=${STR[LDAP_SERVER_LIST]}" )
6418N/A [[ -n ${STR[LDAP_SEARCH_SCOPE]} ]] && \
6418N/A ARG+=( -a "defaultSearchScope=${STR[LDAP_SEARCH_SCOPE]}" )
6418N/A [[ -n ${STR[LDAP_CRED_LEVEL]} ]] && \
6418N/A ARG+=( -a "credentialLevel=${STR[LDAP_CRED_LEVEL]}" )
6418N/A [[ -n ${STR[LDAP_AUTHMETHOD]} ]] && \
6418N/A ARG+=( -a "authenticationMethod=${STR[LDAP_AUTHMETHOD]}" )
6418N/A (( INT[LDAP_FOLLOWREF] )) && X='TRUE"' || X='FALSE"'
6418N/A ARG+=( -a "followReferrals=${X}" )
6418N/A (( INT[LDAP_SEARCH_TIME_LIMIT] )) && \
6418N/A ARG+=( -a "searchTimeLimit=${INT[LDAP_SEARCH_TIME_LIMIT]}" )
6418N/A (( INT[LDAP_PROFILE_TTL] )) && \
6418N/A ARG+=( -a "profileTTL=${INT[LDAP_PROFILE_TTL]}" )
6418N/A [[ -n ${INT[LDAP_BIND_LIMIT]} ]] && \
6418N/A ARG+=( -a "bindTimeLimit=${INT[LDAP_BIND_LIMIT]}" )
6418N/A [[ -n ${STR[LDAP_PREF_SRVLIST]} ]] && \
6418N/A ARG+=( -a "preferredServerList=${STR[LDAP_PREF_SRVLIST]}" )
6418N/A [[ -n ${STR[LDAP_SRV_AUTHMETHOD_PAM]} ]] && \
6418N/A ARG+=(-a "serviceAuthenticationMethod=${STR[LDAP_SRV_AUTHMETHOD_PAM]}")
6418N/A [[ -n ${STR[LDAP_SRV_AUTHMETHOD_KEY]} ]] && \
6418N/A ARG+=(-a "serviceAuthenticationMethod=${STR[LDAP_SRV_AUTHMETHOD_KEY]}")
6418N/A [[ -n ${STR[LDAP_SRV_AUTHMETHOD_CMD]} ]] && \
6418N/A ARG+=(-a "serviceAuthenticationMethod=${STR[LDAP_SRV_AUTHMETHOD_CMD]}")
6418N/A
6418N/A # Add SSDs
6418N/A typeset X
6418N/A for X in "${SSD[@]}" ; do
6418N/A ARG+=( -a "serviceSearchDescriptor=${X}" )
6418N/A done
6418N/A
6418N/A # Execute "ldapclient genprofile" to create profile
6418N/A nextFile add $0
6418N/A if ! ${LDAPCLIENT} "${ARG[@]}" >${TMP[FILE]} 2>${TMP[DIR]}/gen_profile.err
6418N/A then
6418N/A Log.fatal 'ldapclient genprofile failed'
6418N/A return 68
6418N/A fi
6418N/A
6418N/A # Add the generated profile
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A log.fatal 'Attempt to add profile failed!'
6418N/A return 69
6418N/A fi
6418N/A
6418N/A showProgress 'Client profile generated and pushed to the DS.'
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc checkTaskCompletion '' '[+NAME?checkTaskCompletion - Wait and check completion of a DS task.]
6418N/A[+DESCRIPTION?Checks the state of the DS task with the given \adn\a periodically until it got stopped due to an error or has been finished successfully, or the timeout has been hit. Timeout is an integer and specifies the number of seconds to max. wait for completion. If not given or invalid 60 will be used instead.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+1?task failed.]
6418N/A [+2?timeout has been hit, task not yet finished or has an unknown state.]
6418N/A}
6418N/A[+See Also?\bldapsearch\b(1)]
6418N/A\n\n\adn\a [\atimeout\a]
6418N/A'
6418N/Afunction checkTaskCompletion {
6418N/A typeset DN="$1" STATUS='nstaskstatus=' TASKID X
6418N/A integer TIMEOUT=${2:-${INT[TASK_TIMEOUT]}} RESULT=2 SEEN
6418N/A (( TIMEOUT < 10 )) && TIMEOUT=60
6418N/A (( TMPF[IS_OPENDJ] )) && STATUS='ds-task-state='
6418N/A TASKID=${DN%%,*}
6418N/A # Wait for task to finish, display current status.
6418N/A while (( TIMEOUT > 0 )) ; do
6418N/A SEEN=0 X=''
6418N/A ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "${DN}" -s base 'objectclass=*' ${STATUS%=} 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A [[ ${LINE%%,*} == ${TASKID} ]] && SEEN=1 && continue
6418N/A [[ -z ${X} && ${LINE:0:${#STATUS}} == ${STATUS} ]] && \
6418N/A X=${LINE:${#STATUS}}
6418N/A done
6418N/A (( ! SEEN )) && break # an error occured
6418N/A print -n '.'
6418N/A [[ ${X} =~ Finished || ${X} == 'COMPLETED_SUCCESSFULLY' ]] && \
6418N/A RESULT=0 && break
6418N/A [[ ${X:0:12} == 'Index failed' || ${X:016} == 'STOPPED_BY_ERROR' ]] && \
6418N/A RESULT=1 && break
6418N/A sleep 1
6418N/A (( TIMEOUT-=1 ))
6418N/A done
6418N/A # DSEE removes non-recurring tasks automagically, OpenDJ not
6418N/A (( RESULT < 2 && TMPF[IS_OPENDJ] )) && \
6418N/A ${LDAPDELETE} ${CON_ARGS} "${AUTH_ARGS[@]}" "${DN}" >&${TMPF[FD]} 2>&1
6418N/A return ${RESULT}
6418N/A}
6418N/A
6418N/AMan.addFunc rebuildIndex '' '[+NAME?rebuildIndex - Rebuild a single index.]
6418N/A[+DESCRIPTION?Instruct the DS to rebuild the index with the name \aname\a. If the \aname\a starts with "vlv." it indicates a Virtual List View, which is supported for OpenDJ, only. Wrt. to OpenDJ and VLVs a return code of \b0\b does not necessaryly mean, that the index is finally in a non-degraded state. It just means, the task has been executed successfully.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+1?if a VLV index was specified, but the current DS is != OpenDJ/OpenDS.]
6418N/A [+2?if the task failed or did not complete within 60 seconds.]
6418N/A [+66?if scheduling a rebuild task on the DS failed.]
6418N/A}
6418N/A[+SEE ALSO?\bcheckTaskCompletion()\b, \bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A\n\n\aname\a
6418N/A'
6418N/Afunction rebuildIndex {
6418N/A typeset IDX=$1
6418N/A TASKNAME=${IDX}_${ date "+%Y_%m_%d_%H_%M_%S" ; }
6418N/A
6418N/A if [[ ${IDX:0:4} == 'vlv.' ]] && (( ! TMPF[IS_OPENDJ] )) ; then
6418N/A Log.warn 'Non-OpenDJ/OpenDS servers do not support VLV rebuildTasks'
6418N/A return 1
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-task-${TASKNAME}"
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A # NOTE: rebuildTask requires ldif-import LDAP privilege.
6418N/A # It's a little bit inefficient: one could schedule a single task at
6418N/A # the end of the function and use 'rebuildall' or a space separated
6418N/A # list of all attributes in ds-task-rebuild-index to do it at once.
6418N/A DN='ds-task-id='"${TASKNAME}"',cn=Scheduled Tasks,cn=Tasks'
6418N/A print '
6418N/A# rebuild-index --index '"${IDX}"' --baseDN '"${STR[LDAP_BASEDN]}"' \
6418N/A# '"${CON_ARGS} ${AUTH_ARGS[@]}"' -X
6418N/A
6418N/Adn: '"${DN}"'
6418N/Ads-task-id: '"${TASKNAME}"'
6418N/AobjectClass: top
6418N/AobjectClass: ds-task
6418N/AobjectClass: ds-task-rebuild
6418N/Ads-task-class-name: org.opends.server.tasks.RebuildTask
6418N/Ads-task-rebuild-base-dn: '"${STR[LDAP_SUFFIX]}"'
6418N/Ads-task-rebuild-index: '"${IDX}"'
6418N/A#ds-task-rebuild-tmp-directory:
6418N/A' > ${TMP[FILE]}
6418N/A else
6418N/A DN='cn='"${TASKNAME}"',cn=index,cn=tasks,cn=config'
6418N/A print '
6418N/Adn: '"${DN}"'
6418N/Acn: '"${TASKNAME}"'
6418N/Aobjectclass: top
6418N/Aobjectclass: extensibleObject
6418N/AnsInstance: '"${STR[DS_DB]}"'
6418N/AnsIndexAttribute: '"${IDX}"'
6418N/A' > ${TMP[FILE]}
6418N/A fi
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding task for '${IDX}' failed"
6418N/A return 66
6418N/A fi
6418N/A
6418N/A checkTaskCompletion "${DN}" && print "" || { Log.warn 'FAILED'; return 2; }
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_indexes '' '[+NAME?add_indexes - Add indexes.]
6418N/A[+DESCRIPTION?Add indexes of the given \atypes\a (e.g. "pres eq") for the given \aattributes\a (e.g. "uidNumber gidnumber") and schedule corresponding tasks to actually create the indexes unless they already exist. Both arguments are handle as a whitespace separated list.]
6418N/A[+RETURN VALUES]{
6418N/A [+-1?syntax error (insufficient parameters).]
6418N/A [+0?on success.]
6418N/A [+>= 66?fatal error.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A\n\n\atypes\a \aattributes\a
6418N/A'
6418N/Afunction add_indexes {
6418N/A if [[ -z ${STR[DS_DB]} ]]; then
6418N/A get_backend || return 66
6418N/A fi
6418N/A [[ -z $1 || -z $2 ]] && Log.warn "${.sh.fun}(): syntax error" && return -1
6418N/A
6418N/A typeset -l TYPES=${1//,/ } # we allow comma separated lists as well
6418N/A typeset IDX=${2//,/ }
6418N/A
6418N/A Log.verbose "Processing '${TYPES// /,}' indexes ..."
6418N/A
6418N/A typeset DN="cn=index,cn=${STR[DS_DB]},cn=ldbm database,cn=plugins,cn=config"
6418N/A typeset LTYPE="nsIndexType: ${TYPES// /$'\n'nsIndexType: }"
6418N/A typeset ATTR='cn' OC='extensibleObject' DST TASKNAME LINE X
6418N/A integer SEEN
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A OC='ds-cfg-branch'
6418N/A DN="cn=Index,ds-cfg-backend-id=${STR[DS_DB]},cn=Backends,cn=config"
6418N/A ATTR='ds-cfg-attribute'
6418N/A LTYPE=''
6418N/A for X in ${TYPES}; do
6418N/A [[ $X == 'eq' ]] && LTYPE+='ds-cfg-index-type: equality\n'
6418N/A [[ $X == 'pres' ]] && LTYPE+='ds-cfg-index-type: presence\n'
6418N/A [[ $X == 'sub' ]] && LTYPE+='ds-cfg-index-type: substring\n'
6418N/A done
6418N/A fi
6418N/A
6418N/A # check, whether Index container exists - if not, create it
6418N/A if ! ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${DN}" \
6418N/A -s base 'objectclass=*' > /dev/null 2>&1
6418N/A then
6418N/A nextFile add $0
6418N/A X=${DN%%,*}
6418N/A print '
6418N/Adn: '"${DN}"'
6418N/AobjectClass: top
6418N/AobjectClass: '"${OC}"'
6418N/Acn: '"${X#*=}"'
6418N/A' >${TMP[FILE]}
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Failed to add backend Index base'
6418N/A return 66
6418N/A fi
6418N/A fi
6418N/A
6418N/A for DST in ${IDX} ; do
6418N/A # Check if entry exists first. If so, skip to next
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" \
6418N/A -b "${ATTR}=${DST},${DN}" -s base 'objectclass=*' > /dev/null 2>&1
6418N/A then
6418N/A showProgress "'${DST}' index exists."
6418N/A continue
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-${DST}"
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A X=${LTYPE//'\n'/ }
6418N/A X=${X//: /:}
6418N/A print '
6418N/A# dsconfig create-local-db-index '"${CON_ARGS} ${AUTH_ARGS[@]}"' -X \
6418N/A# '"${X//ds-cfg-/--set }"' \
6418N/A# --backend-name '"${STR[DS_DB]}"' --index-name '"${DST}"'
6418N/A
6418N/Adn: ds-cfg-attribute='"${DST},${DN}"'
6418N/Ads-cfg-attribute: '"${DST}"'
6418N/AobjectClass: top
6418N/AobjectClass: ds-cfg-local-db-index
6418N/A'"${LTYPE}"'
6418N/A' > ${TMP[FILE]}
6418N/A else
6418N/A print '
6418N/Adn: cn='"${DST},${DN}"'
6418N/AobjectClass: top
6418N/AobjectClass: nsIndex
6418N/Acn: '"${DST}"'
6418N/AnsSystemIndex: false
6418N/A'"${LTYPE}"'
6418N/A' > ${TMP[FILE]}
6418N/A fi
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${DST}' backend index failed"
6418N/A return 67
6418N/A fi
6418N/A showProgress "'${DST}' backend index added."
6418N/A rebuildIndex ${DST}
6418N/A done
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc add_eq_indexes '' '[+NAME?add_eq_indexes - Add indexes of type pres and eq.]
6418N/A[+DESCRIPTION?Add eq,pres indexes and schedule corresponding tasks to actually create the indexes unless they already exist.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?fatal error.]
6418N/A}
6418N/A[+SEE ALSO?\badd_indexes()\b.]
6418N/A'
6418N/Afunction add_eq_indexes {
6418N/A add_indexes "pres eq" \
6418N/A "uidNumber ipNetworkNumber gidnumber oncrpcnumber automountKey"
6418N/A}
6418N/A
6418N/AMan.addFunc add_sub_indexes '' '[+NAME?add_sub_indexes - Add indexes of type pres, eq and sub.]
6418N/A[+DESCRIPTION?Add eq,pres,sub indexes and schedule corresponding tasks to actually create the indexes unless they already exist.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?fatal error.]
6418N/A}
6418N/A[+SEE ALSO?\badd_indexes()\b.]
6418N/A'
6418N/Afunction add_sub_indexes {
6418N/A add_indexes "pres eq sub" \
6418N/A "ipHostNumber membernisnetgroup nisnetgrouptriple"
6418N/A}
6418N/A
6418N/AMan.addFunc add_vlv_indexes_OpenDJ '' '[+NAME?add_vlv_indexes_OpenDJ - Add VLV indexes to OpenDS/OpenDJ.]
6418N/A[+DESCRIPTION?OpenDS/OpenDJ specialized part of \badd_vlv_indexes()\b (pulled out for easier maintenance).]
6418N/A[+SEE ALSO?\badd_vlv_indexes()\b, https://blogs.oracle.com/kanthi/entry/ldap_paged_results_more]
6418N/A[+NOTES?\bpagedResultsControl\b and \bVLV\b is per default allowed for authenticated users, only. To check, try something like this:]{
6418N/A [+?ldapsearch -r -j /tmp/pw -D "cn=Directory Manager" -h ldaphost \]
6418N/A [+? -b "cn=Access Control Handler,cn=config" "objectclass=*" | \]
6418N/A [+? egrep "1.2.840.113556.1.4.319|2.16.840.1.113730.3.4.9"]
6418N/A}
6418N/A\n\n\avname\a \afile\a
6418N/A'
6418N/Afunction add_vlv_indexes_OpenDJ {
6418N/A typeset -n INDEX_TABLE=$1
6418N/A typeset OUT="$2" ENTRY IDX_NAME CN SCOPE='single-level' BASE FILTER
6418N/A
6418N/A [[ ${STR[LDAP_SEARCH_SCOPE]} == sub ]] && SCOPE='subordinate-subtree'
6418N/A BACKEND="cn=VLV Index,ds-cfg-backend-id=${STR[DS_DB]},cn=Backends,cn=config"
6418N/A
6418N/A # check, whether VLV Index container exists - if not, create it
6418N/A if ! ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -b "${BACKEND}" \
6418N/A -s base 'objectclass=*' > /dev/null 2>&1
6418N/A then
6418N/A nextFile add $0
6418N/A print '
6418N/Adn: '"${BACKEND}"'
6418N/AobjectClass: top
6418N/AobjectClass: ds-cfg-branch
6418N/Acn: VLV Index
6418N/A' >${TMP[FILE]}
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal 'Adding VLV Index base'
6418N/A return 66
6418N/A fi
6418N/A fi
6418N/A
6418N/A integer COUNT=0
6418N/A # create index entries
6418N/A for ENTRY in "${INDEX_TABLE[@]}" ; do
6418N/A typeset -a F=( ${ENTRY} ) # split columns
6418N/A
6418N/A IDX_NAME="${STR[LDAP_DOMAIN]}.get${F[0]}"
6418N/A BASE="ou=${F[2]},${STR[LDAP_BASEDN]}"
6418N/A [[ ${F[2]} =~ = ]] && BASE="${BASE:3}" # cut out ou=
6418N/A FILTER="objectClass=${F[3]}"
6418N/A [[ ${F[3]:0:1} == '&' ]] && FILTER="&(objectClass=${F[3]:2}"
6418N/A
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -s base \
6418N/A -b "ds-cfg-name=${IDX_NAME},${BACKEND}" 'objectclass=*' \
6418N/A > /dev/null 2>&1
6418N/A then
6418N/A showProgress "'${IDX_NAME}' VLV index exists."
6418N/A continue
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-${IDX_NAME}"
6418N/A print '
6418N/A# dsconfig create-local-db-vlv-index '"${CON_ARGS} ${AUTH_ARGS[@]}"' -X \
6418N/A# --backend-name "'"${STR[DS_DB]}"'" \
6418N/A# --set "base-dn:'"${BASE}"'" \
6418N/A# --index-name '"${IDX_NAME}"' --set "sort-order:cn uid" \
6418N/A# --set "scope:'"${SCOPE}"'" --set "filter:'"${FILTER}"'"
6418N/A
6418N/Adn: ds-cfg-name='"${IDX_NAME},${BACKEND}"'
6418N/AobjectClass: top
6418N/AobjectClass: ds-cfg-local-db-vlv-index
6418N/Ads-cfg-name: '"${IDX_NAME}"'
6418N/Ads-cfg-base-dn: '"${BASE}"'
6418N/Ads-cfg-scope: '"${SCOPE}"'
6418N/Ads-cfg-filter: '"${FILTER}"'
6418N/Ads-cfg-sort-order: cn uid
6418N/Aaci: (targetattr = "*")
6418N/A (
6418N/A version 3.0; acl "Config";
6418N/A allow (read,search,compare) userdn="ldap:///anyone";
6418N/A )
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${IDX_NAME}' VLV index failed"
6418N/A return 67
6418N/A fi
6418N/A showProgress "'${IDX_NAME}' VLV index added."
6418N/A
6418N/A if rebuildIndex "vlv.${IDX_NAME}" ; then
6418N/A (( COUNT++ ))
6418N/A else
6418N/A print "rebuild-index -b '${STR[LDAP_SUFFIX]}' " \
6418N/A "--index 'vlv.${IDX_NAME}'" >>${OUT}
6418N/A fi
6418N/A done
6418N/A if (( COUNT )); then
6418N/A # Bug or feature: Even if scheduled as task, VLV idx rebuild leaves
6418N/A # the index in degraded state. So:
6418N/A showProgress 'Rebuilding degraded indexes.'
6418N/A if ! rebuildIndex rebuilddegraded ; then
6418N/A print "svcadm disable opendj@VERS@\n" \
6418N/A "rebuild-index -b '${STR[LDAP_SUFFIX]}' --rebuildDegraded\n" \
6418N/A "svcadm enable opendj@VERS@"
6418N/A >>${OUT}
6418N/A fi
6418N/A fi
6418N/A}
6418N/A
6418N/AMan.addFunc add_vlv_indexes_DSEE '' '[+NAME?add_vlv_indexes_DSEE - Add VLV indexes to DSEE.]
6418N/A[+DESCRIPTION?DSEE specialized part of \badd_vlv_indexes()\b (pulled out for easier maintenance).]
6418N/A[+SEE ALSO?\b\badd_vlv_indexes()\b.]
6418N/A\n\n\avname\a \afile\a
6418N/A'
6418N/Afunction add_vlv_indexes_DSEE {
6418N/A typeset -n INDEX_TABLE=$1
6418N/A typeset OUT="$2" ENTRY IDX_NAME CN SCOPE=1 BASE FILTER
6418N/A
6418N/A typeset INFO=( ${TMP[DS_INFO]} )
6418N/A integer MAJOR=${INFO[${#INFO[@]}-2]}
6418N/A typeset INSTANCE="@serverInstance@" LINE
6418N/A ${LDAPSEARCH} -v ${CON_ARGS} "${AUTH_ARGS[@]}" -b 'cn=config' \
6418N/A -s base 'objectclass=*' nsslapd-instancedir 2>/dev/null | \
6418N/A while read LINE ; do
6418N/A [[ ${LINE:0:20} == 'nsslapd-instancedir=' ]] && LINE=${LINE:20} && break
6418N/A done
6418N/A if (( MAJOR < 6 )); then
6418N/A # DSEE 5.x only.
6418N/A [[ ${LINE} =~ slapd- ]] && LINE=${LINE#*/} && INSTANCE=${LINE#*-}
6418N/A else
6418N/A # 6+ - the instance path
6418N/A INSTANCE="${LINE}"
6418N/A fi
6418N/A [[ ${STR[LDAP_SEARCH_SCOPE]} == sub ]] && SCOPE=2
6418N/A BACKEND="cn=${STR[DS_DB]},cn=ldbm database,cn=plugins,cn=config"
6418N/A
6418N/A # create index entries
6418N/A for ENTRY in "${INDEX_TABLE[@]}" ; do
6418N/A typeset -a F=( ${ENTRY} ) # split columns
6418N/A
6418N/A IDX_NAME="${STR[LDAP_DOMAIN]}.get${F[0]}"
6418N/A CN="${STR[LDAP_DOMAIN]}_${F[1]}_vlv_index"
6418N/A BASE="ou=${F[2]},${STR[LDAP_BASEDN]}"
6418N/A [[ ${F[2]} =~ = ]] && BASE="${BASE:3}" # cut out ou=
6418N/A FILTER="objectClass=${F[3]}"
6418N/A [[ ${F[3]:0:1} == '&' ]] && FILTER="&(objectClass=${F[3]:2}"
6418N/A
6418N/A if ${LDAPSEARCH} ${CON_ARGS} "${AUTH_ARGS[@]}" -s base \
6418N/A -b "cn=${IDX_NAME},cn=${CN},${BACKEND}" 'objectclass=*' \
6418N/A > /dev/null 2>&1
6418N/A then
6418N/A showProgress "'${IDX_NAME}' VLV index exists."
6418N/A continue
6418N/A fi
6418N/A
6418N/A nextFile add "${0}-${IDX_NAME}"
6418N/A print '
6418N/Adn: '"cn=${CN},${BACKEND}"'
6418N/AobjectClass: top
6418N/AobjectClass: vlvSearch
6418N/Acn: '"${CN}"'
6418N/Avlvbase: '"${BASE}"'
6418N/Avlvscope: '${SCOPE}'
6418N/Avlvfilter: ('"${FILTER}"')
6418N/Aaci: (target = "ldap:///'"cn=${CN},${BACKEND}"'") (targetattr = "*")
6418N/A (
6418N/A version 3.0; acl "Config";
6418N/A allow (read,search,compare) userdn="ldap:///anyone";
6418N/A )
6418N/A
6418N/Adn: cn='"${IDX_NAME},cn=${CN},${BACKEND}"'
6418N/Acn: '"${IDX_NAME}"'
6418N/AvlvSort: cn uid
6418N/Aobjectclass: top
6418N/Aobjectclass: vlvIndex
6418N/A' > ${TMP[FILE]}
6418N/A
6418N/A if ! ${LDAPMODIFY} -a ${CON_ARGS} "${AUTH_ARGS[@]}" -f ${TMP[FILE]} \
6418N/A >&${TMPF[FD]} 2>&1
6418N/A then
6418N/A Log.fatal "Adding '${IDX_NAME}' VLV index failed"
6418N/A return 66
6418N/A fi
6418N/A showProgress "'${IDX_NAME}' VLV index added."
6418N/A
6418N/A if (( MAJOR < 6 )); then
6418N/A # DSEE 5.x
6418N/A print "directoryserver -s '${INSTANCE}' vlvindex" \
6418N/A "-n '${STR[DS_DB]}' -T '${IDX_NAME}'" >> ${OUT}
6418N/A else
6418N/A # assume DSEE 6+
6418N/A print "dsadm reindex -l -t '${IDX_NAME}'" \
6418N/A "'${INSTANCE}' '${STR[LDAP_SUFFIX]}'" >> ${OUT}
6418N/A fi
6418N/A done
6418N/A}
6418N/A
6418N/AMan.addFunc add_vlv_indexes '' '[+NAME?add_vlv_indexes - Add VLV indexes.]
6418N/A[+DESCRIPTION?Create VLV indexes entries on the \bSTR[DS_DB]]\b for \bSTR[LDAP_DOMAIN]]\b with \bSTR[LDAP_SEARCH_SCOPE]]\b and create the script \bTMP[DIR]]/do_vlv_index\b to be started on the DS to actually re-index the DB.]
6418N/A[+RETURN VALUES]{
6418N/A [+0?on success.]
6418N/A [+>= 66?fatal error.]
6418N/A}
6418N/A[+SEE ALSO?\bldapsearch\b(1), \bldapmodify\b(1).]
6418N/A'
6418N/Afunction add_vlv_indexes {
6418N/A Log.verbose 'Processing VLV indexes ...'
6418N/A
6418N/A # F[0] F[1] F[2] F[3]
6418N/A # ${LDAP_DOMAIN}.get ${LDAP_DOMAIN}_%s_vlv_index ou=%s objectClass=$1||&(%s)
6418N/A typeset -a INDEXES=(
6418N/A 'grent group group posixGroup'
6418N/A 'hostent hosts hosts ipHost'
6418N/A 'netent networks networks ipNetwork'
6418N/A 'pwent passwd people posixAccount'
6418N/A 'rpcent rpc rpc oncRpc'
6418N/A 'spent shadow people shadowAccount'
6418N/A # Indexes added during NIS to LDAP transition
6418N/A 'auhoent auho automountMapName=auto_home automount'
6418N/A 'soluent solu people SolarisUserAttr'
6418N/A 'authent auth SolarisAuthAttr SolarisAuthAttr'
6418N/A 'execent exec SolarisProfAttr &(SolarisExecAttr)(SolarisKernelSecurityPolicy=*)'
6418N/A 'profent prof SolarisProfAttr &(SolarisProfAttr)(SolarisAttrLongDesc=*)'
6418N/A 'mailent mail aliases mailGroup'
6418N/A 'bootent _boot ethers &(bootableDevice)(bootParameter=*)'
6418N/A 'ethent ethers ethers &(ieee802Device)(macAddress=*)'
6418N/A 'ngrpent netgroup netgroup nisNetgroup'
6418N/A 'ipnent ipn networks &(ipNetwork)(cn=*)'
6418N/A 'maskent mask networks &(ipNetwork)(ipNetmaskNumber=*)'
6418N/A 'prent pr printers printerService'
6418N/A 'ip4ent ip4 hosts &(ipHost)(ipHostNumber=*.*)'
6418N/A 'ip6ent ip6 hosts &(ipHost)(ipHostNumber=*:*)'
6418N/A )
6418N/A
6418N/A # temp file for vlvindex commands
6418N/A typeset OUT=${TMP[DIR]}/tmp
6418N/A rm -f ${OUT} && touch ${OUT}
6418N/A
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A add_vlv_indexes_OpenDJ INDEXES ${OUT}
6418N/A else
6418N/A add_vlv_indexes_DSEE INDEXES ${OUT}
6418N/A fi
6418N/A nextFile sh
6418N/A mv ${OUT} ${TMP[FILE]}
6418N/A TMP[VLV_CMDS]=${TMP[FILE]}
6418N/A}
6418N/A
6418N/AMan.addFunc display_vlv_cmds '' '[+NAME?display_vlv_cmds - Display VLV index commands to run on server.]
6418N/A[+DESCRIPTION?Display VLV index commands to run on server and save the file to /var/tmp/doIndexVLV-\bSTR[DS_HOST]].sh\b.]
6418N/A'
6418N/Afunction display_vlv_cmds {
6418N/A typeset SAV="/var/tmp/doIndexVLV-${STR[DS_HOST]}.sh"
6418N/A
6418N/A [[ -s ${TMP[VLV_CMDS]} ]] || return
6418N/A # some problems occured, so the file is not empty
6418N/A [[ -e ${SAV} ]] && SAV="${SAV%.sh}-$$.sh"
6418N/A cp -p ${TMP[VLV_CMDS]} "${SAV}"
6418N/A
6418N/A typeset MSG='NOTE: '"${PROG}"'configured the entries for VLV indexes.'
6418N/A if (( TMPF[IS_OPENDJ] )); then
6418N/A MSG+='
6418N/ATo create the actual VLV indexes, you need to stop the DS on the host
6418N/A'"'${STR[DS_HOST]}'"', e.g. using "svcadm disable -t opendj@VERS@"
6418N/Aor, if manually started, "ds-stop" and than run the commands shown in the file
6418N/A'"'${SAV}'"'. Than restart the DS e.g. using
6418N/A"svcadm enable opendj@VERS@" or "ds-start".
6418N/A'
6418N/A else
6418N/A typeset INFO=( ${DS_INFO[@]} )
6418N/A if (( INFO[1] >= 6 )); then
6418N/A MSG+='
6418N/AUse the dsadm command delivered with the DS on the host '"'${STR[DS_HOST]}'"'
6418N/Ato stop the server. Then, using dsadm, follow the dsadm examples shown in the
6418N/Afile '"'${SAV}'"' to create the actual VLV indexes.
6418N/A'
6418N/A else
6418N/A MSG+='
6418N/AUse the directoryserver(1m) script on the host '"'${STR[DS_HOST]}'"'
6418N/Ato stop the server. Then, using directoryserver, follow the directoryserver
6418N/Aexamples shown in the file '"'${SAV}'"' to create the
6418N/Aactual VLV indexes.
6418N/A'
6418N/A fi
6418N/A fi
6418N/A Log.info "\n\n${MSG}"
6418N/A}
6418N/A
6418N/AMan.addFunc doMain '' '[+NAME?doMain - the main entry point.]
6418N/A[+DESCRIPTION?The entry point, where the real work starts.]
6418N/A'
6418N/Afunction doMain {
6418N/A # Initialize the variables that need to be set to NULL, or some
6418N/A # other initial value before the rest of the functions can be called
6418N/A init || return 1
6418N/A show_vars
6418N/A
6418N/A # Print extra line to separate from prompt
6418N/A print
6418N/A
6418N/A # Either load the user specified config file or prompt user for config info
6418N/A if [[ -n ${TMP[IN]} ]]; then
6418N/A load_config_file "${TMP[IN]}"
6418N/A validate_info || return 1 # Validate basic info in file
6418N/A else
6418N/A display_msg 'backup_server'
6418N/A get_confirm 'Do you wish to continue with server setup (y/n/h)?' \
6418N/A 'n' 'backup_help' && return 1
6418N/A
6418N/A # Ask for all required infos
6418N/A prompt_config_info || return 1
6418N/A (( INT[LDAP_ENABLE_SHADOW_UPDATE] && INT[EXISTING_PROFILE] )) && \
6418N/A return 0 # just enabled shadow update in an existing profile
6418N/A # Allow user to modify results
6418N/A integer RES
6418N/A display_summary
6418N/A RES=$?
6418N/A # save the work for now, so that even on exit/errors it can be re-used
6418N/A [[ -n ${TMP[OUT]} ]] && create_config_file "${TMP[OUT]}"
6418N/A (( RES )) && return 1
6418N/A fi
6418N/A
6418N/A if (( INT[NEED_TIME] )); then
6418N/A modify_timelimit || return 1
6418N/A fi
6418N/A
6418N/A if (( INT[NEED_SIZE] )); then
6418N/A modify_sizelimit || return 1
6418N/A fi
6418N/A
6418N/A # Modify the password storage scheme to support CRYPT
6418N/A if (( INT[NEED_CRYPT] )); then
6418N/A modify_pwd_crypt || return 1
6418N/A fi
6418N/A
6418N/A # schema modifications
6418N/A modify_cn || return 1
6418N/A update_schema_attr || return 1
6418N/A update_schema_obj || return 1
6418N/A
6418N/A add_suffix || return 1
6418N/A
6418N/A # Add missing suffix ACIs
6418N/A add_suffix_aci || return 1
6418N/A
6418N/A # Add base objects (if needed)
6418N/A add_base_objects || return 1
6418N/A
6418N/A # Update the NisDomainObject.
6418N/A # The Base DN might of just been created, so this MUST happen after
6418N/A # the base objects have been added!
6418N/A set_nisdomain || return 1
6418N/A
6418N/A # Add top level classes (new containers)
6418N/A add_new_containers || return 1
6418N/A
6418N/A add_auto_maps || return 1
6418N/A
6418N/A modify_top_aci || return 1
6418N/A
6418N/A add_vlv_aci || return 1
6418N/A
6418N/A if (( INT[NEED_PROXY] )); then
6418N/A add_proxyagent || return 1
6418N/A if (( ! INT[LDAP_ENABLE_SHADOW_UPDATE] )); then
6418N/A allow_proxy_read_pw || return 1
6418N/A fi
6418N/A fi
6418N/A
6418N/A if (( INT[NEED_ADMIN] )); then
6418N/A add_admin || return 1
6418N/A allow_admin_read_write_shadow || return 1
6418N/A deny_non_admin_shadow_access || return 1
6418N/A fi
6418N/A
6418N/A if (( INT[GSSAPI_ENABLE] )); then
6418N/A add_id_mapping_rules
6418N/A # do not modify ACI if "sasl/GSSAPI" and "self" are not selected
6418N/A if [[ ${STR[LDAP_CRED_LEVEL]} == 'self' && \
6418N/A ${STR[LDAP_AUTHMETHOD]} == 'sasl/GSSAPI' ]]
6418N/A then
6418N/A modify_userpassword_acl_for_gssapi || return 1
6418N/A else
6418N/A Log.warn 'ACL for GSSAPI was not set because of incompatibility' \
6418N/A 'in profile'
6418N/A fi
6418N/A fi
6418N/A
6418N/A if (( INT[NEED_HOSTACL] )); then
6418N/A allow_host_read_write_shadow || return 66
6418N/A deny_non_host_shadow_access || return 67
6418N/A fi
6418N/A
6418N/A
6418N/A # Generate client profile and add it to the server
6418N/A add_profile || return 1
6418N/A
6418N/A # Add Indexes to improve search performance
6418N/A add_eq_indexes || return 1
6418N/A add_sub_indexes || return 1
6418N/A add_vlv_indexes || return 1
6418N/A
6418N/A # Display setup complete message
6418N/A Log.printMarker
6418N/A Log.info 'Setup of DS server' "'${STR[DS_HOST]}'" 'is complete.'
6418N/A Log.printMarker
6418N/A
6418N/A # Display VLV index commands to be executed on server (if any)
6418N/A display_vlv_cmds
6418N/A
6418N/A # Create final config file if requested
6418N/A [[ -n ${TMP[OUT]} ]] && create_config_file "${TMP[OUT]}"
6418N/A return 0
6418N/A}
6418N/A
6418N/AMan.addFunc cleanup '' '[+NAME?cleanup - cleanup tempfiles, tty and exit.]
6418N/A[+DESCRIPTION?Removes \aTMP[DIR]]\a unless \aTMPF[DEBUG]]\a is set and restores the echo for the tty.]
6418N/A[+ENVIRONMENT VARIABLES]{' "${ Man.varUsage TMP TMPF ; }" '}
6418N/A'
6418N/Afunction cleanup {
6418N/A (( TMPF[CLEANUP_DONE] )) && return
6418N/A if (( TMPF[DEBUG] )); then
6418N/A typeset X=${ ls -1 ${TMP[DIR]} 2>/dev/null ; }
6418N/A if [[ -z $X || $X == 'rootPWD' ]]; then
6418N/A rm -rf ${TMP[DIR]}
6418N/A else
6418N/A Log.info "Leaving temp dir ${TMP[DIR]} as is. Remove it manually"
6418N/A fi
6418N/A elif (( TMPF[KEEP] )); then
6418N/A typeset X=${ ls -1 ${TMP[DIR]} 2>/dev/null ; }
6418N/A if [[ -z $X || $X == 'rootPWD' ]]; then
6418N/A rm -rf ${TMP[DIR]}
6418N/A else
6418N/A Log.info "Keeping setup scripts and files in ${TMP[DIR]}"
6418N/A fi
6418N/A elif [[ -d ${TMP[DIR]} ]]; then
6418N/A rm -rf ${TMP[DIR]}
6418N/A fi
6418N/A ${STTY:-/usr/bin/stty} echo
6418N/A trap - EXIT 1 2 3 6 15
6418N/A # Might be trapped in the scope of a function which will stop executing
6418N/A # the function itself but not the script. So:
6418N/A [[ -z $1 ]] && kill $$
6418N/A TMPF[CLEANUP_DONE]=1
6418N/A}
6418N/A
6418N/A# debug helper function. Required to be not a 'function'!
6418N/AshowCommand() {
6418N/A typeset CMD="${.sh.command}"
6418N/A [[ -z ${CMD} ]] && return
6418N/A print -n -u2 '\E[0;30;47m'
6418N/A print -u2 -r -n "DEBUG: ${.sh.fun} '${CMD}'"
6418N/A print '\E[0m'
6418N/A}
6418N/A
6418N/AMan.addFunc MAIN '' '[+NAME?'"${PROG}"' - setup the infrastructure of a directory server to provide data and security required by the Solaris (or similar OS) LDAP Naming Services.]
6418N/A[+DESCRIPTION?This script assumes that the Sun/Oracle Directory Server Enterprise Edition (DSEE), or Sun OpenDS or Forgerock OpenDJ is installed and that its setup has been run. This script takes the directory server from that point and sets up the infrastructure for LDAP Naming Services. After running this script, \bldapaddent\b(1M) or some other tools can be used to populate data.]
6418N/A[h:help?Print this help and exit.]
6418N/A[F:functions?Print out a list of names of all currently defined script functions and exit (see \btypeset +f\b).]
6418N/A[H:usage]:[function?Show the usage info for the function with the given name if available and exit. (see also option \b-F\b).]
6418N/A[T:trace]:[fname_list?A comma or whitespace separated list of function names, which should be traced when running this script. If the list consist of the single word "ALL" or "*" all known functions get traced. "MAIN" is the special word to enable the trace of the main script. Gets activated as soon as this option gets processed, so option order might be important.]
6418N/A[d:debug?Enable really verbose debug info.]
6418N/A[C:no-color?Do not use ANSI escape codes to color the output.]
6418N/A[k:keep?Keep the files used to modify the DS. Files are enumerated and prefixed with the command to use for executing it so that one is able to do the same manually what this script did and thus may help to fine tune the setup of your DS. Actually it is recommended to run this script against a virgin DS and than re-use/adjust everything you need on your production system.]
6418N/A[I:importpwp?If specified, the storage scheme for Password Policy Import will be changed in the same way as the storage scheme for the Default Password Policy. If not specified, the storage scheme for Password Policy Import stays untouched. This option gets ignored for non-OpenDS/OpenDJ directory servers.]
6418N/A[i:in]:[file?Get setup info from the given file.]
6418N/A[o:out]:[file?Generate a server configuration output file.]
6418N/A[s:djSyntax?If given, the OpenDJ schema defintions will be used to complement the servers schema if needed, no matter which kind of server has been detected.]
6418N/A[S:eeSyntax?If given, the Sun DSEE schema defintions will be used to complement the servers schema if needed, no matter which kind of server has been detected.
6418N/AWrt. Solaris it should not make a difference, whether OpenDJ or DSEE syntax is used. OpenDJ syntax is usually a little bit more precise.]
6418N/A[t:timeout]:[seconds:=60?When this script creates an index, it also schedules a task to rebuild the index immediately. The \atimeout\a specifies, how long to wait for task completion. If the task gets not finished within the given time, the script treats that as an error and continues its work.]
6418N/A[v:verbose?Verbose mode - makes the script a little bit more chatty.]
6418N/A[+NOTES?This script should work for the following DS:]{
6418N/A [+?Sun DS 5.x]
6418N/A [+?Sun DSEE 6.x/7.x]
6418N/A [+?Oracle ODSEE 11g]
6418N/A [+?Sun OpenDS 2.x]
6418N/A [+?Forgerock OpenDJ 2.x]
6418N/A}
6418N/A'
6418N/A
6418N/ATMPF[DEBUG]=0 TMPF[KEEP]=0 TMPF[FD]=4
6418N/A
6418N/AX="${ print ${Man.FUNC[MAIN]} ; }"
6418N/Awhile getopts "${X}" option ; do
6418N/A case "${option}" in
6418N/A '?'|h) showUsage ${PROG} MAIN ; exit 0 ;;
6418N/A F) typeset +f ; exit 0 ;;
6418N/A T) if [[ ${OPTARG} == '*' || ${OPTARG} == 'ALL' ]]; then
6418N/A typeset -ft ${ typeset +f ; }
6418N/A elif [[ ${OPTARG} == 'MAIN' ]]; then
6418N/A set -x
6418N/A else
6418N/A typeset -ft ${OPTARG//,/ }
6418N/A fi
6418N/A ;;
6418N/A H) if [[ ${OPTARG%_t} != $OPTARG ]]; then
6418N/A $OPTARG --man # self-defined types
6418N/A else
6418N/A showUsage "$OPTARG" "$OPTARG" # functions
6418N/A fi
6418N/A exit 0
6418N/A ;;
6418N/A C) Log.COLORED=0 ;;
6418N/A d) TMPF[DEBUG]=1 ;;
6418N/A k) TMPF[KEEP]=1 ;;
6418N/A I) INT[NEED_CRYPT_IMPORT]=1 ;;
6418N/A i) TMP[IN]="${OPTARG}" ;;
6418N/A o) TMP[OUT]="${OPTARG}" ;;
6418N/A S) TMPF[SYNTAX]=2 ; print DSEE ;;
6418N/A s) TMPF[SYNTAX]=1 ; print DJ ;;
6418N/A t) is_numeric "${OPTARG}" && INT[TASK_TIMEOUT]=${OPTARG} ;;
6418N/A v) Log.VERBOSE=1 ; TMPF[FD]=1 ;;
6418N/A *) Log.fatal '**Internal ERROR: Supported option missing handler'
6418N/A exit 1
6418N/A ;;
6418N/A esac
6418N/Adone
6418N/AX=$(( OPTIND - 1 ))
6418N/Ashift $X
6418N/A(( TMPF[DEBUG] )) && Man.listVars
6418N/A
6418N/Aunset LC_ALL LC_LANG
6418N/Aexport LC_CTYPE=C # avoid any surprises
6418N/A
6418N/A# Create TMP[DIR]
6418N/ATMP[DIR]=${ mktemp -d /tmp/${PROG}.XXXXX ; }
6418N/Aif [[ -z ${TMP[DIR]} ]]; then
6418N/A Log.fatal 'Unable to create a safe temporary directory'
6418N/A exit 1
6418N/Afi
6418N/Atrap cleanup EXIT 1 2 3 6 15 # and register to cleanup on exit/signal
6418N/Aif (( TMPF[DEBUG] )); then
6418N/A trap 'typeset _CMD_="${.sh.command}"
6418N/A print -u2 -n "\E[0;30;47m"
6418N/A print -u2 -n -r "${.sh.fun:-MAIN}(): ${_CMD_}"
6418N/A print -u2 "\E[0m"
6418N/A ' TMPF[DEBUG]
6418N/Afi
6418N/A
6418N/A# Prevent new files from being read by group or others
6418N/Aumask 077
6418N/A
6418N/AdoMain
6418N/AX=$?
6418N/A
6418N/Acleanup NOKILL
6418N/A
6418N/Aexit ${X}
6418N/A
6418N/A# vim:ts=4 filetype=sh
6418N/A# :syntax sync fromstart