#!/bin/sh

echo $0 $@ | grep -q '[[:space:]]-d\([[:space:]]\|$\)' && set -x

rdelim='[[:space:]]\+'
wdelim=' '

#pam configuration
pamldapfile="/etc/pam_ldap.conf"

#nss configuration
nssldapfile=
nssldapfile1="/etc/nss_ldap.conf"
nssldapfile2="/etc/nslcd.conf"
nsswitchfile="/etc/nsswitch.conf"

# openldap conf
ldap_conf="/etc/openldap/ldap.conf"

# krb conf
krb5_conf="/etc/krb5.conf"

# samba conf
smb_conf="/etc/samba/smb.conf"

# time sync command
net_cmd="/usr/bin/net"

# FreeIPA client command
ipa_cmd="/usr/sbin/ipa-client-install"

# sssd config
sssd_conf="/etc/sssd/sssd.conf"

# group mapping
user_groups="/etc/alterator/auth/user-groups"
admin_groups="/etc/alterator/auth/admin-groups"

#select between nss_ldap and nss-ldapd
[ -f "$nssldapfile1" ] && nssldapfile="$nssldapfile1"
[ -f "$nssldapfile2" ] && nssldapfile="$nssldapfile2"

# Use old LDAP auth scheme (nss_ldap or nss-ldapd) or new one (sssd)
ldap_auth_sssd="no"
test rpm -q sssd &>/dev/null || ldap_auth_sssd="yes"

. alterator-datetime-functions
. shell-config
. shell-ini-config
. shell-quote
. shell-error

#turn off auto expansion
set -f

# getting current auth
get_status()
{
    local status="$(/usr/sbin/control system-auth)"

    case "$status" in
        local)
            echo "local"
	    ;;
        ldap)
            echo -n "ldap " && pam_ldap_info
            ;;
        krb5*)
            echo -n "$status " && pam_ldap_info
            ;;
        winbind|sss)
            # test FreeIPA join
            if grep -q '^ipa_domain' "$sssd_conf" &>/dev/null; then
                echo -n "freeipa " && pam_ipa_info
            elif grep -q '^ldap_uri' "$sssd_conf" &>/dev/null; then
                echo -n "krb5 " && pam_ldap_info
            else
                echo -n "ad " && pam_ad_info
            fi
            ;;
        *)
            echo "unknown status"
            ;;
    esac
}

list()
{
    # always local
    echo "local"

    # checking pam_ldap and libnss_ldap libs
    [ -n "$(find /$(getconf SLIB)/security -maxdepth 1 -name 'pam_ldap.*')" ] &&
	[ -n "$(find /$(getconf SLIB) -maxdepth 1 -name 'libnss_ldap.so.*')" ] &&
    echo "ldap"

    # checking ldap and krb5 libs
    if [ "$ldap_auth_sssd" = "yes" ]; then
        rpm -q sssd-ldap sssd-krb5 &>/dev/null &&
        echo "krb5"
    else
        [ -n "$(find /$(getconf SLIB)/security -maxdepth 1 -name 'pam_ldap.*')" ] &&
        [ -n "$(find /$(getconf SLIB) -maxdepth 1 -name 'libnss_ldap.so.*')" ] &&
        [ -n "$(find /$(getconf SLIB) -maxdepth 1 -name 'libkrb5.so.*')" ] &&
        echo "krb5"
    fi

    # checking winbind or sss libs
    [ -n "$(find /$(getconf SLIB)/security -maxdepth 1 -regextype egrep -regex '.*/pam_(winbind|sss).so')" ] &&
	echo "ad"

    # checking freeipa-client executable
    [ -x "$ipa_cmd" ] &&
	echo "freeipa"
}

pam_ldap_info()
{
    local uri basedn

    if grep -q '^ldap_uri' "$sssd_conf" &>/dev/null; then
        uri="$(sed -n 's/^ldap_uri *= *//p' "$sssd_conf")"
        basedn="$(sed -n 's/^ldap_search_base *= *//p' "$sssd_conf")"
    elif [ -f "$pamldapfile" ];then
        uri="$(read_pam_ldap uri)"
        basedn="$(read_pam_ldap base)"
    else
        uri="$(read_nss_ldap uri)"
        basedn="$(read_nss_ldap base)"
    fi

    check_uri "$uri" && check_basedn "$basedn" && echo "$basedn $uri"
}

pam_ad_info()
{
    local domain="$(ini_config_get "$smb_conf" "global" "realm")"
    local hostname="$(ini_config_get "$smb_conf" "global" "netbios name")"
    local workgroup="$(ini_config_get "$smb_conf" "global" "workgroup")"
    echo "$domain $hostname $workgroup"
}

pam_ipa_info()
{
    local domain="$(sed -n 's/^ipa_domain *= *//p' "$sssd_conf")"
    local hostname="$(sed -n 's/^ipa_hostname *= *//p' "$sssd_conf")"
    hostname="${hostname//.$domain}"
    echo "$domain $hostname"
}

check_uri()
{
    local uri="$1"

    [ -z "$uri" ] && message "$0 (check_uri) uri not set" && return 1

    [ -z "$(echo "$uri"| egrep "^ldap[s|i]?:\/\/[^\/]+/?$")" ] && message "$0 (check_uri) invalid uri format" && return 1

    :
}

check_basedn()
{
    local basedn="$1"

    [ -z "$basedn" ] && message "$0 (check_basedn) basedn not set" && return 1

    [ -z "$(echo "$basedn"| egrep "^dc=[^,]+(,dc=[^,]+)*$")" ] && message "$0 (check_basedn) invalid basedn format" && return 1

    :
}

read_pam_ldap()
{
    read_config "$pamldapfile" "$1"
}


read_nss_ldap()
{
    read_config "$nssldapfile" "$1"
}

read_config()
{
    shell_config_get "$1" "$2" "$rdelim"
}


write_profile()
{
    local scheme="$1"

    case "$scheme" in
	local)
	    /usr/sbin/control system-auth local
	    write_nsswitch "passwd" "files"
	    write_nsswitch "shadow" "tcb files"
	    write_nsswitch "group" "files"
	    ;;
	ldap|krb5*)
        if [ "$ldap_auth_sssd" = "yes"  ]; then
            /usr/sbin/control system-auth "sss"
            write_nsswitch "passwd" "files sss"
            write_nsswitch "shadow" "tcb files sss"
            if [ -x /usr/bin/rolelst ]; then
                write_nsswitch "group" "files [SUCCESS=merge] sss role"
            else
                write_nsswitch "group" "files [SUCCESS=merge] sss"
            fi
        else
            /usr/sbin/control system-auth "$scheme"
            write_nsswitch "passwd" "files ldap"
            write_nsswitch "shadow" "tcb files ldap"
            write_nsswitch "group" "files [SUCCESS=merge] ldap"
        fi
	    ;;
	ad)
	    if [ -e "$sssd_conf" ]; then
		scheme="sss"
	    else
		scheme="winbind"
	    fi
            /usr/sbin/control system-auth "$scheme"
	    write_nsswitch "passwd" "files $scheme"
	    write_nsswitch "shadow" "tcb files $scheme"
	    if [ -x /usr/bin/rolelst ]; then
	        write_nsswitch "group" "files [SUCCESS=merge] $scheme role"
	    else
	        write_nsswitch "group" "files [SUCCESS=merge] $scheme"
	    fi
	    ;;
    esac
    # [SUCCESS=merge] is supported only in glibc-core >= 2.23. Remove this option for earlier version
    if [ $(rpmvercmp `rpm -q --qf '%{version}' glibc-core` '2.23') == -1 ]; then
	subst 's/\[SUCCESS=merge\] //g' "$nsswitchfile"
    fi
}

write_nsswitch()
{
    write_config "$nsswitchfile" "$1:" "$2"
}

write_2_ldap()
{
    write_pam_ldap "$1" "$2"
    write_nss_ldap "$1" "$2"
    write_ldap_conf "$1" "$2"
}

write_pam_ldap()
{
    [ -f "$pamldapfile" ] && write_config "$pamldapfile" "$1" "$2"
}

write_nss_ldap()
{
    write_config "$nssldapfile" "$1" "$2"
}

write_ldap_conf()
{
    # ugly, but effective
    sed -r -i -e "/^[^#]*$1.*$/Id" "$ldap_conf"
    echo "$1 $2" >> "$ldap_conf"
}

write_config()
{
    shell_config_set "$1" "$2" "$3" "$rdelim" "$wdelim"
}

dn_2_host()
{
    local dn="$1"

    echo "$dn"|sed -e 's/^dc=//i'|sed -e 's/,dc=/\./g'
}


remove_host_from_confs()
{
    del_from_conf_var "$pamldapfile" "host" && del_from_conf_var "$nssldapfile" "host"
}

del_from_conf_var()
{
    shell_config_del "$1" "$2" "$rdelim"
}

upper()
{
    echo -n "$1" | tr '[[:lower:]]' '[[:upper:]]'
}

lower()
{
    echo -n "$1" | tr '[[:upper:]]' '[[:lower:]]'
}

set_domain_group_mapping()
{
	# Check if libnss-role is installed
	if [ ! -x /usr/bin/rolelst ]; then
		return
	fi
	groupadd -r localadmins &>/dev/null
	if [ -e /etc/role ]; then
		/bin/mv -f /etc/role /etc/role.old
		touch /etc/role
	fi
	# Add domain groups by its name
	echo "Domain Users:users" >> /etc/role
	echo "Domain Admins:localadmins" >> /etc/role
}

adapt_dm()
{
	export shell_ini_config_prefix=''
	if [ -e /etc/lightdm/lightdm.conf ]; then
		ini_config_set /etc/lightdm/lightdm.conf "Seat:*" "greeter-hide-users" "true"
		chmod a+r /etc/lightdm/lightdm.conf
	fi
	if [ -e /etc/lightdm/lightdm-gtk-greeter.conf ]; then
		ini_config_set /etc/lightdm/lightdm-gtk-greeter.conf "greeter" "show-language-selector" "false"
		chmod a+r /etc/lightdm/lightdm-gtk-greeter.conf
	fi
	export shell_ini_config_prefix='	'
}

write_ad_conf()
{
	local domain="$1"
	local hostname="$2"
	local workgroup="$3"

	# Prepare values for configuration
	[ -z "$hostname" ] && hostname="$(hostname -s)"
	[ -z "$workgroup" ] && workgroup="${domain/.*/}"

	# Check hostname length
	if [ "$(echo -n "$hostname" | wc -m)" -gt 15 ]; then
		echo "Netbios name should not be more 15 chars" >&2
		exit 1
	fi

	# Convert to upper case
	domain="$(upper $domain)"
	hostname="$(upper $hostname)"
	workgroup="$(upper $workgroup)"

	# Prepare file for write parameters
	test -e "$smb_conf.orig" || cp "$smb_conf" "$smb_conf.orig"

	# Mapping paraments for Samba < 4
	if [ -n "$(rpm -qf /etc/samba/smb.conf --qf="%{version}"|grep '^3\.')" ] ; then
	    MAPPING_PARAMS="$(cat << MAPPING_PARAMS_SAMBA3
        idmap uid = 10000-20000000
        idmap gid = 10000-20000000
        idmap backend = tdb
MAPPING_PARAMS_SAMBA3
)"
	else
		if [ -e "$sssd_conf" ]; then
		    MAPPING_PARAMS="$(cat << MAPPING_PARAMS_SSSD
        idmap config * : range = 200000-2000200000
        idmap config * : backend = sss
MAPPING_PARAMS_SSSD
)"
		else
		    MAPPING_PARAMS="$(cat << MAPPING_PARAMS_SAMBA4
        idmap config * : range = 10000-20000000
        idmap config * : backend = tdb
MAPPING_PARAMS_SAMBA4
)"
		fi
	fi

	if [ -e "$sssd_conf" ]; then
	    WINBIND_PARAMS="$(cat << MAPPING_PARAMS_WINBIND_SSSD
	winbind use default domain = yes
	winbind enum users = no
	winbind enum groups = no
	template homedir = /home/$domain/%U
MAPPING_PARAMS_WINBIND_SSSD
)"
	else
	    MAPPING_PARAMS="$(cat << MAPPING_PARAMS_WINBIND
	winbind use default domain = yes
	winbind enum users = no
	winbind enum groups = no
	winbind refresh tickets = yes
	winbind offline logon = yes
MAPPING_PARAMS_WINBIND
)"
	fi

	# Write main parameters
	CONFIG="$(cat << AD_PARAMS
	security = ads
	realm = $domain
	workgroup = $workgroup
	netbios name = $hostname
	template shell = /bin/bash
	kerberos method = system keytab
	wins support = no
$WINBIND_PARAMS
$MAPPING_PARAMS
;	encrypt passwords = true
;	dns proxy = no
;	socket options = TCP_NODELAY
;	domain master = no
;	local master = no
;	preferred master = no
;	os level = 0
;	domain logons = no
;	load printers = no
;	show add printer wizard = no
;	printcap name = /dev/null
;	disable spoolss = yes
AD_PARAMS
)"

	# Replace entire section [global] in /etc/samba/smb.conf by new config
	sed -i -e "/^\[global\]/,/^\[/ {/^\([^[]\|$\)/d};/^\[global\]/a\\`echo "$CONFIG"|sed ':a;{N;s/\n/\\\\n/};ba'`" "$smb_conf"

	# Set parameters for PAM modules
	. shell-ini-config
	shell_ini_config_prefix=''
	if [ -e "$sssd_conf" ]; then
	    ini_config_set "$sssd_conf" 'sssd' 'services' 'nss, pam'
	    ini_config_set "$sssd_conf" 'sssd' 'domains' "$domain"
	    ini_config_set "$sssd_conf" "domain/$domain" 'id_provider' 'ad'
	    ini_config_set "$sssd_conf" "domain/$domain" 'auth_provider' 'ad'
	    ini_config_set "$sssd_conf" "domain/$domain" 'chpass_provider' 'ad'
	    ini_config_set "$sssd_conf" "domain/$domain" 'access_provider' 'ad'
	    ini_config_set "$sssd_conf" "domain/$domain" 'default_shell' '/bin/bash'
	    ini_config_set "$sssd_conf" "domain/$domain" 'fallback_homedir' '/home/%d/%u'
	    ini_config_set "$sssd_conf" "domain/$domain" 'debug_level' '0'
	    ini_config_set "$sssd_conf" "domain/$domain" '; cache_credentials' 'false'
	    ini_config_set "$sssd_conf" "domain/$domain" 'ad_gpo_ignore_unreadable' 'true'
	    ini_config_set "$sssd_conf" "domain/$domain" 'ad_gpo_access_control' 'permissive'
            chmod 0600 "$sssd_conf"
	else
	    pam_winbind_cfg='/etc/security/pam_winbind.conf'
	    ini_config_set "$pam_winbind_cfg" 'global' 'cached_login' 'yes'
	    ini_config_set "$pam_winbind_cfg" 'global' 'krb5_auth' 'yes'
	    ini_config_set "$pam_winbind_cfg" 'global' 'krb5_ccache_type' 'KEYRING'
	    ini_config_set "$pam_winbind_cfg" 'global' 'silent' 'yes'
            chmod a+r "$pam_winbind_cfg"

	    # Remove krb5_ccache_type=FILE from /etc/pam.d/system-auth-winbind
	    sed -i 's/ krb5_ccache_type=FILE//g' /etc/pam.d/system-auth-winbind
	fi
	# Map domain groups to local Unix groups
	set_domain_group_mapping

	# Set time sync from dc for client
	write_pool "$domain"
	write_ntp_status "#t"

	# Adapt DM for too many domain users
	adapt_dm
}

write_sssd_ldap_conf()
{
    local domain="$1"
    local basedn="$2"
    local ldapuri="$3"

    . shell-ini-config
    shell_ini_config_prefix=''
    # Remove previous [domain/...] section
    subst '/^\[domain\//,$d' "$sssd_conf"
    if [ -e "$sssd_conf" ]; then
        ini_config_set "$sssd_conf" 'sssd' 'services' 'nss, pam'
        ini_config_set "$sssd_conf" 'sssd' 'domains' "$domain"
        ini_config_set "$sssd_conf" "domain/$domain" 'id_provider' 'ldap'
        ini_config_set "$sssd_conf" "domain/$domain" 'auth_provider' 'krb5'
        ini_config_set "$sssd_conf" "domain/$domain" 'chpass_provider' 'krb5'
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_uri' "$ldapuri"
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_tls_reqcert' 'never'
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_search_base' "$basedn"
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_user_object_class' 'posixAccount'
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_group_object_class' 'posixGroup'
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_user_home_directory' 'homeDirectory'
        ini_config_set "$sssd_conf" "domain/$domain" 'ldap_force_upper_case_realm' 'true'
        ini_config_set "$sssd_conf" "domain/$domain" 'krb5_server' "$domain"
        ini_config_set "$sssd_conf" "domain/$domain" 'krb5_realm' "$(upper $domain)"
        ini_config_set "$sssd_conf" "domain/$domain" 'debug_level' '0'
        chmod 0600 "$sssd_conf"
    fi

    # Prepare Kerberos environment
    set_kerberos_realm "$domain"

    # Map domain groups to local Unix groups
    set_domain_group_mapping

    # Set time sync from dc for client
    write_pool "$domain"
    write_ntp_status "#t"

    # Adapt DM for too many domain users
    adapt_dm
}

#initial settings
init()
{
    # removing host parameter from pam_ldap_conf
    remove_host_from_confs
    if [ -f "$nssldapfile1" ]; then
        write_config "$nssldapfile1" bind_policy soft
        write_config "$nssldapfile1" bind_timelimit 30
    fi
}

# Enable service and (re)start it
enable_service() {
    service="$1"
    if [ -e "/etc/init.d/$service" -o -e "/lib/systemd/system/$service.service" ]; then
        chkconfig $service on &>/dev/null
        [ -n "$(service $service status| grep '^active\|running$')" ] && service $service stop &>/dev/null
        service $service start >/dev/null
    fi
    return 0
}

# Disable service and stop it
disable_service() {
    service="$1"
    if [ -e "/etc/init.d/$service" -o -e "/lib/systemd/system/$service.service" ]; then
        chkconfig $service off &>/dev/null
        [ -n "$(service $service status| grep '^active\|running$')" ] && service $service stop &>/dev/null
    fi
    if [ -e "/lib/systemd/system/$service.socket" ]; then
    	SYSTEMCTL="systemctl"
    	"$SYSTEMCTL" disable --now $service.socket
    fi
    return 0
}

# Set correct FQDN
set_hostname()
{
    local FQDN="$(lower "$1")"
    if [ -n "$FQDN" ]; then
        shell_config_set "/etc/sysconfig/network" "HOSTNAME" "$FQDN"
    fi
}

# Check domain name in DNS
check_domain_in_dns()
{
    host -t srv "_kerberos._tcp.$1" | grep -q 'has SRV record' 2>/dev/null
    if [ $? -ne 0 ]; then
        echo "Unable to find specified domain" >&2
        return 1
    fi
    return 0
}

# Set parameter to /etc/krb5.conf
krb5_config_set()
{
    local conf_file="$1"; shift
    local section="$1"; shift
    local param="$1"; shift
    local value="$1"; shift
    if grep -q "^[[:space:]]*$param[[:space:]]*=" "$conf_file" ; then
        subst "s/^\([[:space:]]*$param[[:space:]]*=[[:space:]]*\).*$/\1$value/" "$conf_file"
    else
        subst "/^\[$section\]$/a $param = $value" "$conf_file"
    fi
}

# Set Kerberos realm
set_kerberos_realm()
{
    test -e "$krb5_conf" || touch "$krb5_conf"
    krb5_config_set "$krb5_conf" "libdefaults" "default_realm" "$(upper $1)"
    krb5_config_set "$krb5_conf" "libdefaults" "dns_lookup_kdc" "true"
    krb5_config_set "$krb5_conf" "libdefaults" "dns_lookup_realm" "false"
    krb5_config_set "$krb5_conf" "libdefaults" "default_ccache_name" "KEYRING:persistent:%{uid}"
    # Prevent GSS failure in sssd (Server not found in Kerberos database)
    krb5_config_set "$krb5_conf" "libdefaults" "rdns" "false"
    chmod a+r "$krb5_conf"
}

# Join to Active Directory domin
join_ad_domain()
{
    local ldomain="$1"
    local domain="$(upper $ldomain)"
    local user="$2"
    local password="$3"
    local host_name="$4"

    [ -x /usr/bin/kinit ] || fatal "krb5-kinit is required for join to Active Directory domain"
    [ -x "$net_cmd" ] || fatal "$net_cmd from samba-common or samba-common-tools package is required for join to Active Directory domain"
    [ -n "$(ls /etc/init.d/{winbind,sssd} 2>/dev/null)" ] || fatal "samba-winbind or sssd-ad is required for join to Active Directory domain"

    # Prepare Kerberos environment
    set_kerberos_realm "$ldomain"

    # Get Kerberos ticket for administrator
    output="$(echo "$password" | kinit "$user@$domain" 2>&1 >/dev/null)"
    if [ "$?" -ne 0 ]; then
	#echo "ERROR: $output"
	error_unknown_kdc="$(echo "$output"|grep '^kinit: Cannot contact any KDC for realm')"
	error_bad_username="$(echo "$output"|grep '^kinit: Client not found in Kerberos database while getting initial credentials$')"
	error_bad_preauth="$(echo "$output"|grep '^kinit: Preauthentication failed while getting initial credentials$')"
	error_bad_credentials="$(echo "$output"|grep '^kinit: Password incorrect while getting initial credentials$')"
	[ -n "$error_unknown_kdc" ] && echo "Cannot contact KDC for realm" >&2
	[ -n "$error_bad_username" ] && echo "Unknown administrator name" >&2
	[ -n "$error_bad_preauth" ] && echo "Preauthentication failed" >&2
	[ -n "$error_bad_credentials" ] && echo "Wrong password" >&2
	return 1
    else
	# Set correct FQDN
	set_hostname "$host_name.$ldomain"

	# Join to domain
	$net_cmd ads join -U"$user%$password" --no-dns-updates

	[ "$?" -ne 0 ] && return 1

	# Register machine in domain DNS
	if [ -n "$host_name" ]; then
		$net_cmd ads dns register -U"$user%$password" "$host_name.$ldomain"
	fi

	# Destroy ticket
	kdestroy &>/dev/null
    fi
}

# Join FreeIPA domain
join_ipa_domain()
{
    local domain_name="$1"
    local host_name="$2"
    local admin_name="$3"
    local admin_password="$4"
    local log="/tmp/freeipa-join-$(date +%d.%m.%Y-%H:%M:%S)-$domain_name.log"

    # Begin log
    date > "$log"
    echo "Domain: $domain_name" >> "$log"
    echo >> "$log"

    # Set hostname
    set_hostname "$host_name.$domain_name"

    # Uninstall old join
    "$ipa_cmd" -U --uninstall &>/dev/null

    # Join to domain
    $ipa_cmd -U --domain "$domain_name" -p "$admin_name" -w "$admin_password" 2>&1 | tee -a "$log"
    ret=$?

    # Adapt DM for too many domain users
    adapt_dm

    echo "Finished at $(date)" >> "$log"
    return $ret
}

usage() {
    cat << USAGE.
Usage: system-auth [-d] action [object...]
Show or change system authentication scheme.

Options:
-d         Show debug output

Actions:
status     show current authentication information
list       list available authentication schemes
write      set authentication parameters
--version  show current program version

Examples:
Show current authentication information
  system-auth status

Use local authentication
  system-auth write local

Use LDAP authentication
  system-auth write ldap dc=domain,dc=name ldap://127.0.0.1

Use Active Directory authentication
  system-auth write ad domain.name host workgroup Administrator password

Use FreeIPA authentication
  system-auth write freeipa domain.name host admin password
USAGE.
}

# Place dns source immediately after files if .local domain is requested
check_avahi() {
	domain="$1"
	if [ "${domain##*.}" = 'local' ]; then
		subst '/^hosts:/ s/ dns//;s/files/files dns/' "$nsswitchfile"
	fi
}

action="$1" ; shift
[ "$action" = "-d" ] && action="$1" && shift
[ $# -ge 1 ] && object="$1" && shift

case "$action" in
    status)
        get_status
    ;;
    list)
        list
    ;;
    write)
	# Disable service of old scheme
	current="$(/usr/sbin/control system-auth)"
	[ "$current" = "ldap" -o "$current" = "krb5" ] && disable_service nslcd
	[ "$current" = "ldap" -o "$current" = "krb5" ] && disable_service settime-rfc867
	[ "$current" = "winbind" ] && disable_service winbind
	[ "$current" = "sss" ] && disable_service sssd

    case "$object" in
        local)
            write_profile "$object"
            ;;
        ldap|krb5*)
	    check_avahi "$2"
            if  check_basedn "$1" && check_uri "$2"  ;then
                if [ "$ldap_auth_sssd" = "yes" ]; then
                    rpm -q sssd-ldap sssd-krb5 &>/dev/null || fatal "LDAP authentication with SSSD requires both sssd-ldap and sssd-krb5 packages installed"
                    write_profile "$object"

                    # Extract domain name from ldap_uri
                    domain="${2##*/}"
                    domain="${domain##ldap.}"

                    # Store configuration parameters: domain baseDN ldap_uri
                    write_sssd_ldap_conf "$domain" "$1" "$2"

                    # Make topdir for home directories for Astra Linux Directory
                    domain_type="$(ldapsearch -x -LLL -b "$1" -h "$domain" -s base o 2>/dev/null | sed -n 's/o: //p')"
                    if [ "$domain_type" = "Astra Linux Directory" ]; then
                        mkdir /ald_home 2>/dev/null
                    fi

                    enable_service sssd
                    disable_service nscd
                else
                    init
                    write_profile "$object"
                    write_2_ldap base "$1"
                    write_2_ldap uri "$2"
                    # if nss-ldapd is used, restart daemon
                    enable_service nslcd
                    enable_service settime-rfc867
                fi
            else
                exit 1
            fi
            ;;
        ad)
            if  test -n "$1" ;then
		check_avahi "$1"
                test -x "$net_cmd" || fatal "Cannot find $net_cmd executable required to join to Active Directory domain"
                # Check domain name in DNS
                check_domain_in_dns "$1" || exit 1
                write_profile "$object"
                # Sync time with DC before join
                $net_cmd time set -S "$1" &>/dev/null
                # Store configuration parameters: domain [hostname] [workgroup]
                write_ad_conf "$1" "$2" "$3"
                # Join computer to domain
                join_ad_domain "$1" "$4" "$5" "$2"
                [ "$?" -ne 0 ] && exit 1
                # prepare auth service
                if [ -e "$sssd_conf" ]; then
		    disable_service nscd
                    enable_service sssd
                fi
                enable_service winbind
            else
                exit 1
            fi
            ;;
        freeipa)
            if  test -n "$1" ;then
		check_avahi "$1"
                test -x "$ipa_cmd" || fatal "Cannot find $ipa_cmd executable required to join to FreeIPA domain"
                # Check domain name in DNS
                check_domain_in_dns "$1" || exit 1
                join_ipa_domain "$1" "$2" "$3" "$4"
                [ "$?" -ne 0 ] && exit 1
                # prepare auth service
                enable_service sssd
            else
                exit 1
            fi
            ;;

        *)
            fatal "unknown auth type $object"
        ;;
      esac
    ;;
    --version)
        rpm -q alterator-auth --qf '%{version}\n'
	;;
    *)
	usage
	;;
esac

