Trying to search /etc/pam.d/common-password file for entry that starts with password required pam_unix.so and check to see if sha512 is in the fourth column. If its there, do nothing. If its not there add it. It could be anywhere in the fourth column, but it seems easiest to add to the end if not there.
password required pam_unix.so use_authtok nullok shadow try_first_pass
So ending line should look like:
password required pam_unix.so use_authtok nullok shadow try_first_pass sha512
Using the below if statement and replacing the comment with my command:
if [[ "$(grep 'password'$'\t''required'$'\t''pam_unix.so' common-password | cut -f4)" != *"sha512"* ]]; then
>&2 echo 'Remediation needs to be done'
fi
Tried below awk but end up with an empty common-password file
awk '/^'password'$'\t''required'$'\t''pam_unix.so'/{print $0," sha512"}' /etc/pam.d/common-password > /etc/pam.d/common-password.fixed && mv /etc/pam.d/common-password.fixed /etc/pam.d/common-password
Tried below grep and sed, but get error "sed: no input files"
grep -F 'password'$'\t''required'$'\t''pam_unix.so' /etc/pam.d/common-password | sed --follow-symlinks -ie 's/$/& sha512/g'
Need to be able to find this line and modify it and only this line. And only if it has not already been modified. I only want to modify this one line if it exists and leave the rest of the file intact.
Any help would be greatly appreciated.
CodePudding user response:
If you can use gnu-awk
you can make use of -i inplace
and set the field separator and the output field separator to a tab to compare the field values.
Then you can check if field 4 does not contain sha512 using $4 !~ /sha512/
For example
awk -i inplace '
BEGIN{FS=OFS="\t"}
$1=="password" && $2=="required" && $3=="pam_unix.so" && $4 !~ /sha512/{$0 = $0 OFS "sha512"}1
' file
CodePudding user response:
For one line, use vi
and save yourself the trouble of fixing the mess a typo will make.
If you really need an automated edit, simplify to one executable and consolidate your logic.
$: sed -i '/password\trequired\tpam_unix.so\t/{ /\tsha512/{n}; s/$/\tsha512/; }' file
this:
- searches for records that have the initial required string of
password\trequired\tpam_unix.so\t
- opens a block that groups statements to be executed collectively in
{...}
- searches for records to exclude with
/\tsha512/{n}
; then
goes on to thenext
record and skips the rest of the steps in the outer block. This will still output the record, so it won't be deleted from the file on the in-place edit (used
for that). - if the previous check did not match, the
n
won't be executed, so the next commands
ubstitutes in the string you want at the end of the record. - the closing brace of the outer block ends the set of commands on the only outer scan, so
sed
proceeds to the next record.
If the end-of-record tab logic is not an issue, and you are sure there are no trailing tabs otherwise, or if you are confident that they indicate an empty final field, just use 's/$/\tsha512/'
, but if it's possible there might be trash tabs at the end of the record, you might want to clean those - maybe 's/\t*$/\tsha512/'
, or even 's/\t{0,1}$/\tsha512/'
. Check your file and your logic against the possible consequences of carelessly editing...
Good luck.