Changing Passwords with a script.

We are real strict when it comes to passwords. Every 60 days the admins have to change passwords on all of the accounts. And there is pretty strict enforcement of the type of passwords chosen. This is a tedious and monotonous job. Ww don't use NIS or LDAP, so this has to be done on each machine. So we log into each machine and change each account. Not all accounts are on all machines. What I want to do it make a master shadow password file, find the user in it, take the line out, and replace the corresponding line taken from my generated master file.

Here is a line that does what I want:
sed 's/ramosg:MWmv2eaET4N3E:15266:7:60::::/ramosg:h8YU4ImoLFM.g:15248:7:60::::/g' shadow > shadow.changed1

The above should be one line. Here is what I tried in a script:

test1=$(grep $lognam shadow);
test2=$(grep $lognam shadow.changed);

sed 's/$test1/$test2/g' shadow > shadow.modified;

$lognam is the first field of shadow. Is that the right syntax for the sed command? It works when I issue the sed at the command line, but not in the script. Thanks.

If you truly have single qoutes round your sed prgramme, then your problem is that $test1 and $test2 are not getting expanded. Unsure how you got it to work from the command line as it should have had the same issue when issued manually. Since you have nothing in the quotes that requires single quotes, you should be able to replace them with double quotes:

sed "s/$test1/$test2/g" shadow > shadow.modified;

If that doesn't work, try echoing the command to verify that your variables are as you expect:

echo sed "s/$test1/$test2/g" shadow 
1 Like

Thank you. That fixed it. I'm getting another error regarding 'garbled' output, but that one can wait. Thanks again.

OK, the double quotes fixed the major problem, but sed pukes on some of the passwd lines. If the shadow passwd entry happens to include a certain character, it doesn't like it. Example:

Works:
sed "s/olthoft:whzxrwpleb5Xs:15251:7:63::::/olthoft:eAoSnqwC2kURE:15251:7:60::::/g" shadow

Doesn't work:

[root@appoc9 ~]# sed "s/winslows:bwAO.qzcx.DsY:15251:7:56::::/winslows:CU/9jp.EGy.oM:15252::60::::/g" shadow
sed: command garbled: s/winslows:bwAO.qzcx.DsY:15251:7:56::::/winslows:CU/9jp.EGy.oM:15252::60::::/g
[root@appoc9 ~]#

[root@appoc9 ~]# sed "s/smithk:5Q8DTqy4S.F/o:15231:7:56::::/smithk:*LKXF06htZfx4tfc:15251::60::::/g" shadow
sed: command garbled: s/smithk:5Q8DTqy4S.F/o:15231:7:56::::/smithk:*LK
XF06htZfx4tfc:15251::60::::/g
[root@appoc9 ~]#

The only thing I see common in both is a '/', but I won't know what is in the string.

You've hit the nail on the head. The slant in the original pattern is causing your grief. The format of the sed substitute command is:

s<delim>pattern<delim>replacement<delim>

The delim character can be anything, but it cannot occur in the pattern. By having a pattern with a slant, you're "marking" the end of the pattern early, and then you're tossing in extra information that sed is complaining about.

Assuming that you're using Kshell or bash, then something like this would work:

test1=$(grep $lognam shadow);
test2=$(grep $lognam shadow.changed);
sed "s/${test1//\//\\/}/${test2//\//\\/}/" > shadow.modified;

The shell magic converts all forward slants in test1 and test2 into "\/" combinations which escape the slant when sed reads the string. It should now be fine. And if there aren't any slants, then the string is not affected.

---------- Post updated at 20:29 ---------- Previous update was at 20:03 ----------

It just occurred to me that you might need to escape other characters on the pattern side. Specifically the dot (.) and splat (*) need to be escaped. These additional lines should do the trick.


test1=$(grep $lognam shadow);
test2=$(grep $lognam shadow.changed);
test1="${test1//./\\.}"
test1="${test1//\*/\\*}"
sed "s/${test1//\//\\/}/${test2//\//\\/}/" > shadow.modified;
1 Like

I won't be able to try it until tomorrow. Thanks again.