web-dev-qa-db-ja.com

BASHを使用したLDAP検索フィルター

Bashスクリプトで次のクエリを実行しようとしています。これにより、whileループから渡された定義済みの属性について、2つの異なるオブジェクトクラスをチェックできます。

#!/bin/bash

inputfile="$1"
binddn="cn=admin,o=services"
password="BLAH"
IFS=','
while read -r Field1 Field2 Field3 Field4 Field5 Field6 ;
do
    ldapsearch -h "`hostname --fqdn`" -p 389 -x -LLL -D "${binddn}" -w "${password}" "'(&(|(ObjectClass=Group1)(ObjectClass=Group2))(Field1Attribute="${Field1}"))'"
done < "$inputfile"
exit 0

コマンドを実行するたびに、変数Field1は正常に渡されますが、不正な検索フィルターエラーが発生します。

ldapsearch -h HOSTNAME -p 389 -x -LLL -D cn=admin,o=services -w BLAH ''\''(&(|(ObjectClass=Group1)(ObjectClass=Group2))(Field1Attribute=FIELD1OUTPUT))'\'''
ldapsearch: ldap_search_ext: Bad search filter (87)

コマンドがフィルターの最初と最後に( ''\')を追加することに気づきました。ティックとバックスラッシュを除いたコマンドを手動で実行すると、クエリは正常に実行されます。これはどのように追加されますか?

また、検索フィルターを変数として渡しただけでなく、コマンド自体も成功していません。

5
drfunkenstein

もし、するなら:

ldapsearch -h ... "'(&(this)(that="${Field1}"))'"

一重引用符は引用符付き文字列の一部になり、ldapsearchに移動します。それらを期待しないので、エラーが発生します。また、2番目の二重引用符が引用を終了するため、${Field1}の展開は引用されません。 (引用はネストしません。)

他の出力は、Bashのxtraceの出力のようになります。引数には文字通りの引用が実際に含まれていると伝えようとしますが、引用は読みにくいです。

これで:

''\''(&(|(ObjectClass=Group1)(ObjectClass=Group2))(Field1Attribute=FIELD1OUTPUT))'\'''

我々は持っています

''           -- an empty string
\'           -- a literal backslash
'(&(|(...))' -- a quoted string
\'           -- another literal backslash
''           -- another empty string

あなたが欲しいのはどちらかだと思う

ldapsearch -h ... "(&(this)(that=\"${Field1}\"))"

文字列の二重引用符がldapsearchになっている、または

ldapsearch -h ... "(&(this)(that=${Field1}))"

彼らがいなければ。

いずれの場合も、周囲の単一引用符なし。二重引用符があるべきかどうか正確にはわかりません。ldapsearchルールが受け入れる形式を思い出せません。

私が実際にテストできる限り、これは1台のマシンで正常に動作します。

$ user=itvirta
$ ldapsearch -xLLL "(&(objectClass=shadowAccount)(uid=$user))" 
$ ldapsearch -xLLL '(&(objectClass=shadowAccount)(uid=itvirta))' 
4
ilkkachu