From f55d282b6ccb65f8bd37fc922507ad16b6024c2f Mon Sep 17 00:00:00 2001 From: Turo Soisenniemi Date: Wed, 24 Aug 2022 22:47:43 +0300 Subject: [PATCH 1/5] Support for nested groups (AD) Fixes https://github.com/BernhardLinz/zabbix-ldap-sync-bash/issues/4. When using nested group search, full path to group must be provided. --- zabbix-ldap-sync.sh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/zabbix-ldap-sync.sh b/zabbix-ldap-sync.sh index ff31dc9..a62fab6 100755 --- a/zabbix-ldap-sync.sh +++ b/zabbix-ldap-sync.sh @@ -387,6 +387,14 @@ else Print_Verbose_Text "ZABBIX_MediaTypeID (using Default Value)" "${ZABBIX_MediaTypeID}" fi #################################################################################################### +if [ ${AD_nested_groups} == 1 ]; then + Print_Verbose_Text "AD nested groups" "enabled" + LDAP_member_search_filter="(&(objectClass=group)(memberOf:1.2.840.113556.1.4.1941:=${LDAP_Groupname_for_Sync}))" +else + Print_Verbose_Text "AD nested groups" "disabled" + LDAP_member_search_filter="(&(objectClass=group)(cn=${LDAP_Groupname_for_Sync}))" +fi +#################################################################################################### if [ "$b_verbose" = "false" ]; then Print_Status_Done "done" $GREEN else @@ -423,30 +431,30 @@ if [ LDAP_Ignore_SSL_Certificate = "false" ]; then # normal ldapsearch call if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "(&(objectClass=group)(cn="'$LDAP_Groupname_for_Sync'"))"' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter}' else - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "(&(objectClass=group)(cn="'$LDAP_Groupname_for_Sync'"))"' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter}' fi fi # yes, ldapsearch is called twice - first time without grep to catch the exitcode, 2. time to catch the content - tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "(&(objectClass=group)(cn=$LDAP_Groupname_for_Sync))" o member` + tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member` ldapsearch_exitcode="$?" if [ "$b_verbose" = "true" ]; then echo "ldapsearch_exitcode: $ldapsearch_exitcode"; fi - tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "(&(objectClass=group)(cn=$LDAP_Groupname_for_Sync))" o member | grep member:` + tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member | grep member:` else # ignore SSL ldapsearch if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "(&(objectClass=group)(cn='$LDAP_Groupname_for_Sync'))" o member' + echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter} o member' else - echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "(&(objectClass=group)(cn='$LDAP_Groupname_for_Sync'))" o member' + echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter} o member' fi fi # yes, ldapsearch is called twice - first time without grep to catch the exitcode, 2. time to catch the content - tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "(&(objectClass=group)(cn=$LDAP_Groupname_for_Sync))" o member` + tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member` ldapsearch_exitcode="$?" if [ "$b_verbose" = "true" ]; then echo "ldapsearch_exitcode: $ldapsearch_exitcode"; fi - tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "(&(objectClass=group)(cn=$LDAP_Groupname_for_Sync))" o member | grep member:` + tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member | grep member:` fi if [ "$b_verbose" = "true" ]; then echo 'Result ldapsearch (with "grep member:" : '"$tempvar" From a2275faa28927ca1055a0a4a8a06180b97d9fd5e Mon Sep 17 00:00:00 2001 From: Turo Soisenniemi Date: Wed, 24 Aug 2022 22:51:20 +0300 Subject: [PATCH 2/5] Example configuration for nested groups --- config-example.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config-example.sh b/config-example.sh index 9490b81..e1514f7 100644 --- a/config-example.sh +++ b/config-example.sh @@ -31,6 +31,8 @@ LDAP_SearchBase="DC=exampledomain,DC=local" # Name of Groups in LDAP (Active-Directory) and in Zabbix for Sync with Zabbix LDAP_Groupname_for_Sync="Zabbix-Super-Admin" ZABBIX_Groupname_for_Sync="LDAP-SuperAdmin" +# When nested groups are enabled LDAP_Groupname_for_Sync must be provided with full path to group. e.g. CN=group,OU=Groups,DC=example,DC=com +AD_nested_groups=0 # When you remove an user from the LDAP-Group, the user will moved in this group which is "Not enabled" = Disabled and Frontend access is "disabled" ZABBIX_Disabled_User_Group="LDAP-Disabled" From 9fd50be4f8b47292152a7d6414b4caf4bd75642a Mon Sep 17 00:00:00 2001 From: Turo Soisenniemi Date: Thu, 25 Aug 2022 09:08:43 +0300 Subject: [PATCH 3/5] Fixed space support in ldap group --- zabbix-ldap-sync.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/zabbix-ldap-sync.sh b/zabbix-ldap-sync.sh index a62fab6..b68da2b 100755 --- a/zabbix-ldap-sync.sh +++ b/zabbix-ldap-sync.sh @@ -431,30 +431,30 @@ if [ LDAP_Ignore_SSL_Certificate = "false" ]; then # normal ldapsearch call if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter}' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter"}' else - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter}' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}"' fi fi # yes, ldapsearch is called twice - first time without grep to catch the exitcode, 2. time to catch the content - tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member` + tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "${LDAP_member_search_filter}" o member` ldapsearch_exitcode="$?" if [ "$b_verbose" = "true" ]; then echo "ldapsearch_exitcode: $ldapsearch_exitcode"; fi - tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member | grep member:` + tempvar=`ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "${LDAP_member_search_filter}" o member | grep member:` else # ignore SSL ldapsearch if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter} o member' + echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}" o member' else - echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" ${LDAP_member_search_filter} o member' + echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}" o member' fi fi # yes, ldapsearch is called twice - first time without grep to catch the exitcode, 2. time to catch the content - tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member` + tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "${LDAP_member_search_filter}" o member` ldapsearch_exitcode="$?" if [ "$b_verbose" = "true" ]; then echo "ldapsearch_exitcode: $ldapsearch_exitcode"; fi - tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" ${LDAP_member_search_filter} o member | grep member:` + tempvar=`LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H $LDAP_Source_URL -D "$LDAP_Bind_User_DN" -w "$LDAP_Bind_User_Password" -b "$LDAP_SearchBase" "${LDAP_member_search_filter}" o member | grep member:` fi if [ "$b_verbose" = "true" ]; then echo 'Result ldapsearch (with "grep member:" : '"$tempvar" From 9c184169f3ce0a1de52509ce9701b053ab624872 Mon Sep 17 00:00:00 2001 From: Turo Soisenniemi Date: Thu, 25 Aug 2022 09:12:14 +0300 Subject: [PATCH 4/5] fixed typo --- zabbix-ldap-sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zabbix-ldap-sync.sh b/zabbix-ldap-sync.sh index b68da2b..0addf20 100755 --- a/zabbix-ldap-sync.sh +++ b/zabbix-ldap-sync.sh @@ -431,7 +431,7 @@ if [ LDAP_Ignore_SSL_Certificate = "false" ]; then # normal ldapsearch call if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter"}' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}"' else echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}"' fi From 63949ee1f14fe99fc0d2b8c0a97cddb4f18aeac6 Mon Sep 17 00:00:00 2001 From: Turo Soisenniemi Date: Tue, 27 Sep 2022 16:19:59 +0300 Subject: [PATCH 5/5] Fixed printing actual search filter when using verbose --- zabbix-ldap-sync.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zabbix-ldap-sync.sh b/zabbix-ldap-sync.sh index 0addf20..67bfe39 100755 --- a/zabbix-ldap-sync.sh +++ b/zabbix-ldap-sync.sh @@ -431,9 +431,9 @@ if [ LDAP_Ignore_SSL_Certificate = "false" ]; then # normal ldapsearch call if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}"' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "'${LDAP_member_search_filter}'"' else - echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}"' + echo 'ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "'${LDAP_member_search_filter}'"' fi fi # yes, ldapsearch is called twice - first time without grep to catch the exitcode, 2. time to catch the content @@ -445,9 +445,9 @@ else # ignore SSL ldapsearch if [ "$b_verbose" = "true" ]; then if [ "$b_showpasswords" = "true" ]; then - echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}" o member' + echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "'$LDAP_Bind_User_Password'" -b "'$LDAP_SearchBase'" "'${LDAP_member_search_filter}'" o member' else - echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "${LDAP_member_search_filter}" o member' + echo 'LDAPTLS_REQCERT=never ldapsearch -x -o ldif-wrap=no -H '$LDAP_Source_URL' -D "'$LDAP_Bind_User_DN'" -w "***********" -b "'$LDAP_SearchBase'" "'${LDAP_member_search_filter}'" o member' fi fi # yes, ldapsearch is called twice - first time without grep to catch the exitcode, 2. time to catch the content