Reputation: 14393
I'm writing a simple BASH script to generate an LDIF file, which I can then use to add a user to my OpenLDAP server.
This is the script:
#!/bin/bash
#add LDAP user, v1.0, by mbobak, 11/17/2020
if [ $# != 6 ];
then
echo "`basename $0`: error: invalid number of arguments:"
echo "`basename $0` <userid> <firstname> <lastname> <gidnum> <uidnum> <empno>"
exit 1
fi
userid=$1
firstname=$2
lastname=$3
gidnum=$4
uidnum=$5
empno=$6
temppasswd=`slappasswd -s pw4${userid}`
echo ${userid} ${firstname} ${lastname} ${gidnum} ${uidnum} ${empno} ${temppasswd}
sed -e "s/#userid#/${userid}/g" -e "s/#gidnum#/${gidnum}/g" -e "s/#firstname#/${firstname}/g" -e "s/#lastname#/${lastname}/g" -e "s/#uidnum#/${uidnum}/g" -e "s/#empno#/${empno}/g" -e "s/#temppasswd#/${temppasswd}/g" user_tmpl.ldif
I use it with this template:
dn: uid=#userid#,ou=people,dc=nitssolutions,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: #userid#
gidNumber: #gidnum#
givenName: #firstname#
sn: #lastname#
displayName: #firstname# #lastname#
homeDirectory: /home/#userid#
mail: #userid#@nitssolutions.com
loginShell: /bin/bash
cn: #firstname# #lastname#
uidNumber: #uidnum#
employeeType: INT-FT
employeeNumber: #empno#
dn: uid=#userid#,ou=people,dc=nitssolutions,dc=com
changetype: modify
add: userPassword
userPassword: #temppasswd#
This seems to work just fine, except when the output of slappasswd
contains a /
character.
When that happens, I get the following error:
./add_ldap_user.sh jdoe John Doe 123456 123456 NS1234
jdoe John Doe 123456 123456 NS1234 {SSHA}kTwHVDBiK4ub3laqwaqZpAUwILrW/Vw9
sed: -e expression #7, char 51: unknown option to `s'
Again, this only happens when the output of slappasswd
contains a /
.
I'm sure I'm missing something simple here, but it's not clear to me what the correct answer is. I can't simply escape the entire expression, or my variable reverts to a static string '${temppasswd}', which doesn't help. I need the value of ${temppasswd} even if it contains characters that need to be escaped.
Help?
Upvotes: 2
Views: 104
Reputation: 19555
With envsubst
and the following redesigned template:
dn: uid=${userid},ou=people,dc=nitssolutions,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: ${userid}
gidNumber: ${gidnum}
givenName: ${firstname}
sn: ${lastname}
displayName: ${firstname} ${lastname}
homeDirectory: /home/${userid}
mail: ${userid}@nitssolutions.com
loginShell: /bin/bash
cn: ${firstname} ${lastname}
uidNumber: ${uidnum}
employeeType: INT-FT
employeeNumber: ${empno}
dn: uid=${userid},ou=people,dc=nitssolutions,dc=com
changetype: modify
add: userPassword
userPassword: ${temppasswd}
Processed with: program1
#!/usr/bin/env bash
Iam="${0##*/}" # Basename of myself
if [ $# -ne 6 ];
cat <<ERR >&2
$Iam: error: invalid number of arguments:
Usage:
$Iam <userid> <firstname> <lastname> <gidnum> <uidnum> <empno>
ERR
exit 1
fi
userid="$1" firstname="$2" lastname="$3" \
gidnum="$4" uidnum="$5" empno="$6" \
temppasswd=$(slappasswd -s "pw4$userid") \
envsubst <user_tmpl.ldif
Test run with dummy values:
./program1 foo bar baz 666 42 99
foo bar baz 666 42 99 ciWatEpIcs
Output
dn: uid=foo,ou=people,dc=nitssolutions,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: foo
gidNumber: 666
givenName: bar
sn: baz
displayName: bar baz
homeDirectory: /home/foo
mail: [email protected]
loginShell: /bin/bash
cn: bar baz
uidNumber: 42
employeeType: INT-FT
employeeNumber: 99
dn: uid=foo,ou=people,dc=nitssolutions,dc=com
changetype: modify
add: userPassword
userPassword: ciWatEpIcs
And now with a simple here document, it does not even need envsubst
program2
:
#!/usr/bin/env bash
Iam="${0##*/}" # Basename of myself
if [ $# -ne 6 ];
then
cat <<ERR >&2
$Iam: error: invalid number of arguments:
Usage:
$Iam <userid> <firstname> <lastname> <gidnum> <uidnum> <empno>
ERR
exit 1
fi
userid=$1
firstname=$2
lastname=$3
gidnum=$4
uidnum=$5
empno=$6
temppasswd=$(slappasswd -s "pw4$userid")
cat <<LDIFTEMPLATE
dn: uid=${userid},ou=people,dc=nitssolutions,dc=com
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: ${userid}
gidNumber: ${gidnum}
givenName: ${firstname}
sn: ${lastname}
displayName: ${firstname} ${lastname}
homeDirectory: /home/${userid}
mail: ${userid}@nitssolutions.com
loginShell: /bin/bash
cn: ${firstname} ${lastname}
uidNumber: ${uidnum}
employeeType: INT-FT
employeeNumber: ${empno}
dn: uid=${userid},ou=people,dc=nitssolutions,dc=com
changetype: modify
add: userPassword
userPassword: ${temppasswd}
LDIFTEMPLATE
Upvotes: 1
Reputation: 141050
this only happens when the output of slappasswd contains a /.
Choose a different s
command separating character. Like ~
or any other character.
sed -e "s~#userid#~${userid}~g"
In edge cases with GNU sed you can use any byte, for example you may use C escaping $'\x01'
to write 0x01 byte:
sed -e $'s\x01#userid#\x01'"${userid}"$'\x01g'
But I recommend not to reinvent the wheel and use existing templating tools. Change to format of the template from #userid#
to just ${userid}
and you may use use envsubst
.
Upvotes: 3