I am at my wits end....
All I want to do is set the From using a command line mail in a script.
I have tried mutt, mail, mailx...
Here is on command I tried:
echo "Once again" | mail -s "Maybe this time" -A file.csv stevec#isonas.com -r 'John <john#company.com>' -a From:John\<john#company.com\>
And another:
mutt -e "set from=john#company.com"...
And another:
mutt -e "set from=john#company.com" -e "set realname=John"
My /etc/mailname has the name I want too. I also tried configuring a muttrc file and that doesn't work
And another try:
mailx -r "DoNotReply#company.com" -a "From:DoNotReply#company.com" -s "Subject" -A "/opt/file.csv" "john#anothercompnay.com" <<< Some Text
Any ideas I can try?
I assume that you have configured john#company.com in an extra configuration file (~/.mutt/accounts/john) which you usually source as soon as you start using it in mutt. Simply load that configuration.
echo "mail body" | mutt -e "source ~/.mutt/accounts/john" -e "set content_type=text/plain" -s "subject" -- peter#company.com
An account specific configuration file may look like this (msmtp is used in this case to send mails):
set sendmail = "/usr/bin/msmtp -a Mailbox"
set realname = "John"
set from = "john#company.com"
set mbox_type = Maildir
set folder = "/home/john/.mails"
set spoolfile = "+Mailbox/INBOX"
set record = "+Mailbox/Sent"
set postponed = "+Mailbox/Drafts"
Related
I have a strange problem - possibly I'm just going blind. I have this short script, which replaces the string #qry# in the here-document with a select statement in a file and then pipes it to mysql:
#!/bin/bash
if [[ "$1" == "-h" ]]
then
echo "sqljob [sqlfile] [procnm] [host] [database] [config file]"
echo " sqlfile: text file containing an SQL statement"
echo " procnm: name that will given to the new, stored procedure"
echo " host: hostname of IP address of the database server"
echo " database: the procedure will be created here"
echo " config file: default configuration file with username and password"
exit
fi
infile=$1
procnm=$2
hn=$3
pn=$4
db=$5
mycfg=$6
{
set -o noglob
sed -e "s/#qry#/$(echo $(cat $infile))/g" <<!
drop procedure if exists $procnm;
delete from jobs where jobname="$procnm";
insert into jobs
set
notes="SQL job $procnm",
jobname="$procnm",
parm_tmpl='int';
delimiter //
create procedure $procnm(vqid int)
begin
call joblogmsg(vqid,0,"$procnm","","Executing #qry#");
drop table if exists ${procnm}_res;
create table ${procnm}_res as
#qry#
end//
delimiter ;
!
} | mysql --defaults-file=$mycfg -h $hn -P $pn $db
However, when the select contains *, it expands to whatever is in the directory even though I use noglob. However, it works from the command line:
$ set -o noglob
$ ls *
What am I doing wrong?
Edit
Block Comments in a Shell Script has been suggested as a duplicate, but as you will notice, I need to expand ${procnm} in the here-doc; I just need to avoid the same happening to select *.
I suspect it is because the construct echo (cat). The echo command gets the * from the cat command and the shell in which it runs expands it. In that shell set noglob is not active.
Try leaving the echo away: /$(cat $infile)/, in the end that is the data you need; then there is no extra glob expansion by a shell.
Save an email attachment automatically to map with qmail and reformime
I'm trying to move attachment automatically to another locatie with the dot-qmail file.
My .qmail file
#------------------------------------------------------------
| condredirect pdf-junkmail headermatch 'X-Spam-Status: Yes'
| reformime -X /bin/sh -c "if [ "\${FILENAME#*.}" == "pdf" ]; then cat > /home/users/name/home/$(date +%Y%m%d)_\$FILENAME; fi"
# Forward not set
# Vacation Message not set
./Maildir/
This works for a simple mail with one attachment. My questions:
How can I also move the mailmessage that belongs to this attachment to a mailbox named "done".
Above command doesn't work with multiple attachments in one mailmessage? How can I ajust this line to work for multiple attachments?
This doesn't work if the filename contains multiple dots like "how.areyou.pdf"
Thanks for the help
Here is a featured implementation for your problem.
First save and set permissions to this bash script for your user.
You will need to call it from your .qmail file:
extract-pdf-attachments.sh
#!/usr/bin/env bash
# This script process mail message attachments from stdin MIME message
# Extract all PDF files attachments
# and return the MIME message to stdout for further processing
# Ensure all locale settings are set to C, to prevent
# reformime from failing MIME headers decode with
# [unknown character set: ANSI_X3.4-1968]
# See: https://bugs.gentoo.org/304093
export LC_ALL=C LANG=C LANGUAGE=C
# Setting the destination path for saved attachments
attachements='/home/users/name/home'
trap 'rm -f -- "$mailmessage"' EXIT # Purge temporary mail message
# Create a temporary message file
mailmessage="$(mktemp)"
# Save stdin message to tempfile
cat > "$mailmessage"
# Iterate all MIME sections from the message
while read -r mime_section; do
# Get all section info headers
section_info="$(reformime -s "$mime_section" -i <"$mailmessage")"
# Parse the Content-Type header
content_type="$(grep 'content-type' <<<"$section_info" | cut -d ' ' -f 2-)"
# Parse the Content-Name header (if available)
content_name="$(grep 'content-name' <<<"$section_info" | cut -d ' ' -f 2-)"
# Decode the value of the Content-Name header
content_name="$(reformime -c UTF-8 -h "$content_name")"
if [[ $content_type = "application/pdf" || $content_name =~ .*\.[pP][dD][fF] ]]; then
# Attachment is a PDF
if [ -z "$content_name" ]; then
# The attachment has no name, so create a random name
content_name="$(mktemp --dry-run unnamed_XXXXXXXX.pdf)"
fi
# Prepend the date to the attachment filename
filename="$(date +%Y%m%d)_$content_name"
# Save the attachment to a file
reformime -s "$mime_section" -e <"$mailmessage" >"$attachements/$filename"
fi
done < <(reformime < "$mailmessage") # reformime list all mime sections
cat <"$mailmessage" # Re-inject the message to stdout for further processing
Then in you .qmail:
#------------------------------------------------------------
| condredirect pdf-junkmail headermatch 'X-Spam-Status: Yes'
| bash /path/to/extract-pdf-attachments.sh | condredirect done true
# Forward not set
# Vacation Message not set
./Maildir/
I am attempting to create a bash script that will ssh into remote network devices, run commands based on the model, and then save the output.
At this time I have my expect file that contains the following:
#!/user/bin/expect
set pw xxxxxxx
set timeout 5
spawn ssh [lindex $argv 0]
expect "TACACS Password:"
send "$pw\r"
interact
I have my .sh file that contains variables which allows me to login to separate "host" files based on Model type. It contains:
shopt -s expand_aliases
fpath="path where scripts are located"
opath="MAC_Results.log"
for i in $( cat $fpath/3560hosts )
do
expect script.exp $i >> "$opath"
done
When I run my .sh, everything operates as expected. My issue lies in I do not know how to call my aliases. I have edited the .bashrc and have sourced it. The .bashrc contains the following:
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# User specific aliases and functions
alias loc3560="term length 0; show mac address-table | ex Gi|CPU|Po; exit"
alias locx="term length 0; show mac address-table | ex Gi[1|2]/1|CPU|Vl99|Po1|dynamic|system; exit"
I have also added the aliases within my .sh aliases. but cant seem to get the right syntax. I have tried the following variations but with no success...
for i in $( cat $fpath/3560hosts )
do
expect script.exp $i $loc3560 >> "$opath"
done
and
for i in $( cat $fpath/3560hosts )
do
expect script.exp $i >> "$opath";
$loc3560
done
Would appreciate any suggestions on where to put these to call to them.
Unfortunately I was not able to figure out how to call my functions or aliases within my main .sh script. With that though I found a way to achieve what I wanted via my expect file . Code listed below and it works like a charm. My subdirectory of 21 files has now been reduced to 3!
set loc3560 "show mac address-table | ex Gi|CPU|Po
exit"
set locx "show mac address-table | ex Gi1/1|Gi2/1|CPU|Vl99|Po1|dynamic|system
exit"
set loc4500 "show mac address-table | ex 1/3|1/5|Port-channel|Switch|1/1|1/2|dynamic|system
exit"
set loc888 "show mac-address-table | i FastEthernet
exit"
set loces2 "show mac address-table | i Fa0
exit"
spawn ssh [lindex $argv 0]
expect "TACACS Password:"
send "$pw\r"
expect "#"
send "$ver\r"
expect {
"C3560-IPSERVICESK9-M" {
send "$loc3560\r"
exp_continue
}
"CAT3K_CAA-UNIVERSALK9" {
send "$locx\r"
exp_continue
}
"C3750E-UNIVERSALK9-M" {
send "$locx\r"
exp_continue
}
"CISCO888-SEC-K9" {
send "$loc888\r"
exp_continue
}
"bootflash:/cat4500e" {
send "$loc4500\r"
exp_continue
}
"SM-ES2-24" {
send "$loces2\r"
exp_continue
}
}
interact
expect "#"
send "exit\r"
end
From here I am then able to call my script and output it to a log file in my directory via:
./script.sh >> Results.log
What I'm trying to do is have salt set an internal host ip based on the current value of $i from the for loop. I've tried the following but was unsuccessful at modifying a network script that contains this line: 192.168.200.100 which resides in all 39 nodes.
for ((i=2; i<=30; i++)); do sudo salt -L "host$i.dev.mysite.com" cmd.run "sed -i "s/192.168.200.100/192.168.200.$i/" /etc/sysconfig/network-scripts/ifcfg-bond1; done"
Results I am looking is to have each hostX.dev.mysite.com bond1 files modified from 192.168.200.100 to 192.168.200.2
host2.dev.mysite.com /etc/sysconfig/network-scripts/ifcfg-bond1 = 192.168.200.2
host3.dev.mysite.com /etc/sysconfig/network-scripts/ifcfg-bond1 = 192.168.200.3
host4.dev.mysite.com /etc/sysconfig/network-scripts/ifcfg-bond1 = 192.168.200.4
host5.dev.mysite.com /etc/sysconfig/network-scripts/ifcfg-bond1 = 192.168.200.5
host6.dev.mysite.com /etc/sysconfig/network-scripts/ifcfg-bond1 = 192.168.200.6
host7.dev.mysite.com /etc/sysconfig/network-scripts/ifcfg-bond1 = 192.168.200.7
etc...
Something like this?
for ((i=2;i<=30;i++)); do
sudo salt -L "host${i}.dev.mysite.com" cmd.run "sed -r -i \"s#([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)[0-9]{1,3}\$#\1$i#\" /etc/sysconfig/network-scripts/ifcfg-bond1"
done
i tried to setup squid3 with multiple auth_param. Basically, the first choice should be basic_ldap_auth and if this doesnt return OK it should try basic_ncsa_auth with the same values. As far as i know squid doesnt support it however there is the possibility to use "external" ACL
auth_param basic program /usr/lib/squid3/basic_fake_auth
external_acl_type MultAuth %SRC %LOGIN %{Proxy-Authorization} /etc/squid3/multAuth.pl
acl extAuth external MultAuth
my "multAuth.pl"
use URI::Escape;
use MIME::Base64;
$|=1;
while (<>) {
($ip,$user,$auth) = split();
# Retrieve the password from the authentication header
$auth = uri_unescape($auth);
($type,$authData) = split(/ /, $auth);
$authString = decode_base64($authData);
($username,$password) = split(/:/, $authString);
# do the authentication and pass results back to Squid.
$ldap = `/bin/bash auth/ldap.sh`;
if ($ldap == "OK") {
print "OK";
}
$ncsa = `/bin/bash auth/ncsa.sh`;
if ($ncsa == "OK") {
print "OK";
} else {
print "ERR";
}
}
now i am trying to run with ncsa.sh and ldap.sh the "normal" shell command for these auth methods.
./basic_ldap_auth -R -b "dc=domain,dc=de" -D "CN=Administrator,CN=Users,DC=domain,DC=de" -w "password" -f sAMAccountName=%s -h domain.de
user password
and
./basic_ncsa_auth /etc/squid3/users
user password
Therefor i ran:
auth/ncsa.sh
#!/usr/bin/expect
eval spawn [lrange $argv 0 end]
expect ""
send [lindex $argv 1]
send '\r'
expect {
"OK" {
echo OK
exp_continue
}
"ERR" {
echo ERR
exp_continue
}
interact
with
./ncsa.sh "/usr/lib/squid3/basic_ncsa_auth /etc/squid3/users" "user password"
and i generate the following error:
couldn't execute "/usr/lib/squid3/basic_ncsa_auth /etc/squid3/users": no such file or directory
while executing
"spawn {/usr/lib/squid3/basic_ncsa_auth /etc/squid3/users} {user password}"
("eval" body line 1)
invoked from within
"eval spawn [lrange $argv 0 end]"
(file "./ncsa.sh" line 2)
Besides this error, i am not sure how to pass the variables (username & password) forward and i am also not sure how to answer the shell questions like for example the user & pw input for basic_ldap_auth .
Is there a nice way how to solve that? or any other good plan ?
thanks!
FWIW, the following script helped me transition from passwd based to LDAP based authentication.
Contrary to your requirements, my script acts the other way around: It first checks passwd, then LDAP.
#!/usr/bin/env bash
# multiple Squid basic auth checks
# originally posted here: https://github.com/HackerHarry/mSquidAuth
#
# credits
# https://stackoverflow.com/questions/24147067/verify-user-and-password-against-a-file-created-by-htpasswd/40131483
# https://stackoverflow.com/questions/38710483/how-to-stop-ldapsearch1-from-base64-encoding-userpassword-and-other-attributes
#
# requires ldap-utils, openssl and perl
# tested with Squid 4 using a "auth_param basic program /usr/lib/squid/mSquidAuth.sh" line
# authenticate first against squid password file
# if this fails, try LDAP (Active Directory) and also check group membership
# variables
# sLOGFILE=/var/log/squid/mSquidAuth.log
sPWDFILE="/etc/squid/passwd"
sLDAPHOST="ldaps://dc.domain.local:636"
sBASE="DC=domain,DC=local"
sLDS_OPTIONS="-o ldif-wrap=no -o nettimeout=7 -LLL -P3 -x "
sBINDDN="CN=LDAP-read-user,OU=Users,DC=domain,DC=local"
sBINDPW="read-user-password"
sGROUP="Proxy-Users"
# functions
function _grantAccess {
# echo "access granted - $sUSER" >>$sLOGFILE
echo "OK"
}
function _denyAccess {
# echo "access denied - $sUSER" >>$sLOGFILE
echo "ERR"
}
function _setUserAndPass {
local sAuth="$1"
local sOldIFS=$IFS
IFS=' '
set -- $sAuth
IFS=$sOldIFS
# set it globally
sUSER="$1"
sPASS="$2"
}
# loop
while (true); do
read -r sAUTH
sUSER=""
sPASS=""
sSALT=""
sUSERENTRY=""
sHASHEDPW=""
sUSERDN=""
iDNCOUNT=0
if [ -z "$sAUTH" ]; then
# echo "exiting" >>$sLOGFILE
exit 0
fi
_setUserAndPass "$sAUTH"
sUSERENTRY=$(grep -E "^${sUSER}:" "$sPWDFILE")
if [ -n "$sUSERENTRY" ]; then
sSALT=$(echo "$sUSERENTRY" | cut -d$ -f3)
if [ -n "$sSALT" ]; then
sHASHEDPW=$(openssl passwd -apr1 -salt "$sSALT" "$sPASS")
if [ "$sUSERENTRY" = "${sUSER}:${sHASHEDPW}" ]; then
_grantAccess
continue
fi
fi
fi
# LDAP is next
iDNCOUNT=$(ldapsearch $sLDS_OPTIONS -H "$sLDAPHOST" -D "$sBINDDN" -w "$sBINDPW" -b "$sBASE" "(|(sAMAccountName=${sUSER})(userPrincipalName=${sUSER}))" dn 2>/dev/null | grep -cE 'dn::? ')
if [ $iDNCOUNT != 1 ]; then
# user needs a unique account
_denyAccess
continue
fi
# get user's DN
# we need the extra grep in case we get lines back starting with "# refldap" :/
sUSERDN=$(ldapsearch $sLDS_OPTIONS -H "$sLDAPHOST" -D "$sBINDDN" -w "$sBINDPW" -b "$sBASE" "(|(sAMAccountName=${sUSER})(userPrincipalName=${sUSER}))" dn 2>/dev/null | perl -MMIME::Base64 -n -00 -e 's/\n +//g;s/(?<=:: )(\S+)/decode_base64($1)/eg;print' | grep -E 'dn::? ' | sed -r 's/dn::? //')
# try and bind using that DN to check password validity
# also test if that user is member of a particular group
# backslash in DN needs special treatment
if ldapsearch $sLDS_OPTIONS -H "$sLDAPHOST" -D "$sUSERDN" -w "$sPASS" -b "$sBASE" "name=${sGROUP}" member 2>/dev/null | perl -MMIME::Base64 -n -00 -e 's/\n +//g;s/(?<=:: )(\S+)/decode_base64($1)/eg;print' | grep -q "${sUSERDN/\\/\\\\}"; then
_grantAccess
continue
fi
_denyAccess
done