Okay so I JUST started bash scripting two weeks ago, and I ran into an issue last week that I just cannot fix. I'll describe my problem as best I can and I've included my script. I welcome any criticisms on what I am doing wrong with this code; Actually, I implore you to please provide as much criticism on my technique as you can so that I can learn from it.
Objectives
I installed a new Zimbra Collaboration Suite for my company, and am in the process of migrating user accounts. I am trying to create a bash script to do the following:
- Pull all user accounts from active directory via LDAP.
- Format the LDAP query results to be used in a
zmprov ca
command.
- Enumerate the lines of the formatted results.
- Iterate through each line and run it as a
zmprov
command.
Assumptions for the purposes of this example
- Name of the bash file = zdap
- My Active Directory domain = MYLOCALDOMAIN
- My username for LDAP = admin
- My password for LDAP = P@ssw0rd
- My LDAP IP address = 1.2.3.4
Script
Here is my script:
#!/bin/bash
#Use this script to pull user information from Company Active Directory
argerror="Usage: company-ldap domain username"
if [ "$1" == "local" ]; then
domain=MYLOCALDOMAIN
ou=MAIN
else
echo "$argerror"
exit
fi
if [ -z $2 ]; then
echo "$argerror"
exit
else
user=$2
fi
password=P@ssw0rd
ldapsearch -h 1.2.3.4 -p 389 -D "cn=$user,ou=$ou,dc=$domain,dc=COM" \
-w "$password" -b "ou=$ou,dc=$domain,dc=COM" \
"(&(name=*)(mail=*)(givenName=*)(sn=*))" \
'name' 'mail' 'givenName' 'sn' -LLL -S 'name' |
grep -B 1 'name\|mail\|sn\|givenName' |
grep -v '^dn:' | tr '\n' ' ' |
sed -e 's/ -- /\n/g' |
awk '{s=""; for (i=1;i<NF;i++) s = s $i " ";print $NF " " s}' |
sed -e 's/sn: /sn '\''/g' |
sed -e 's/ givenName: /'\'' gn '\''/g' |
sed -e 's/ mail: / /g' |
sed -e 's/ name: /'\'' displayName '\''/g' |
awk '{print "ca " $0"'\''"}' |
sed -e 's/ '\''$/'\''/g' |
awk '{($2 = $2 " tempzimbrapw1234"); print $0}' |
while read line ; do zmprov $line ; done
I call the command with this:
./zdap local admin
Requested edit...
The zmprov
command for a given user (Joe Smith) looks like this:
zmprov ca joe.smith@mylocaldomain.com tempzimbrapw1234 sn 'Smith' gn 'Joe' displayName 'Joe Smith'
Results and my Problem
- The ldap query runs perfectly (e.g., if I run that command separately, it will return the proper ldap results...so the issue isn't LDAP credentials/connection/query related).
- If I echo the command, it also looks just fine (e.g., if I type the
command out to match the echoed version and it will actually add the
account like I want).
However, when I run the zdap bash script I wrote, I expect to get a create account confirmation from Zimbra, but instead get this message:
zimbra@CPU-00154:~$ ./zdap local admin
usage: createAccount(ca) {name@domain} {password} [attr1 value1 [attr2 value2..
For general help, type : zmprov --help
Unfortunately I have tried too many solutions to list them all here. I've spent a week reading manuals, forums, etc. and have tried tons of tweaks, adjustments, new commands, etc. but to no avail.
Once again, I would greatly appreciate any criticisms regarding my script or overall method for accomplishing this. Please try to include examples with your suggestions so that I can see what I'm doing wrong here. Thank you in advance.
EDIT:
I thought I should include the format of the LDAP query result so you can see what my command is working with:
dn: CN=admin,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: admin
mail: admin@mylocaldomain.com
--
dn: CN=Jane Doe,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: Jane Doe
mail: jane.doe@mylocaldomain.com
--
dn: CN=Joe Smith,OU=MAIN,DC=MYLOCALDOMAIN,DC=COM
name: Joe Smith
mail: joe.smith@mylocaldomain.com
UPDATE
I managed to work out the issue using the printf
command (special thanks to rici for that suggestion). The output from printf was this...
<|zmprov|> <|ca|> <|joe.smith@mylocaldomain.com|> <|tempzimbrapw1234|> <|#|> <|sn|> <|'Smith'|> <|gn|> <|'Joe'|> <|displayName|> <|'Joe|> <|Smith'|>
As you can see, the value of the last argument (displayName) was being misinterpreted.