#!/bin/bash # ------- # File: llxcfg-ldap-server # Description: LliureX ldap server utility # Author: Angel Berlanas Vicente # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA # -------- set -e ############################# # GLOBAL VARIABLES # ############################# SLAP_OPTIONS="" CPKGS="ldap-common ldap-server armor" LDAP_DB_DIR="/var/lib/slapd/" FORCE_INIT="" PASSWORD="" TEMPLATES_DIRECTORY="" LDIF_DIRECTORY="" #LOST SOME VARIABLES LLX_GETVAR="/usr/sbin/llxcfg-showvars" LWAT_IDS="/var/log/lliurex-lwatlogs/users_id" LWAT_LOGT="/var/log/lliurex-lwatlogs/lwat_profesores" LWAT_LOGO="/var/log/lliurex-lwatlogs/lwat_otros" LWAT_LOGA="/var/log/lliurex-lwatlogs/lwat_alumnos" LWAT_LOG_CLEAN_DIR="/var/lib/slapd/" NEXT_ID="" PATH_TO_SET_ACL="/net/share" PATH_TO_TOKENS_LDAP="/var/lib/llxcfg-ldap/tokens" # VALUES: LIB_FILE="/usr/share/lliurex/llxcfg-ldap/common.sh" [ -e $LIB_FILE ] || exitmessage "File not Found Exception: $LIB_FILE not present" . $LIB_FILE ################################# # SEARCH PASSWORD # ################################# search_passwords(){ PASSWORD="NOT PRESENT" if [ -f /etc/shadow ]; then PASSWORD=$(cat /etc/shadow | grep $1 | cut -d':' -f2) fi } ################################# # PRECONFIGURE # ################################# replenish_ldifs_with_variables(){ #READING VARIABLES SYSTEM_TPL_FILE=$(llxcfg-config filename ldap-server/system.tpl) ADMINS_TPL_FILE=$(llxcfg-config filename ldap-server/admins.tpl) ADMIN_TPL_FILE=$(llxcfg-config filename ldap-server/admin.tpl) LWAT_TPL_FILE=$(llxcfg-config filename ldap-server/lwat.tpl) REPLICANT_TPL_FILE=$(llxcfg-config filename ldap-server/replicant.tpl) } ################################# # GENERATE LWAT LDIF # ################################# generate_admin_ldif(){ llxcfg-systemvars add LDAP_NEXT_ID=11000 ADMIN_TMP_FILE=$(mktemp /tmp/ldap-install.XXXXXXXX) ADMINS_TMP_FILE=$(mktemp /tmp/ldap-install.XXXXXXXX) AUX_TMP_FILE=$(mktemp /tmp/ldap-install.XXXXXXXX) AUX_TMP_FILE_MEMBER=$(mktemp /tmp/ldap-install.XXXXXXXX) AUX_TMP_FILE_MEMBERUID=$(mktemp /tmp/ldap-install.XXXXXXXX) MEMBER_STRING="" lliurex-userfuncs llx_get_group_members admin > $ADMIN_TMP_FILE # #FIXME skel-install # cp -f $ADMINS_TPL_FILE $ADMINS_TMP_FILE # # Search password in /etc/shadow # ATTENTTION!! THIS IS A SUBSHELL ^_^ # # cat $ADMIN_TMP_FILE | while read line do #For each line in file search_passwords $line #Posix Account fields ################# export LLX_UID=$(lliurex-userfuncs llx_get_userid $line) export LLX_GID=$(lliurex-userfuncs llx_get_groupgid $line) export LLX_HOME=$(lliurex-userfuncs llx_get_userhome $line) line=$(echo $line| sed "s/\[:blank:\]//g") #FIXME skel-install sed -e "s%USERNAME_UID%$LLX_UID%g;s%LLX_USERNAME%$line%g;s%LLX_GID%$LLX_GID%g;s%LLX_HOME%$LLX_HOME%g;" $ADMIN_TPL_FILE >> $AUX_TMP_FILE echo -e "userPassword: {crypt}"$PASSWORD >> $AUX_TMP_FILE echo -e "" >> $AUX_TMP_FILE echo $line >> $AUX_TMP_FILE_MEMBERUID MEMBER_STRING="uid=$line,_@_LDAP_ADMIN_PEOPLE_BASE_DN_@_" echo $MEMBER_STRING >> $AUX_TMP_FILE_MEMBER eval $(llxcfg-showvars LDAP_NEXT_ID) LDAP_NEXT_ID=$(($LDAP_NEXT_ID + 1)) llxcfg-systemvars add LDAP_NEXT_ID=$LDAP_NEXT_ID done sed "s%^%member:\ %g" $AUX_TMP_FILE_MEMBER >> $ADMINS_TMP_FILE sed "s%^%memberUid:\ %g" $AUX_TMP_FILE_MEMBERUID >> $ADMINS_TMP_FILE llxcfg-template $AUX_TMP_FILE > $LDIF_DIRECTORY/admin.ldif llxcfg-template $ADMINS_TMP_FILE > $LDIF_DIRECTORY/admins.ldif # # REMOVING TEMPFILES # rm $AUX_TMP_FILE rm $ADMIN_TMP_FILE rm $ADMINS_TMP_FILE rm $AUX_TMP_FILE_MEMBER rm $AUX_TMP_FILE_MEMBERUID } die(){ echo "$1" >&2 exit 1 } function generate_secrets(){ eval $(llxcfg-showvars LDAP_SRV_MODE LDAP_BASE_DN LDAP_REPLICATOR_NAME LDAP_MASTER_DIR) case "$LDAP_SRV_MODE" in SLAVE) for n in $LDAP_REPLICATOR_NAME ldap ; do MF="$LDAP_MASTER_DIR/$n" [ -r "$MF" ] || die "Error: $MF not found" done LDAP_REPLICATOR_PASS="$LDAP_MASTER_DIR/$LDAP_REPLICATOR_NAME" LDAP_ADMIN_FILE="$LDAP_MASTER_DIR/ldap" ;; STANDALONE) LDAP_REPLICATOR_PASS=$(llxcfg-passgen --force $LDAP_REPLICATOR_NAME gen) LDAP_ADMIN_FILE=$(llxcfg-passgen --chucknorris ldap gen) ;; MASTER) if [ -r "$LDAP_MASTER_DIR/$LDAP_REPLICATOR_NAME" ] ; then LDAP_REPLICATOR_PASS="$LDAP_MASTER_DIR/$LDAP_REPLICATOR_NAME" else LDAP_REPLICATOR_PASS=$(llxcfg-passgen --force $LDAP_REPLICATOR_NAME gen) cp -p "$LDAP_REPLICATOR_PASS" "$LDAP_MASTER_DIR/$LDAP_REPLICATOR_NAME" fi if [ -r "$LDAP_MASTER_DIR/ldap" ] ; then LDAP_ADMIN_FILE="$LDAP_MASTER_DIR/ldap" else LDAP_ADMIN_FILE=$(llxcfg-passgen --chucknorris ldap gen) cp -p "$LDAP_ADMIN_FILE" "$LDAP_MASTER_DIR/ldap" fi ;; esac llxcfg-systemvars add "LDAP_REPLICATOR_PASS=$LDAP_REPLICATOR_PASS" llxcfg-systemvars add "LDAP_ADMIN_FILE=$LDAP_ADMIN_FILE" return 0 } function generate_replicant() { eval $(llxcfg-showvars LDAP_REPLICATOR_PASS) export PASSWORD_REPLICANT="$(cat $LDAP_REPLICATOR_PASS)" llxcfg-template $REPLICANT_TPL_FILE > $LDIF_DIRECTORY/replicant.ldif unset PASSWORD_REPLICANT } #function setpassword_replicant() #{ # REPLIPASS=$(llxcfg-passgen replicant show) # TARGET_DN="cn=replicant,$LDAP_BASE_DN" # ldappasswd -x -D "cn=admin,$LDAP_BASE_DN" -w "$(cat "$LDAP_ADMIN_FILE")" -s "$(cat $REPLIPASS)" "$TARGET_DN" || exit_message "ERROR: password for user $U_PASS has been NOT CHANGED" #P_REPLICATOR_PASS build_environment(){ LDIF_DIRECTORY=$(mktemp -d /tmp/llxcfg-ldap.XXXXXXXX) } clean_environment(){ rm -rf $LDIF_DIRECTORY } set_acls(){ # SET THE ACLS llxcfg-acl "$PATH_TO_SET_ACL" (cat "$PATH_TO_TOKENS_LDAP" ; echo "$PATH_TO_SET_ACL") | sort -u | llxcfg-install - "$PATH_TO_TOKENS_LDAP" } needs_acls(){ # SANITY CHEKS grep -q "$PATH_TO_SET_ACL" "$PATH_TO_TOKENS_LDAP" || return 0 return 1 } clean_lwat(){ # cleaning lwat environment # if ldap is re-installed we must delete the lwat-logs files for l in $LWAT_IDS $LWAT_LOGT $LWAT_LOGO $LWAT_LOGA ; do [ ! -e "$l" ] || :> "$l" done return 0 } generate_lwat_ldif(){ eval $(llxcfg-showvars LDAP_ADMIN_FILE) generate_new_codigo_centro export PASSWORD_SECRET="$(cat $LDAP_ADMIN_FILE | mkpasswd -s -H md5)" llxcfg-template $LWAT_TPL_FILE > $LDIF_DIRECTORY/lwat.ldif unset PASSWORD_SECRET llxcfg-systemvars del TMP_CODIGO_CENTRO } ################################# # GENERATE SYSTEM LDIF # ################################# generate_system_ldif(){ SYSTEM_AUX_FILE=$(mktemp llxcfg-ldap.XXXXXXXXXXXXXXXXXXXX) cat /etc/group | while read line do GROUPNAME=$(echo $line |cut -d':' -f1) SECONDVALUE=$(echo $line |cut -d':' -f3) if [ "$SECONDVALUE" -lt 1000 ] ; then cat $SYSTEM_TPL_FILE | sed "s/GROUPSYSTEM/$GROUPNAME/; s/GROUPGID/$SECONDVALUE/g" >> $SYSTEM_AUX_FILE fi done llxcfg-template $SYSTEM_AUX_FILE > $LDIF_DIRECTORY/system.ldif rm $SYSTEM_AUX_FILE } load_ldifs_to_slapd(){ # source variable file VAR_FILE="/etc/default/slapd" [ ! -r "$VAR_FILE" ] || . "$VAR_FILE" [ -z "$SLAPD_CONF" ] || SLAP_OPTIONS="-f $SLAPD_CONF" rm -rf /var/lib/slapd/* LDIFFILES="$LDIF_DIRECTORY/lwat.ldif $LDIF_DIRECTORY/admins.ldif $LDIF_DIRECTORY/system.ldif $LDIF_DIRECTORY/admin.ldif" if [ -r "$LDIF_DIRECTORY/replicant.ldif" -a $LDAP_SRV_MODE = "MASTER" ]; then LDIFFILES="$LDIFFILES $LDIF_DIRECTORY/replicant.ldif" fi for ldif in $LDIFFILES do echo "slapadd $SLAP_OPTIONS -c -l $ldif 2>/dev/null" slapadd $SLAP_OPTIONS -c -l $ldif 2>/dev/null if [ ! $? ]; then echo "error: Unable to load $ldif" exit 1 fi done } fixperms(){ #The database must be owned by openldap if getent passwd openldap | grep -q openldap ; then chown -R openldap:openldap "$LDAP_DB_DIR" fi } usage(){ CMD="$(basename "$0")" exit_message \ "Usage: $CMD [ --force ] init $CMD clean-logs $CMD set-acl PATH $CMD passwd USER NEWPASSWORD $CMD {start|stop|restart|reload|allow|deny|info|listfiles|update|revert|cpkgs}" # TODO: think about additional actions ... } exit_message() { echo -e "$1" >&2 exit 1 } test_hostname(){ hostname -f |grep -q "^[^\.]\+\.${SRV_DOMAIN}$" || exit_message "ERROR: invalid FQDN" return 0 } pam_enable(){ llxcfg-systemvars add ENABLE_NSS_LDAP=yes llxcfg-cpkg update pamnss-common &>/dev/null || true return 0 } ############## # MAIN # ############## if [ "$1" = "--force" ] ; then FORCE_INIT="Y" shift fi ACTION="$1" # simple cpkg actions case "$ACTION" in start|stop|restart|reload) llxcfg-cpkg invoke "$ACTION" $CPKGS exit 0 ;; cpkgs) for c in $CPKGS ; do echo $c done exit 0 ;; allow|deny|listfiles|update|revert|info) llxcfg-cpkg "$ACTION" $CPKGS || true exit 0 ;; set-acl) [ $# -eq 2 ] || usage PATH_TO_SET_ACL="$2" needs_acls || exit 0 set_acls ;; init) [ $FORCE_INIT ] || exit_message "See the usage (the --force option is not present)" llxcfg-cpkg invoke stop $CPKGS /etc/init.d/slapd stop # Deprecated waiting the new Version #prepare-llxcfg-backup-ldap build_environment we_have_all_the_ingredients # echo "Building BASE DN...working" # building_base_dn [ llxcfg_is_valid_LWAT_LDAP_DN ] || exit_message "Base DN is not Valid, see the man page" building_ldap_vars # llxcfg-archivevars llxldap store LDAP_BASE_DN CODIGO_CENTRO store_ldap_vars rc=0 llxcfg-cpkg configure $CPKGS &> /dev/null || rc=$? remove_ldap_vars [ $rc -eq 0 ] || exit_message "Unable to configure LDAP server" generate_secrets replenish_ldifs_with_variables echo "LDAP Populate ...working" generate_lwat_ldif generate_admin_ldif generate_system_ldif generate_replicant load_ldifs_to_slapd echo "Some additional operations ...working" fixperms lliurex-pki -n ldap.crt -u openldap -g openldap -p 644 clean_environment echo "Cleaning lwat environment" clean_lwat store_ldap_vars if ! llxcfg-cpkg update $CPKGS &> /dev/null ; then remove_ldap_vars exit_message "ERROR: Unable to configure/restart ldap services" fi RESTART_DONE="Y" if ! llxcfg-cpkg invoke restart $CPKGS ; then # try manually killall slapd sleep 2 invoke-rc.d slapd restart || RESTART_DONE="" fi if [ -z "$RESTART_DONE" ] ; then exit_message "ERROR: Unable to restart ldap services" exit 1 fi # set ENABLE_NSS_LDAP variable to allow server to be client of himself pam_enable set_acls exit 0 ;; clean-logs) # Clean log for ldap (only the last is in use) find "$LDAP_DB_DIR" -name "log.*"| sort | head -n -2 | xargs rm -rf ;; passwd) U_NAME="$2" U_PASS="$3" [ "$U_NAME" -a "$U_PASS" ] || usage # get variables eval $(llxcfg-showvars LDAP_BASE_DN LDAP_ADMIN_FILE ) [ "$LDAP_BASE_DN" -a "$LDAP_ADMIN_FILE" -a -r "$LDAP_ADMIN_FILE" ] || exit_message "Missing required varibles ... It seems like LDAP is not well initialized" # get dn TARGET_DN="$(ldapsearch -x -LLL "(&(objectClass=posixAccount)(uid=$U_NAME))" |perl -p -0040 -e 's/\n //' |sed -ne "/^dn:/{s%dn:[[:blank:]]*%%;p}" |head -1)" [ "$TARGET_DN" ] || exit_message "User $U_NAME not found in LDAP" ldappasswd -x -D "cn=admin,$LDAP_BASE_DN" -w "$(cat "$LDAP_ADMIN_FILE")" -s "$U_PASS" "$TARGET_DN" || exit_message "ERROR: password for user $U_PASS has been NOT CHANGED" echo "Password SUCCESSFULLY updated" exit 0 ;; *) usage ;; esac exit 0