• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Shell script zur SQL und LDAP Abfrage

tonosinai

Newbie
Hallo Leute ich habe mir für meinen Mailserver ein kleines Script gebastelt, welches sich an einem LDAP Server anmeldet und dort Benutzer ausliest, welche sich in einer bestimmten Gruppe befinden. Anschließend ließt es Benutzerabhängig aus einer MySQL Datenbank Daten aus und verschickt diese per Mail an den Benutzer. Das Script läuft soweit auch problemlos. Da dies mein 1. Shelscript ist würde ich gern ein paar Meinungen dazu hören. Wahrscheinlich gibt es 1000 Verbesserungsvorschläge, wie man Dinge einfacher machen kann ;-)

Code:
#!/bin/bash
# Programm zum automatischen Ermitteln der eingegangenen Spams
# Author: Stefan
# Land: Deutschland
# Mail: 
# Scriptversion: 0.3
# Changelog:	0.1 Erstellung des Scripts 28.01.11
#		0.2 Erstellung Benutzerabfrage über LDAP/AD 30.01.11
#		0.3 Einführung Funktion zur Nutzung mehrerer LDAP Server 31.01.11

#Globale Variablen

#Datumskonvertierung
datum=`date +"%d.%m.%Y"` #Datum im Format Tag Monat Jahr
tag=`date +"%w"` #Tag der Woche
hostname=hostname

#Definition  der Programmpfade
muttbin=/usr/bin/mutt   	#Mailprogramm
mysqlbin=/usr/bin/mysql 	#Mysql
ldapbin=/usr/bin/ldapsearch	#Ldapsearch
grepbin=/usr/bin/grep		#grep
awkbin=/usr/bin/awk		#awk

#Definition der MySQL Daten
mysqluser=db
mysqlpassword=geheim
mysqldb=spam
mysqlhost=127.0.0.1

#Definition der LDAP Daten
basedn="dc=example,dc=com"
ldapuser="cn=ldapabfrage,ou=Serviceaccounts"
ldappass='geheim'
ldapgroup="CN=spambox1,OU=Gruppen" #Benutzer muss Mitglied in dieser Gruppe sein
ldaphost=(10.0.0.1 10.0.0.2) #Angabe von mehreren LDAP Hosts möglich
ldapport=389

#Definition des Mailaufbaus
adminmail=admin@example.com
subjectd="Tägliche Spamübersicht $datum"
subjectw="Wöchentliche Spamübersicht $datum"
homedir=/tmp
body=$homedir/mailtext #Textdatei zum Erstellen des Mailtext 
domain=example.com #Maildomäne
url="http://spambox" #Webfrontend URL Domäne wird automatisch im Mailtext ergänzt

#Ende der Variablendeklaration

#Test der LDAP Verbindung
ldaptest=($($ldapbin -LLL -x -b "$basedn" -D "$ldapuser,$basedn" -h $ldaphost -p $ldapport -w $ldappass))
ldapcount=1
while [ "${#ldaptest[*]}" -eq "0" ]
	do
		if [ $ldapcount -eq ${#ldaphost[*]} ]; then
			ldaptest=1
		else	
			ldaphost=${ldaphost[$ldapcount]}
			ldaptest=($($ldapbin -LLL -x -b "$basedn" -D "$ldapuser,$basedn" -h $ldaphost -p $ldapport -w $ldappass))
			ldapcount=$[$ldapcount+1]
		fi
	done

#Programmaufruf

if [ $ldaptest = "1" ]; then
	echo "Kein LDAP Server gefunden" > $body
	$muttbin -s "LDAP Abfrage fehlgeschlagen $hostname" $adminmail < $body
else
	#E.Mailuser auslesen
	user=($($ldapbin -LLL -x -b "$basedn" -D "$ldapuser,$basedn" -h $ldaphost -p $ldapport -w $ldappass -s sub "(memberOf=$ldapgroup,$basedn)" sAMAccountName | grep sAMAccountName | awk '{ print $2 }'))

	#Anrede Auslesen
	anrede=($($ldapbin -LLL -x -b "$basedn" -D "$ldapuser,$basedn" -h $ldaphost -p $ldapport -w $ldappass -s sub "(memberOf=$ldapgroup,$basedn)" name | $grepbin name | $awkbin '{ print $2 }'))

	count=0           #Zähler auf Null setzen

	#So lange durchlaufen  bis count nicht mehr unter der Anzahl der Datensätze im Array ist
	while [ $count -le $[${#user[*]}-1] ] #-1 da der Array eine Zahl zuviel ausgibt
	      do
	        userid=${user[$count]}
	        anredeid=${anrede[$count]}
		
		#Definition SQL Abfrage
		if [ "$tag" = "0" ]; then
			select="SELECT CAST(msgs.time_iso AS DATE) AS Datum, msgs.from_addr AS Absender, msgs.subject AS Betreff FROM msgs INNER JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id LEFT JOIN maddr AS sender ON msgs.sid=sender.id LEFT JOIN maddr AS recip  ON msgrcpt.rid=recip.id	WHERE msgs.content != 'C' AND recip.email = '$userid@$domain' AND CAST(msgs.time_iso AS DATE) BETWEEN CURDATE() -7 AND CURDATE() ORDER BY msgs.time_iso DESC;"
		else	
			select="SELECT CAST(msgs.time_iso AS DATE) AS Datum, msgs.from_addr AS Absender, msgs.subject AS Betreff FROM msgs INNER JOIN msgrcpt ON msgs.mail_id=msgrcpt.mail_id LEFT JOIN maddr AS sender ON msgs.sid=sender.id LEFT JOIN maddr AS recip  ON msgrcpt.rid=recip.id	WHERE msgs.content != 'C' AND recip.email = '$userid@$domain' AND CAST(msgs.time_iso AS DATE) = CURDATE() ORDER BY msgs.from_addr DESC;"
	        fi
	        
	        #Ausführen der Abfrage
	        $mysqlbin -t --default-character-set=UTF8 --user=$mysqluser --password="$mysqlpassword" -D $mysqldb --execute="$select" > $homedir/$userid.txt
		
		#Auslesen der Dateigröße als Mailsendeoption
		gr=$(ls -l $homedir/$userid.txt | $awkbin '{ print $5 }')
		
		if [ "$gr" = "0" ]; then
	   		echo "Keine Spams vorhanden" > $body
	   	else
	   		echo "Hallo $anredeid," > $body
	   		echo " " >> $body
			echo "in der Tabelle findest du eine Auflistung der eingegangenen Spammails." >> $body
	   		echo " " >> $body
	   		$mysqlbin -t --default-character-set=UTF8 --user=$mysqluser --password="$mysqlpassword" -D $mysqldb --execute="$select" >> $body
	   		echo " " >> $body
	   		echo "Die Übersicht aller eingegangenen Spams findest du unter $url.$domain". >> $body
	   		echo "Anmeldung ist mit den Windowsanmeldedaten möglich." >> $body
	   		if [ "$tag" = "0" ]; then
	   			$muttbin -s "$subjectw" $userid@$domain < $body
	   		else
	   			$muttbin -s "$subjectd" $userid@$domain < $body
	   		fi
		fi
		count=$[$count+1]  #Zähler um eins erhöhen   
	      done
fi	
exit 0

Für Fragen, Hinweise und Verbesserungsvorschläge bin ich dankbar.

Gruss

Stefan
 

P6CNAT

Advanced Hacker
Hallo Stefan,

leider kenne ich die Funktionen und Datenstrukturen von LDAP nicht. Deshalb kann ich keine Verbesserungsvorschläge machen.
Aber das Programm ist gut gegliedert und lässt sich leicht lesen. Einfach vorbildlich. Dafür gibt es ein :thumbs:

Gruß
Georg
 

Tooltime

Advanced Hacker
Ich würde aber Konfigurationen in eine eigene Datei auslagern, damit bei Änderungen nicht direkt im Code hantiert wird, oder z.B. verschiedene Benutzer eigene Konfigs benutzen. Kleines Beispiel:
Code:
#Definition der MySQL Daten
mysqluser=db
mysqlpassword=geheim
mysqldb=spam
mysqlhost=127.0.0.1
Auslagern in dbconfig, Systemweit /etc/dbconfig, jeder user ~\dbconfig. Und im Script einfach folgendes einfügen
Code:
. /etc/dbconfig
. ~\dbconfig
Naja, einwenig aufhüpschen,abfragen ob Dateien vorhanden wegen Fehlermeldungen.
Oder die LDAP-Zugangsdaten gehören entweder nach /etc/openldap/ldap.conf, oder jeder User ~\.ldaprc. Dann kann man sie auch gleich selbst in der Shell benutzen. Aber das ist nörgeln auf hohen Niveau.
 

P6CNAT

Advanced Hacker
Tooltime schrieb:
Ich würde aber Konfigurationen in eine eigene Datei auslagern
:thumbs:
Oh ja,
ist sehr empfehlenswert und kann eine Menge Arbeit ersparen, wenn dasselbe Script in verschiedenen Umgebungen läuft.
Wenn absehbar ist, dass Scripte auf verschiedenen Servern laufen sollen, würde ich in die Konfigurationsdatei sogar noch eine Abhängigkeit vom Server einbauen. Dann könntest du eine Konfigurationsdatei pflegen und auf verschiedene Server verteilen.

Gruß
Georg
 
Oben