Zimbra + LDAP часть 2 (неожиданное письмо)

Приветствую вас мои дорогие читатели... может местами даже подписчики.
На днях ко мне пришло на почту вот такое письмо.

Текст письма полностью сохранен.

"Добрый день. 
Я немного модифицировал ваш скрипт для синхронизации с АД. 
Единственное, убрана настройка для авторизации через АД, но её легко можно добавить из вашего скрипта.
Синхронизируются почти все поля пользователя Zimbra. Если поле не содержит кириллицы закомментировать строку "=`echo $l | base64 -d`"
Создает alias для пользователя для всех доменов Zimbra на основе поля mail в АД, удаляя всё после @.
Теперь его можно запускать с параметрами:
add - добавление новых пользователей. Сравнивает пользователей AD и Zimbra, и добавляет отсутствующих.
sync - тупо вытаскивает пользователей из AD и впихивает в Zimbra
remove - удаляет пользователей находящихся в OU "Уволенные".
Можно добавить в крон и будет сам таскать и удалять пользователей, при недоступности dc нужных пользователей не удалит.
 
Может выложите у себя на сайте. Вдруг кому еще поможет.
 
С уважением, Евгений."

Дорогой Евгений. Спасибо вам большое лично от меня за проделаную вами работу. И за это письмо. Я человек, который не привык присваивать к себе чьи то труды. Так что эта запись здесь распологается именно от вашего имени, я просто подумал что у вас может нет возможности или желания разместить её здесь от себя, ну это не страшно я сделаю это за вас. И все спасибо, коментарии и + будут адресованы именно вам.
Я лишь выступаю здесь в роли печатного издания и ниначто не притендую.
Так что все права и похвала ребята за это, говорите дорогому Евгению.

P.S. к сожалению в данный момент я не могу детально просмотреть скрипт(много работы по внедрению оборудования, всё внимание пока сконцентрированно на ней) я просто его выкладываю сюда как он есть без каких либо исправлений, но как и всегда буду стараться отвечать на коментарии как можно быстрее.
Ещё раз большое спасибо тебе Евгений за твои труды и твоё письмо. Желаю творческих успехов и удачи!
 
# ======================================================================
#
# NAME: AD domain and Zimbra Domain(s)
#
# DATE  : 25.07.2014
#
# PURPOSE: Add, Sync and Remove users in Zimbral LDAP
#
# ======================================================================
#!/bin/bash
 
Domain="test.local" # DNS Name or IP of Active Directory
ADDOMAIN="zimbra.test.ru" # if zimbra have some other domain like (zuza.com, ziza.com, ugauga,com)
 
#Values
LDAPSEARCH=/opt/zimbra/bin/ldapsearch
ZMPROV=/opt/zimbra/bin/zmprov
DOMAIN_NAME="test.ru"
TIMESTAMP=`date +%N`
TMP_DIR=/var/tmp
ADS_TMP=$TMP_DIR/users_ads_$TIMESTAMP.lst
ZCS_TMP=$TMP_DIR/users_zcs_$TIMESTAMP.lst
DIF_TMP=$TMP_DIR/users_dif_$TIMESTAMP.lst
LDAP_TMP=$TMP_DIR/ldap_$TIMESTAMP.lst
 
# Server values
LDAP_SERVER="ldap://dc.test.local"
BASEDN="OU=USERS,dc=test,dc=local"
REMDN="OU=Уволенные,dc=test,dc=local"
BINDDN="CN=zimbra,OU=Services,DC=test,dc=local"
BINDPW="P@$$W)RD" #user password 123
FILTER="(&(!(objectClass=computer))(objectClass=user))"
FIELDS="givenName sn telephoneNumber mobile company title l st co description mail"
 
#Function's
 
function extract_user_AD()
{
	# Extract users from ADS
	echo "Extract users from AD $1... "
	$LDAPSEARCH -x -H $LDAP_SERVER -b $1 -D "$BINDDN" -w $BINDPW "$FILTER"  | 
	grep "sAMAccountName" | 
	awk '{print $2}' | 
	sort > $ADS_TMP
	echo "Found `cat $ADS_TMP | wc -l` users ($ADS_TMP)"
}
 
function extract_users_Zimbra()
{
	#Extract users from ZCS
	echo "Quering ZCS... "
	$ZMPROV -l gaa $DOMAIN_NAME | sed 's/@.*//g' | sort > $ZCS_TMP
	echo "Found `cat $ZCS_TMP | wc -l` users ($ZCS_TMP)"s
}
 
#Function for adding users in Zimbra LDAP from Active Directory
function modify_user()
{
	# Import new users
	echo -n "New users: "
	cat $DIF_TMP | grep ^+ | wc -l
 
	if [ "$1" == "add" ]
	then
		item=`cat $DIF_TMP | grep ^+ | sed s/^+//g`
	fi
 
	if [ "$1" == "sync" ]
	then
		item=`cat $ADS_TMP`
	fi
 
	for i in $item
	do
		echo -n " - Adding $i "
 
		searchValues=`$LDAPSEARCH -x -H $LDAP_SERVER -b $BASEDN -D $BINDDN -w $BINDPW -LLL "(sAMAccountName=$i)" sAMAccountName`
		Username=`echo $searchValues | grep -w sAMAccountName: | awk '{split ($0, a, "sAMAccountName:"); print a[2]}' | awk '{print $1}'` #get the username
 
		$LDAPSEARCH -x -H $LDAP_SERVER -b $BASEDN -D $BINDDN -w $BINDPW -LLL "(sAMAccountName=$i)" $FIELDS > $LDAP_TMP
 
		givenName=`cat $LDAP_TMP | grep -w givenName::| awk '{split ($0, a, ": "); print a[2]}'` 
		givenName=`echo $givenName | base64 -d`
 
		sn=`cat $LDAP_TMP | grep -w sn::| awk '{split ($0, a, ": "); print a[2]}'`
		sn=`echo $sn | base64 -d`
 
		telephoneNumber=`cat $LDAP_TMP | grep -w telephoneNumber:| awk '{split ($0, a, ": "); print a[2]}'`
		# telephoneNumber=`echo $telephoneNumber | base64 -d`
 
		mobile=`cat $LDAP_TMP | grep -w mobile:| awk '{split ($0, a, ": "); print a[2]}'`
		# mobile=`echo $mobile | base64 -d`
 
		l=`cat $LDAP_TMP | grep -w l::| awk '{split ($0, a, ": "); print a[2]}'`
		l=`echo $l | base64 -d`
 
		st=`cat $LDAP_TMP | grep -w st::| awk '{split ($0, a, ": "); print a[2]}'`
		st=`echo $st | base64 -d`
 
		co=`cat $LDAP_TMP | grep -w co::| awk '{split ($0, a, ": "); print a[2]}'`
		co=`echo $co | base64 -d`
 
		company=`cat $LDAP_TMP | grep -w company::| awk '{split ($0, a, ": "); print a[2]}'`
		company=`echo $company | base64 -d`
 
		title=`cat $LDAP_TMP | grep -w title::| awk '{split ($0, a, ": "); print a[2]}'`
		title=`echo $title | base64 -d`
 
		description=`cat $LDAP_TMP | grep -w description::| awk '{split ($0, a, ": "); print a[2]}'`
		description=`echo $description | base64 -d`
 
		mail=`cat $LDAP_TMP | grep -w mail: | awk '{split ($0, a, ": "); print a[2]}'|awk '{split ($0, a, "@"); print a[1]}'`
 
		Username=$Username"@"$DOMAIN_NAME
		printf "Creating User $Username n"
 
		$ZMPROV ca $Username passwd > /dev/null
		$ZMPROV ma $i displayName "$givenName $sn" > /dev/null
		$ZMPROV ma $i givenName $givenName > /dev/null
		$ZMPROV ma $i sn $sn > /dev/null
		$ZMPROV ma $i telephoneNumber $telephoneNumber > /dev/null
		$ZMPROV ma $i mobile $mobile > /dev/null
		$ZMPROV ma $i l $l > /dev/null
		$ZMPROV ma $i st $st > /dev/null
		$ZMPROV ma $i co $co > /dev/null
		$ZMPROV ma $i company $company > /dev/null
		$ZMPROV ma $i title $title > /dev/null
		$ZMPROV ma $i description $description > /dev/null
 
		for m in $(/opt/zimbra/bin/zmprov gad)
		do 
			$ZMPROV aaa $i $mail@$m; #Account Alias based upon domain's aliases
		done
 
	RES=$?;
	if [ "$RES" == "0" ] 
	then 
		echo "[Ok]" 
	else 
		echo "[Err]" 
	fi
	done
}
 
function delete_user()
{
	# Delete old users
	echo -n "Old users: "
	cat $DIF_TMP | grep ^" " | wc -l
	for i in $(cat $DIF_TMP | grep ^" " | sed s/^" "//g)
	do
		echo -n " - Deleting $i "
		$ZMPROV deleteAccount $i > /dev/null;
		RES=$?
		if [ "$RES" == "0" ] 
		then 
			echo "[Ok]" 
		else 
			echo "[Err]"
		fi
	done
}
 
#Adding users from AD to Zimbra
if [ "$1" == "add" ]
then 
	extract_user_AD $BASEDN
	extract_users_Zimbra
	echo "Generating diff file ($DIF_TMP)"
	diff -u -i $ZCS_TMP $ADS_TMP | sed 1,3d > $DIF_TMP
	modify_user add
fi
 
#Syncing users from AD to Zimbra
if [ "$1" == "sync" ] 
then
	#extract user for sync fields
	extract_user_AD $BASEDN
	modify_user sync
fi
 
#Removing users from Zimbra
if [ "$1" == "remove" ]
then
	echo "Extract users for remove..."
	extract_user_AD $REMDN
	extract_users_Zimbra
	echo "Generating diff file ($DIF_TMP)"
	diff -u -i $ZCS_TMP $ADS_TMP | sed 1,3d > $DIF_TMP
	delete_user
fi
 
# Removing temp files
rm -f $LDAP_TMP, $ADS_TMP, ZCS_TMP, DIF_TMP
 
2727

Комментарии

Почему то пишет
- line 209: ошибка синтаксиса: неожиданный конец файла.
 Все прекрастно, скрипт работает, но....

непонятки с кодировкой при экспорте записей из AD в Zimbra
(Windows Server 2008R2. CentOs 7. Zimbra 8.5.1)

Вместо кирилици получаю вот такое: ��������
из консоли работает все корректно 
[root@mail tmp]# echo 0KDQvtGB0YHQuNGP | base64 -d
Россия
Кто сталкивался с такой проблемой, подскажите решение, куда глядеть? Спасибо!
Чтобы ldap не переносил длинные строки, нужно добавить параметр (-o ldif-wrap=no):
$LDAPSEARCH -o ldif-wrap=no -x -H $LDAP_SERVER -b $BASEDN -D $BINDDN -w $BINDPW -LLL "(sAMAccountName=$i)" $FIELDS > $LDAP_TMPT
Скрипт обходит пользователей медленно, а если их очень много, то проблема! Ускорить можно, для этого все " $ZMPROV ma " свести в одну запись, т.е. все изменения учетки отработают за одну команду:
$ZMPROV ma $i displayName "$givenName $sn" givenName $givenName  sn $sn ... и т.д.
А вообще еще много чего можно сделать. Доделаю свой скрипт, может выложу...