#!/bin/sh

alterator_api_version=1
po_domain="alterator-ldap-users"

cache_dir="/var/cache/alterator/ldap-users"

default_groups="cdwriter cdrom audio proc radio camera floppy xgrp scanner uucp users"
#turn off auto expansion
set -f

. alterator-sh-functions
. alterator-openldap-functions
. shell-quote

### cache

reset_cache()
{
  rm -rf -- "$cache_dir"
  mkdir -p -- "$cache_dir"
}

### e-mail

# read all available emails
email_list()
{
  local user="$1";shift
  local email_file="$cache_dir/email-$user"

  if [ -f "$email_file" ];then
	cat "$email_file"
  else
   ldap-getent passwd "$user" mail|
    sed -e 's/,[[:blank:]]*/\n/g'|
    tee "$email_file"
  fi
}

# add email to list
email_add()
{
  local user="$1";shift
  local email="$1";shift
  local email_file="$cache_dir/email-$user"

  [ -f "$email_file" ] || email_list >/dev/null
  file_list_add "$email_file" "$email"
}

# remove email from list
email_del()
{
  local user="$1";shift
  local email="$1";shift
  local email_file="$cache_dir/email-$user"

  [ -f "$email_file" ] || email_list >/dev/null
  file_list_del "$email_file" "$email"
}

# reset email value
email_reset()
{
  local user="$1";shift
  local email_file="$cache_dir/email-$user"

  rm -f -- "$email_file"
}

# commit email value
email_commit()
{
  local user="$1";shift
  local email_file="$cache_dir/email-$user"

  [ -f "$email_file" ] || return 0

  if [ -s "$email_file" ]; then
	sed 's/.*/mail:&/' "$email_file"|ldap-usermod replace "$user" > /dev/null
  else
	printf 'mail:\n'|ldap-usermod replace
  fi
  email_reset "$user"
}

###

is_defined()
{
	set | grep -qs "^$1="
}

user_args()
{
	in_cn="$in_sn"
	[ -n "$in_givenname" ] && in_cn="$in_cn $in_givenname"
	[ -n "$in_patronym" ] && in_cn="$in_cn $in_patronym"
	for attr in givenname sn cn o title telephonenumber mobile homedirectory loginshell; do
		is_defined "in_$attr" && printf '%s:%s\n' "$attr" "$(eval printf %s \"\$in_$attr\")"
	done
}

user_read()
{
	local name="$1";shift

	ldap-getent passwd "$name" uid userPassword givenName sn cn o title telephoneNumber mobile homeDirectory loginShell |
		(IFS=: read name userpassword givenname sn cn o title telephonenumber mobile homedirectory loginshell;
		patronym="$(echo ${cn#$sn})"
		patronym="$(echo ${patronym#$givenname})"
		for f in userpassword givenname cn sn patronym o title telephonenumber mobile homedirectory loginshell; do
			write_string_param "$f" "$(eval printf %s \"\$$f\")"
		done

		[ -n "$userpassword" -a -z "${userpassword##!!*}" ] &&
			write_bool_param is_active false ||
			write_bool_param is_active true
		)
}

ldap_user_add_default_groups()
{
    [ -n "$1" ] || return
    for i in $default_groups ;do
        [ -n "$(ldap-getent group "$i")" ] &&
        printf 'memberUid:%s\n' "$1" | ldap-groupmod add "$i" > /dev/null
    done
}

ldap_user_del_default_groups()
{
    [ -n "$1" ] || return
    for i in $(ldap-getent group '*' cn memberUid|egrep "(:$1,|:$1$|,$1,|,$1$)"|cut -f1 -d':')
    do
        printf 'memberUid:%s\n' "$1" | ldap-groupmod del "$i" > /dev/null
    done
}

user_chpasswd()
{
	local r="$(echo "$2" |ldap-passwd "$1" 2>&1)"
    [ -n "$r" ] && write_error "$r" && return 1
    :
}

user_new()
{
	local r="$(ldap-useradd "$1" 2>&1)"
    [ -n "$r" ] && write_error "$r" && return 1
    # trying to init user homedir
    local init_user="$(su - $1 -s /bin/true > /dev/null 2>&1)"
    :
}

user_write()
{
	local r="$(user_args |
		ldap-usermod replace "$1" 2>&1)" 
        [ -n "$r" ] && write_error "$r" && return 1
    :
}

user_delete()
{
	local r="$(ldap-userdel "$1" 2>&1)"
    [ -n "$r" ] && write_error "$r" && return 1
    :
}

set_dn_conf()
{
    local dn="$(system-auth status|cut -f2 -d' ')"
    [ -n "$dn" ] || fatal "set_dn_conf: couldn't detect dn"

    DN_CONF="$(/usr/sbin/ldap-dn find "$dn")"
    [ -f "$DN_CONF" ] || fatal "set_dn_conf: $DN_CONF doesn't exist"

    export ENABLE_KRB="yes"
    export DN_CONF
    base_rootdn_rootpw
}

set_dn_conf
reset_cache

on_message()
{
	case "$in_action" in
		type)
			write_type_item newusername system-account-name
			write_type_item newemail e-mail
			write_type_item telephonenumber telephone-number
			write_type_item mobile telephone-number
			;;
		#object manipulations
		list)
			case "$in__objects" in
				avail_shell)
					while read sh; do
						[ -x "$sh" ] || continue
						write_enum_item "$sh"
					done </etc/shells
					write_enum_item "/sbin/nologin"
					;;
				*)
                local IFS=$'\n'
                for i in $(ldap-getent passwd '*' uid|sort) ;do
                    write_enum_item "$i"
                done
					;;
			esac
			;;
		read)
			[ -n "$in_user" ] || return

			write_string_param passwd_auto "$(pwqgen)"
			! test_bool "$in_auto"
			write_bool_param auto "$?"

			[ -n "$in_user" ] && user_read "$in_user"
			;;
		write)
			[ -n "$in_user" ] || return

			#main settings
			user_write "$in_user" || return

			#password
			if test_bool "$in_auto" && [ -n "$in_passwd_auto" ]; then
				user_chpasswd "$in_user" "$in_passwd_auto"
			elif ! test_bool "$in_auto" && [ -n "$in_passwd_1" -o -n "$in_passwd_2" ] ; then
				if [ "$in_passwd_1" != "$in_passwd_2" ]; then
					write_error "`_ "Passwords mismatch"`"
					return
				else
					user_chpasswd "$in_user" "$in_passwd_1"
				fi
			fi

			;;
		new)
			[ -n "$in_newusername" ] || return
			#new
			user_new "$in_newusername" || return
			email_add "$in_newusername" "$in_newusername@$(dn_2_host "$base")"
			email_commit "$in_newusername"
			ldap_user_add_default_groups "$in_newusername"
			;;
		delete)
			if [ -n "$in_user" ] ;then
                IFS=$'\n'
                for user in $(echo $in_user|sed -e 's/;/\n/g')
                do
                    user_delete "$user" || return
                    ldap_user_del_default_groups "$user"
                done
			fi
			;;
		email_add)
		    [ -n "$in_user" -a -n "$in_newemail" ] || return
		    email_add "$in_user" "$in_newemail"
		    ;;
		email_del)
		    [ -n "$in_user" -a -n "$in_email" ] || return
		    email_del "$in_user" "$in_email"
		    ;;
		email_list)
		    [ -n "$in_user" ] || return
		    email_list "$in_user" |write_enum
		    ;;
		email_commit)
		    [ -n "$in_user" ] || return
		    email_commit "$in_user"
		    ;;
		email_reset)
		    [ -n "$in_user" ] || return
		    email_reset "$in_user"
		    ;;
		generate)
		    write_string_param passwd_auto "$(pwqgen)"
		    ;;
	esac
}

message_loop
