How can you run an ldap search using variables and a not filter? - linux

ldapsearch -h 1.0.24.24 -p 389 -x -t -LLL -S cn -D
cn=user,ou=resources,o=otherresource,c=xx -w server101 -b ou=Non-
Staff,ou=people,o=test,c=us '(&(objectClass=inetOrgPerson)
(createTimestamp<=$month_8)(!(nEApps=*))(nEDHHSNFAccNbr=\00)
(nECreatedBy=cioSelfRegistered)(loginTime<=$month_3))' dn
I can only use my variables if the filters are surrounded by double quotes
and I can only use the not filter if they are surround by single quotes is there a way to make this work in the same query?

! is a special character (it does a command history substitution) in interactive mode, but not in a script. Is this supposed to be something you'll type in interactively, or something embedded in a script? If the latter, you can just use double-quotes, and the ! won't be a problem.
If you're using this interactively, there are a coupe of options. One is to mix quoting modes in a single argument , as in "double-quoted-section"'single-quoted-section'"another-quoted-section". This looks weird, but works fine. Something like this:
ldapsearch -h 1.0.24.24 -p 389 -x -t -LLL -S cn \
-D cn=user,ou=resources,o=otherresource,c=xx -w server101 \
-b ou=Non-Staff,ou=people,o=test,c=us \
"(&(objectClass=inetOrgPerson)(createTimestamp<=$month_8)("'!'"(nEApps=*))(nEDHHSNFAccNbr=\00)(nECreatedBy=cioSelfRegistered)(loginTime<=$month_3))" dn
^^^^^
Alternately, you could define a variable as ! (using single-quotes), then use that variable inside double-quotes:
exclamation='!'
ldapsearch -h 1.0.24.24 -p 389 -x -t -LLL -S cn \
-D cn=user,ou=resources,o=otherresource,c=xx -w server101 \
-b ou=Non-Staff,ou=people,o=test,c=us \
"(&(objectClass=inetOrgPerson)(createTimestamp<=$month_8)($exclamation(nEApps=*))(nEDHHSNFAccNbr=\00)(nECreatedBy=cioSelfRegistered)(loginTime<=$month_3))" dn
^^^^^^^^^^^^

The ! filter only 'needs' single quotes because of the *, which the shell will attempt to expand itself as a wildcard.
Solution: escape it.

Related

SSH remote execution - How to declare a variable inside EOF block (Bash script)

I have the following code in a bash script:
remote_home=/home/folder
dump_file=$remote_home/my_database_`date +%F_%X`.sql
aws_pem=$HOME/my_key.pem
aws_host=user#host
local_folder=$HOME/db_bk
pwd_stg=xxxxxxxxxxxxxxxx
pwd_prod=xxxxxxxxxxxxxxx
ssh -i $aws_pem $aws_host << EOF
mysqldump --column-statistics=0 --result-file=$dump_file -u user -p$pwd_prod -h $db_to_bk my_database
mysql -u user -p$pwd_prod -h $db_to_bk -N -e 'SHOW TABLES from my_database' > $remote_home/test.txt
sh -c 'cat test.txt | while read i ; do mysql -u user -p$pwd_prod -h $db_to_bk -D my_database --tee=$remote_home/rows.txt -e "SELECT COUNT(*) as $i FROM $i" ; done'
EOF
My loop while is not working because "i" variable is becoming empty. May anyone give me a hand, please? I would like to understand how to handle data in such cases.
The local shell is "expanding" all of the $variable references in the here-document, but AIUI you want $i to be passed through to the remote shell and expanded there. To do this, escape (with a backslash) the $ characters you don't want the local shell to expand. I think it'll look like this:
ssh -i $aws_pem $aws_host << EOF
mysqldump --column-statistics=0 --result-file=$dump_file -u user -p$pwd_prod -h $db_to_bk my_database
mysql -u user -p$pwd_prod -h $db_to_bk -N -e 'SHOW TABLES from my_database' > $remote_home/test.txt
sh -c 'cat test.txt | while read i ; do mysql -u user -p$pwd_prod -h $db_to_bk -D my_database --tee=$remote_home/rows.txt -e "SELECT COUNT(*) as \$i FROM \$i" ; done'
EOF
You can test this by replacing the ssh -i $aws_pem $aws_host command with just cat, so it prints the here-document as it'll be passed to the ssh command (i.e. after the local shell has done its parsing and expansions, but before the remote shell has done its). You should see most of the variables replaced by their values (because those have to happen locally, where those variables are defined) but $i passed literally so the remote shell can expand it.
BTW, you should double-quote almost all of your variable references (e.g. ssh -i "$aws_pem" "$aws_host") to prevent weird parsing problems; shellcheck.net will point this out for the local commands (along with some other potential problems), but you should fix it for the remote commands as well (except $i, since that's already double-quoted as part of the SELECT command).

Using printf %q to make a quoted string usable as shell script input

Within a bash script, I am trying to append a command string that is single and double quoted to a file (.profile).
I would like to use echo and then >> the command to .profile. Of course, I am open to any solution that works.
The command I would like to use is echo "curl -X POST -H "Content-Type: application/json" -d '{"value1":"PHONENUMBER","value2":"MESSAGE"}' https://maker.ifttt.com/trigger/TRIGGER/with/key/KEY &> /dev/null" >> .profile but clearly this doesn't work within my bash script.
I am not clear on how printf %q works and don't understand how to apply it to my problem.
I have tried this
`CMDSTRING='curl -X POST -H "Content-Type: application/json" -d '`
`CMDSTRING=${CMDSTRING}"'"`
`CMDSTRING=${CMDSTRING}'{"value1":"+PHONENUMBER","value2":"MESSAGE"}'`
`CMDSTRING=${CMDSTRING}"'"`
`CMDSTRING=${CMDSTRING}' https://maker.ifttt.com/trigger/TRIGGER/with/key/KEY &> /dev/null'`
`echo $CMDSTRING`
Using printf '%q' to generate .profile content looks something like the following:
{
printf '%q ' \
curl -X POST -H "Content-Type: application/json" \
-d '{"value1":"PHONENUMBER","value2":"MESSAGE"}' \
https://maker.ifttt.com/trigger/TRIGGER/with/key/KEY
printf '%s\n' "&>/dev/null"
} >> .profile
Note that you cannot use the %q format string if you want &>/dev/null to be parsed as syntax, since by its very nature it formats everything it's passed to be parsed as data.
Thus, we use printf '%q ' "command name" "first argument" ... for the actual command itself, and format the redirection out-of-band.
That said, note that there's value to the above only if you're substituting variables from an untrusted source (rather than hardcoding them as in the example), and are worried about invalid values being abused for command injection. If you're truly just appending a constant string to the end of a file, a quoted heredoc will let you build more natural-looking shell quoting manually (indeed, as you've already done!), and pass it through verbatim:
cat >>.profile <<'EOF'
curl -X POST -H "Content-Type: application/json" \
-d '{"value1":"PHONENUMBER","value2":"MESSAGE"}' \
https://maker.ifttt.com/trigger/TRIGGER/with/key/KEY &> /dev/null
EOF
Here, everything between the <<'EOF' and the EOF are passed through exactly-as-given, including quotes and parameter expansions the shell might otherwise try to interpret.

Using Environment Variables in cURL Command - Unix

My question is very simple. I want to use environment variables in a cURL command sth similar to this:
curl -k -X POST -H 'Content-Type: application/json' -d '{"username":"$USERNAME","password":"$PASSWORD"}'
When I run the command $USERNAME is passed to the command as a "$USERNAME" string not the value of the variable. Is there a way to escape this situation?
Thanks.
Single quotes inhibit variable substitution, so use double quotes. The inner double quotes must then be escaped.
... -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}"
Since this answer was written in 2015, it has become clear that this technique is insufficient to properly create JSON:
$ USERNAME=person1
$ PASSWORD="some \"gnarly 'password"
$ echo "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}"
{"username":"person1","password":"some "gnarly 'password"}
$ echo "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}" | jq .
parse error: Invalid numeric literal at line 1, column 47
The quoting problem are clear. The (shell) solutions are not
Current best practice: use a JSON-specific tool to create JSON:
jq
$ jq -n -c --arg username "$USERNAME" --arg password "$PASSWORD" '$ARGS.named'
{"username":"person1","password":"some \"gnarly 'password"}
jo
$ jo "username=$USERNAME" "password=$PASSWORD"
{"username":"person1","password":"some \"gnarly 'password"}
And with curl:
json=$( jq -n -c --arg username "$USERNAME" --arg password "$PASSWORD" '$ARGS.named' )
# or
json=$( jo "username=$USERNAME" "password=$PASSWORD" )
# then
curl ... -d "$json"
For less quoting, read from standard input instead.
curl -k -X POST -H 'Content-Type: application/json' -d #- <<EOF
{ "username": "$USERNAME", "password": "$PASSWORD"}
EOF
-d #foo reads from a file named foo. If you use - as the file name, it reads from standard input. Here, standard input is supplied from a here document, which is treated as a double-quoted string without actually enclosing it in double quotes.
curl -k -X POST -H 'Content-Type: application/json' -d '{"username":"'$USERNAME'","password":"'$PASSWORD'"}'
Here the variable are placed outside of "'" quotes and will be expanded by shell (just like in echo $USERNAME). For example assuming that USRNAME=xxx and PASSWORD=yyy the argv[7] string passed to curl is {"username":"xxx","password":"yyy"}
And yes, this will not work when $USERNAME or $PASSWORD contain space characters.
Our: curl -k -X POST -H 'Content-Type: application/json' -d '{"username":"'"$USERNAME"'","password":"'"$PASSWORD"'"}'
You can wrap the environment variables with "'" and you should keep the single quote for the external json object.
e.g
-d '{"username":"'"$USERNAME"'","password":"'"$PASSWORD"'"}'

Escape special characters in a bash script

I have a command that I want to put in a script but I'm having issues. The command is very picky and it looks like this:
command_to_run -H 'ip_address' -u 'user' -p 'passwd' --register naming_data "/location/of/backup/folder/" "[destination-location]"
I want to create an interactive bash script that asks the user for the ip_address, user, password, location of backup folder and a destination location. The problem I'm having is that I'm storing the user's input on variables (IP_ADD, USERNAME, etc) but when I pass it to the command like
$COMMAND -H '$IPADD' -u '$USERNAME' .....
but again my issues are in the single quotes, the "/" the "[]" ad passing the variables. Can anyone give me a hint and what I need to fix in order to have it working??
Like Etan said, use double quotes:
command_to_run -H "$ip_address" -u "$user" -p "$passwd" ....
Use double quotes:
$COMMAND -H "$IPADD" -u "$USERNAME" ...
If you use single quotes in the shell, variables will not getting expanded meaning the literal $USERNAME will being used for the username.

.bash_profile ldapsearch function not outputting to terminal [duplicate]

This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
Closed 8 years ago.
I have a bash function in my .bash_profile that is not returning results to the terminal.
When I run the command as normal via the CLI results are returned.
ldap_check_cleaup ()
{
ldapsearch -LLL -h itdsvbms.SomeDomain.org -p 389 \
-D "uid=SomeUser,o=SomeDomain.org" -w SomePassWord -b "ou=People,o=SomeDomain.org" \
-s sub '(&(ReservedRMAliases=$1)(!(RMid=*))(RMAliasUpdateDate=12/01/2012 19:02:00)(RMAliasStatus=IN)(status=IN))' | \
tee /dev/tty
}
running ldap_check_clenaup TestRecord returns no output when executed from the bash prompt. TestRecord does exist and when the following command is run from the CLI, the correct record is returned:
ldapsearch -LLL -h itdsvbms.SomeDomain.org -p 389 -D "uid=SomeUser,o=SomeDomain.org" \
-w SomePassWord -b "ou=People,o=SomeDomain.org" \
-s sub '(&(ReservedRMAliases=TestRecord)(!(RMid=***))(RMAliasUpdateDate=12/01/2012 19:02:00)(RMAliasStatus=IN)(status=IN))' | \
tee /dev/tty`
The lack of out put only happens when I try to use this ldapsearch and the arguments as a bash function.
I think this may be related to using ' instead of " for the attribute (!(RMid=*)) but I am unsure, please help.
You need to use double-quotes around the argument that contains $1. Variable interpolation is not performed inside single-quoted strings.

Resources