#!/bin/sh
BOLD=$(tput bold)
NORMAL=$(tput sgr0)
brest_admin=brestadmin
brestusers=brestusers
brestadmins=brestadmins
tmp_folder=/tmp/brest-configure
tmp_passfile=$tmp_folder/p
HOSTNAME=`hostname -s`
DOMAIN=`hostname -d`
FQDN=$HOSTNAME.$DOMAIN
ONEHOME=/var/lib/one

systemctl restart opennebula-onedisk-incron.service

KDC=$( awk '{if ($1 == "server") print $3}' '/etc/ipa/default.conf' )
if [ -z $KDC ]; then
        KDC=$FQDN
        echo "Вы находитесь на контроллере/реплике домена IPA!
Nebula Sunstone следует разворачивать на клиенте IPA"
exit 0
fi

SUFFIXS=$(echo $DOMAIN | tr "." "\n")
SUFFIX=""
for N in $SUFFIXS
do
   PART="dc=$N"
   if [ "$SUFFIX" != "" ]; then
      SUFFIX="$SUFFIX,$PART"
   else
      SUFFIX="$PART"
   fi
done

trap ctrl_c INT
function ctrl_c() {
        echo -e "\n\n** Срыв настройки\n"
        rm -rf $tmp_ald_folder
        exit 0
}

function create_brest_admin_name {
    local brest_admin_name=;
    while [ -z "$brest_admin_name" ]; do
        echo -n "Введите логин для администратора Бреста: "
        read brest_admin_name
        if ! echo "$brest_admin_name" | grep -Eq  '^[A-Za-z]+[0-9A-Za-z]*$';then
            echo -ne "\nОШИБКА:  логин не может начинаться с цифры, содержать кириллические или специальные символы\n"
            brest_admin_name=
        fi
        if [ "$brest_admin_name" == "brestadmin" ];then
            echo -ne "\nОШИБКА:  локальный пользователь brestadmin уже существует в системе! Выберите другое имя.\n"
            brest_admin_name=
        fi
    done
    brest_admin="$brest_admin_name"
}


function create_password {
    result_create_password=
    local pass=;  local pass2=; local check_pass=
    while [ -z "$pass" ]; do
        echo -n "Введите пароль для пользователя: "
        read -s pass
        if [ "$pass" != "`echo $pass | sed "/[А-Я]/d; /[а-я]/d;"`" ];then
            echo -ne "\nОШИБКА:  пароль не может содержать кириллические символы\n"
            pass=
            continue
        fi
        check_pass=`echo "$pass" | cracklib-check | grep -wv " OK" | awk '{$1 = "ОШИБКА:  пароль"; print}'`
        if [ -n "$check_pass" ];then
            echo -ne "\n$check_pass\n"
            pass=
            continue
        fi
        echo -ne "\nПовторите ввод пароля: "
        read -s pass2
        if [ "$pass" != "$pass2" ];then
            echo -ne "\nОШИБКА:  пароли не совпадают\n"
            pass=
        fi
    done
    result_create_password="$pass"
}

function group_merging {
    #Fix for Astra 1.6 Update 7
    adduser libvirt-qemu kvm

    echo "Добавление системных групп в домен"
    for G in kvm libvirt libvirt-qemu libvirt-admin astra-audit
    do
        check_group=$(ipa group-find | grep $G | grep -v grep)
        if [ -z "$check_group" ]; then
            ipa group-add $G --desc="Group for BREST"
        fi
    done
    
    for G in kvm libvirt libvirt-qemu
    do
        check_in_group_bu=$(ipa group-show  $G| grep "$brestusers" | grep -v grep)
        if [ -z "$check_in_group_bu" ]; then
            ipa group_add_member $G --groups=$brestusers
        fi

        check_in_group_ba=$(ipa group-show  $G| grep "$brestadmins" | grep -v grep)
        if [ -z "$check_in_group_ba" ]; then
            ipa group_add_member $G --groups=$brestadmins
        fi
    done

    for G in libvirt-admin astra-audit
    do
        check_in_group_ba=$(ipa group-show  $G| grep "$brestadmins" | grep -v grep)
        if [ -z "$check_in_group_ba" ]; then
            ipa group_add_member $G --groups=$brestadmins
        fi
    done

echo "Включение Group Merging"

tf=/usr/share/pam-configs/groups_merging
sudo touch "${tf}" ; sudo chmod 0644 "${tf}" ; sudo chown root.root "${tf}"
cat <<EOF | sudo tee "${tf}" 1>/dev/null
Name: activate /etc/security/group.conf
Default: yes
Priority: 900
Auth-Type: Primary
Auth:
        required                        pam_group.so use_first_pass
EOF

pam-auth-update --package groups_merging --force

    sed -i -r -e '/^\s*group:/s/(compat|files) sss/\1 [SUCCESS=merge] sss/;' /etc/nsswitch.conf

    cp /etc/group /etc/group_before_libvirt_conf

    test -z "${LOGFILE}" && LOGFILE=/root/deploy.log
    for gp in kvm libvirt libvirt-qemu libvirt-admin brestadmins brestusers astra-audit;
    do
    {
        tgid="$( getent group -s  sss  "${gp}" | awk -F':' '{print $3}' )"
        ogid="$( getent group -s files "${gp}" | awk -F':' '{print $3}' )"
    } 2>/dev/null
    # if group exists locally and in domain
    test -n "${ogid}" && test -n "${tgid}" && test ${ogid} -ne ${tgid} && {
        # use sed because groupmod fails because the new GID already exists
        sed -i -r -e "/^${gp}:/s/:${ogid}:/:${tgid}:/;" /etc/group
        # log to stdout and logfile
        printf '%s %s\n' "$( date -u "+%FT%TZ" )" "Change ${gp} from gid ${ogid} to ${tgid}" | tee -a "${LOGFILE}"
    }
    done

    if [ -d "$ONEHOME/plbl" ]; then
        chown oneadmin:libvirt-qemu $ONEHOME/plbl
        chmod 0775 $ONEHOME/plbl
    fi
    if [ -d "$ONEHOME/commands" ]; then
        chown ${ONE_USER}:libvirt-qemu $ONEHOME/commands
    fi

    if [ -d "$ONEHOME/sessions" ]; then
        chown ${ONE_USER}:libvirt-qemu $ONEHOME/sessions
    fi
}

echo -e "\n${BOLD}Мастер настройки облака${NORMAL}"
#a2dismod authnz_pam
a2enmod auth_kerb
a2enmod cgi


if [ ! -d "$tmp_folder" ]; then
    mkdir $tmp_folder
fi

function admin_auth(){
        echo -n "Введите имя администратора IPA-сервера (по умолчанию admin): "
        read domain_admin
        if [ -z "$domain_admin" ]; then
            domain_admin="admin"
        fi
        echo -n "Введите пароль администратора сервера: "
        read -s admin_pass
        echo
        while [ -z "$admin_pass" ]; do
            echo -n "Введите пароль администратора сервера: "
            read -s admin_pass
            echo
        done
        echo $admin_pass | kinit $domain_admin || {
		echo -e "\033[91m Вы неправильно ввели имя или пароль, попробуйте ещё раз \033[0m"
		admin_auth
	}
}

admin_auth

echo "" > $tmp_passfile
chmod 0400 $tmp_passfile
chown root:root $tmp_passfile
echo "$domain_admin:$admin_pass" > $tmp_passfile

echo "Добавление системных групп..."
for G in $brestusers $brestadmins
do
    check_group=$(ipa group-find | grep $G | grep -v grep)
    if [ -z "$check_group" ]; then
        ipa group-add $G --desc="Group for BREST"
    fi
done

ipa permission-add "Manage brestusers" --right=all --bindtype=permission --type=user  --filter "(memberOf=cn=$brestusers,cn=groups,cn=accounts,$SUFFIX)"

ipa privilege-add "Manage users - brestusers"
ipa privilege-add-permission "Manage users - brestusers" --permissions "Manage brestusers"
ipa privilege-add-permission "Manage users - brestusers" --permissions "System: Modify Group Membership"
ipa privilege-add-permission "Manage users - brestusers" --permissions "System: Add Users"
ipa privilege-add-permission "Manage users - brestusers" --permissions "System: Change User password"

ipa role-add "Brestusers Administrator"
ipa role-add-privilege "Brestusers Administrator" --privileges "Manage users - brestusers"
ipa role-add-member "Brestusers Administrator" --groups=$brestadmins

create_brest_admin_name

check_user=$(ipa user-find | grep -w "${brest_admin}" | grep -v grep)
if [ -z "$check_user" ]; then
    echo -e "\nЗаведение пользователя \"${BOLD}${brest_admin}${NORMAL}\" в домене."
        create_password
        brest_pass="$result_create_password"
    echo "$brest_admin:$brest_pass" >> $tmp_passfile

    ipa user-add $brest_admin --first $brest_admin --last $brest_admin

    ldapmodify -D "cn=Directory Manager" -h $KDC -Y GSSAPI <<- EOF
dn: uid=$brest_admin,cn=users,cn=accounts,$SUFFIX
changetype: modify
replace: userPassword
userPassword: $brest_pass

dn: uid=$brest_admin,cn=users,cn=accounts,$SUFFIX
changetype: modify
replace: krbPasswordExpiration
krbPasswordExpiration: $(date -u -d "@$(($(date +'%s')+(90*24*3600)))" +'%Y%m%d%H%M%S'Z)
EOF

    ipa user-mod $brest_admin --macmin=0 --macmax=0 --miclevel=0
fi
ipa group-add-member $brestusers --users=$brest_admin
ipa group-add-member $brestadmins --users=$brest_admin
ipa group-add-member admins --users=$brest_admin

adduser $brest_admin astra-admin
adduser $brest_admin astra-console
adduser $brest_admin disk
adduser $brest_admin libvirt-admin
adduser $brest_admin libvirt-qemu
adduser $brest_admin libvirt
adduser $brest_admin kvm
adduser $brest_admin astra-audit

group_merging

# rbt: BREST-1429
cp /etc/apache2/sites-available/ad-one-apache2.conf /etc/apache2/sites-available/default.ad-one-apache2.conf >/dev/null
mv /etc/apache2/sites-available/ad-one-apache2.conf /etc/apache2/sites-available/ipa-one-apache2.conf >/dev/null
sed -i "s/@@realm@@/${DOMAIN^^}/" /etc/apache2/sites-available/ipa-one-apache2.conf
sed -i "s/@@client@@/$FQDN/" /etc/apache2/sites-available/ipa-one-apache2.conf

ln -sfn  /etc/apache2/sites-available/ipa-one-apache2.conf /etc/apache2/sites-enabled/one-apache2.conf

one-brestmode

check_oned_user=$(oneuser list --csv | cut -d, -f2 | grep -w "${brest_admin}")
if [ "$check_oned_user" != "$brest_admin" ]; then
    oneuser create $brest_admin "$brest_admin@${DOMAIN^^}" --driver public --group brestadmins
fi
oneuser passwd $brest_admin "$brest_admin@${DOMAIN^^}"

check_service=$(ipa service-find | grep "HTTP/$FQDN@${DOMAIN^^}" | grep -v grep)
if [ -z "$check_service" ]; then
    ipa service-add HTTP/$FQDN@${DOMAIN^^}
    if [ -f /etc/apache2/apache2.keytab ]; then
        rm /etc/apache2/apache2.keytab
    fi
    ipa-getkeytab -s $KDC -p HTTP/$FQDN@${DOMAIN^^} -k /etc/apache2/apache2.keytab
    chown www-data:www-data /etc/apache2/apache2.keytab
    chmod 644 /etc/apache2/apache2.keytab
else
    if [ -f /etc/apache2/apache2.keytab ]; then
        rm /etc/apache2/apache2.keytab
    fi
    ipa-getkeytab -s $KDC -p HTTP/$FQDN@${DOMAIN^^} -k /etc/apache2/apache2.keytab
    chown www-data:www-data /etc/apache2/apache2.keytab
    chmod 644 /etc/apache2/apache2.keytab
fi

service apache2 restart

sed -i 's/#*:ad_user_worker:/:ad_user_worker:/' /etc/one/sunstone-server.conf
sed -i 's/#*:ad_group_worker:/:ad_group_worker:/' /etc/one/sunstone-server.conf

rm -rf $tmp_folder

check_oned_user=$(oneuser list --csv | cut -d, -f2 | grep -w "${brest_admin}")
if [ -f /etc/apache2/apache2.keytab ] && [ "$check_oned_user" == "$brest_admin" ]; then
    if [ -f /var/lib/one/remotes/hooks/raft/sync_users_tokens.sh ]; then
        /var/lib/one/remotes/hooks/raft/sync_users_tokens.sh
    fi
    astramode=$(astra-modeswitch get)
    if [ "$astramode" != "0" ]; then
        sudo pdpl-user -i 127 root
    fi
    echo -e "\n\t${BOLD}Настройка прошла успешно!${NORMAL}"
    echo -e "Вы можете войти в панель управления через браузер по адресу ${BOLD}https://${FQDN}${NORMAL}, пользователь для входа - ${BOLD}${brest_admin}${NORMAL}, пароль - указанный при заведении пользователя в домене. Браузер пользователя должен поддерживать аутентификацию ${BOLD}negotiate${NORMAL}. В браузере Mozilla Firefox в настройках, доступных по адресу ${BOLD}about:config${NORMAL}, необходимо указать: для каких серверов доступна аутентификация negotiate. Для выполнения данной настройки необходимо задать маски доменов или в общем случае http- и https-соединения в качестве значений параметра ${BOLD}network.negotiate-auth.trusted-uris${NORMAL}, вставив, например, значение ${BOLD}http://, https://${NORMAL}. Так же, в качестве значений параметра ${BOLD}network.negotiate-auth.delegation-uris${NORMAL}, обязательно необходимо указать маски доменов которым можно передавать данные для сквозной аутентификации. \n"
    echo -e "\n\t${BOLD}ВНИМАНИЕ!${NORMAL} Доступ к веб-интерфейсу организован через защищенное соединение по протоколу https с помощью самоподписного SSL сертификата, поэтому следует один раз открыть в браузере ссылки ${BOLD}https://${FQDN}${NORMAL}, ${BOLD}https://$FQDN:2616${NORMAL} и ${BOLD}https://$FQDN:29876${NORMAL} и подтвердить использование сертификата. \n"
else
    echo -e "\n\tОшибка!"
    [ "$check_oned_user" != "$brest_admin" ] && echo -e "\n\tПользователь $brest_admin не найден! Проверьте статус сервиса opennebula"
fi
