Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Shell Script to set a user password from variables

I have a very unique situation where I need a password set by a shell script. (I am open to other options.) We are currently looking to use a certain encryption software that requires "Power On Authentication". This requires a separate "encryption user account" for the encryption. I will be setting the local user account in OS X to auto login. I have a script to change BOTH passwords, that will run some applescript commands to prompt the user for there old password, then their new password twice, and it verifies the passwords match. It then verifies the old password is valid against the encryption by running a command and checking for a successful exit status, if it is valid it proceeds to change the encryption password based on the variables given in the apple script. I am looking for a way to verify and set the user account password in the process. I have a basic script but I am looking for a little error checking, in that if the passwords are not already the same (the encryption and local account), or at least if the user account password fails to set, that it is echoed.
I can certainly provide the scripts I have if necessary.

A few side notes - I am well aware of the security implications of coding a password into a shell script. That is not what I am doing, I am passing variables from applescript.

This is for doctors who...god forbid...cannot be burdened with having to keep track of separate accounts. (It is kind of a pain in the rear.)

Help is greatly appreciated.

MacBookPro7,1, Mac OS X (10.6.5), Lots of other computers

Posted on Nov 27, 2010 9:07 PM

Reply
23 replies

Nov 27, 2010 9:22 PM in response to iDam81


(echo $THE_PASSWORD;echo $THE_PASSWORD) | sudo passwd $THEUSERNAME_TOCHANGE

Actually it is best if this is already running as root, as 'sudo' wants your password, and that might be difficult to give if you are running this from a script, that is not in a Terminal session.

Of course if you are in a terminal session, then you can enter you password for 'sudo'

Nov 27, 2010 10:03 PM in response to BobHarris

This will be an icon in the applications folder that launches an applescript application bundle that runs a shell script. I do not want any terminal intervention. Also I am pretty sure that will not work from a shell script. I am pretty sure passwd only accepts input from tty does it not? I am currently using the expect command as follows:


#!/usr/bin/expect
#script name = changePWreq.sh
set oldpass [lindex $argv 0]
set newpass [lindex $argv 1]
spawn /usr/bin/passwd
expect word:
sleep 1
send $oldpass
expect word:
sleep 1
send $newpass
expect word:
sleep 1
send $newpass
expect success


I call the script above from the script below, which takes the user input and passes the variables in as arguments to the script above.


#Prompting User for Password
passWdNtSt="true"
while [ $passWdNtSt == true ];
do
OLDPSWD0=`/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Please enter your old Password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD0 to text returned of the result
end tell
EOF`
PSWD0=`/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Please enter a new password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD0 to text returned of the result
end tell
EOF`
PSWD1=`/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Please verify your new password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD1 to text returned of the result
end tell
EOF`
if [ "$PSWD0" == "$PSWD1" ]; then
passWdNtSt="false"
else
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Your Passwords do not match, please try again!"
end tell
EOF
fi
done
#Setting Encryption User Password
/usr/bin/'softwarevendor' --list-users --authenticate-user $USER --authenticate-password $OLDPSWD0
if [ "$?" != "0" ]; then
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "The password you typed is incorrect. Please try again." buttons {"OK"} default button "OK"
end tell
exit
EOF
else
/usr/bin/softwarevendor --change-password --user $USER --old-password $OLDPSWD0 --new-password $PSWD0 --confirm-password $PSWD1

#Setting OSX account password
/Users/Shared/Softwarevendor/changePWreq.sh $OLDPSWD0 $PSWD0
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Your password has been set." buttons {"OK"} default button "OK"
end tell
EOF
fi

Nov 28, 2010 6:39 AM in response to iDam81

I do not want any terminal intervention.

That means you are going to need 'root' privileges.
Your script is using expect which might be a way to
also pass your admin password to 'sudo'. And when I
say your admin password, I'm assuming when you run
this script you are logged in as an admin user, otherwise
'sudo' is not going to work, and unless you can get
root privileges you are not going to be able to change
the password of another user.

Of course if you are logged in as that user, then they
are allowed to change their own password without any
elevated privileges.
Also I am pretty sure that will not work from a shell script.
I am pretty sure passwd only accepts input from tty does it not?

I actually tested my example before I posted it.
AND it worked last night when 'sudo' was changing the password
of another account. However, this morning, it is not working
for my own account. Neither as is, nor with 'sudo'.

Your 'expect' stuff is looking better and better 🙂
I am currently using the expect command as follows:

I'm not a great 'expect' person, but it seems to me you should
be able to do this all with 'expect', including providing 'sudo'
with your admin password.

#!/usr/bin/expect
#script name = changePWreq.sh
set oldpass [lindex $argv 0]
set newpass [lindex $argv 1]
spawn /usr/bin/passwd
expect word:
sleep 1
send $oldpass
expect word:
sleep 1
send $newpass
expect word:
sleep 1
send $newpass
expect success

If this is being run by the actual user, then in theory
(as I have not tested your code), it should work.
I call the script above from the script below, which takes the user input and passes the variables in as arguments to the script above.


#Prompting User for Password
passWdNtSt="true"
while [ $passWdNtSt == true ];
do
OLDPSWD0=`/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Please enter your old Password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD0 to text returned of the result
end tell
EOF`
PSWD0=`/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Please enter a new password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD0 to text returned of the result
end tell
EOF`
PSWD1=`/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Please verify your new password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD1 to text returned of the result
end tell
EOF`
if [ "$PSWD0" == "$PSWD1" ]; then
passWdNtSt="false"
else
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Your Passwords do not match, please try again!"
end tell
EOF
fi
done
#Setting Encryption User Password
/usr/bin/'softwarevendor' --list-users --authenticate-user $USER --authenticate-password $OLDPSWD0
if [ "$?" != "0" ]; then
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "The password you typed is incorrect. Please try again." buttons {"OK"} default button "OK"
end tell
exit
EOF
else
/usr/bin/softwarevendor --change-password --user $USER --old-password $OLDPSWD0 --new-password $PSWD0 --confirm-password $PSWD1
#Setting OSX account password
/Users/Shared/Softwarevendor/changePWreq.sh $OLDPSWD0 $PSWD0
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "Your password has been set." buttons {"OK"} default button "OK"
end tell
EOF
fi
> /Users/Shared/Softwarevendor/changePWreq.sh $OLDPSWD0 $PSWD0

NOTE: If your users are limited to a-z A-Z 0-9
and a hand full of special characters, your script should
be OK. HOWEVER, if any of the shell magic characters
are allowed as passwords, then you are going to have problems.

$ ` | & * ( ) ? ; ' " <space> <tab>

all have meaning on the command line, and commands such as:

/Users/Shared/Softwarevendor/changePWreq.sh $OLDPSWD0 $PSWD0

is going to have a field day with unprotected magic characters.

I think if you change the way you get our osascript output and
make sure you are running 'bash' as your shell, you can do the
following which will provide shell protection quoting to any
password the user enters:

#!/usr/bin/env bash
read OLDPSWD0 < <(/usr/bin/osascript -e '
tell application "System Events"
activate
display dialog "Please enter your old Password:" default answer "" with hidden answer buttons {"OK"} default button "OK"
set the PSWD0 to text returned of the result
end tell
')
printf -v OLDPSWD0 "%q" "$OLDPSWD0"
echo $OLDPSWD0

The < space <(/usr/bin/osascript ...) is very important,
as it makes sure that the "read OLDPSWD0" happens in the
current shell context and that the osascript runs in a
subprocesses.

I changed the <<-EOD to just use the -e option as it is
easier to work with.

The printf "%q" is what converts any shell magical characters
into a quoted string so that when you $OLDPSWD0 on a command
line, all the magical characters are protected from the shell
seeing them as magical.

Apply the same style to your other osascripts and you should
be good.

The < space <(...) and the printf "%q" are actually all in
the "man bash" man page, however, as with most Unix man pages
it is not obvious 🙂

Nov 28, 2010 7:28 AM in response to iDam81

Can you post some details of whatever this encryption widget might be? It seems ill-suited to the requirements, but I'll reserve that judgement for now.

Keeping passwords in synch is never fun, and this whole area is a huge target, both for attackers and for any savvy auditors that might lurk.

I might look to see if I could add a connection into the device authentication via SASL or Kerberos, for instance. Or raise a dialog to the user via Apple Script. (Then there's the whole issue of whether it's a trusted dialog.)

Nov 28, 2010 8:41 AM in response to MrHoffman

MrHoffman wrote:
Can you post some details of whatever this encryption widget might be? It seems ill-suited to the requirements, but I'll reserve that judgement for now.

Keeping passwords in synch is never fun, and this whole area is a huge target, both for attackers and for any savvy auditors that might lurk.

I might look to see if I could add a connection into the device authentication via SASL or Kerberos, for instance. Or raise a dialog to the user via Apple Script. (Then there's the whole issue of whether it's a trusted dialog.)


I am using Sophos Safe Guard for OS X. To be honest it IS a bit ill-suited. I work for a health care organization which requires all mobile devices are encrypted. Our biggest issue is the POA (Power On Authentication) which requires 2 I.D.s on the machine. The Safeguard ID and the local ID. Until we can turn POA off (in a future release) we are stuck with this. I have looked at a few other pieces of software and they all seem very limited in the MAC realm.

I would be very pleased if you are able to do anything with this. sgadmin is the widget I am calling in place of "softwarevendor".

And just a note - Everything seems to work fine for the SafeGuard user accounts, even verifying the old one before I change it by running a command that requires safeguard authentication and verifying the exit code.

/usr/bin/'softwarevendor' --list-users --authenticate-user $USER --authenticate-password $OLDPSWD0
if [ "$?" != "0" ]; then
/usr/bin/osascript <<-EOF
tell application "System Events"
activate
display dialog "The password you typed is incorrect. Please try again." buttons {"OK"} default button "OK"
end tell
exit
EOF
else

My troubles are with the local account, and if at all possible (Im not holding my breath) trying to verify the SafeGuard and Local account are the same.

/n

@BobHarris - Thank you very much for all of your input. Especially the special characters. I will look into changing that right away. I was unsure how to tackle that. I appreciate you breaking it all down as well. I am still fairly new to scripting and there is still a LOT I don't know so I always appreciate the explanations.

As far as my Expect script...It does seem to run most of the time as I am running the script as the logged in user and changing the password for the logged in user. But my biggest concern is that I get no notice of any kind if the expect script does not change the password. It just runs like it completed. I am looking for some way of "error checking" I guess.

Thank you both again. Very appreciative.

Nov 28, 2010 9:11 AM in response to iDam81

I'm aware of sites that fill the USB slots with epoxy to prevent external storage. Draconian, but it does reduce the risks.

I'd look to get the Mac OS X FileVault encryption approved for use on generic devices, though that might or might not get past the auditors. If it does, you're good to go.

As you've realized, you're really doing the vendor's work here, which means you're increasing the size of the target that both the auditors and the attackers will seek; this vendor doesn't seem to particularly have Mac support. Seems an opening here for a device that's actually integrated, but that's another discussion. I'll have to think about this; how to tie the mount into OD and an external drive, via SASL or such. Interesting question.

Nov 28, 2010 9:24 AM in response to iDam81

As far as my Expect script...It does seem to run most of the time
as I am running the script as the logged in user and changing the
password for the logged in user. But my biggest concern is that
I get no notice of any kind if the expect script does not change
the password. It just runs like it completed. I am looking for
some way of "error checking" I guess.

You could try using the 'su' command to validate that the password
has been changed as desired:

su $USER -c "exit 0"
if [ $? != 0 ]; then
echo oops
fi

You of course put that into an 'expect' script. The 'su' command will
prompt for the password to $USER. You would provide the new password.

If 'su' works, then $? will be 0. If 'su' fails because the password
was wrong, then $? will be 1.

Nov 28, 2010 10:29 AM in response to iDam81

iDam81 wrote:
I have a very unique situation where I need a password set by a shell script.


Groan 😟

(I am open to other options.)


Could you explain a bit more about what you are actually trying to accomplish - "the big picture"?

I understand the bit about 3rd party encryption software and mobile encryption regulations and convoluted scripts. None of that is important. You can buy expensive, useless software, have draconian regulations, and write convoluted scripts all without our help. Imagine the perfect environment, assuming anything is possible, and explain that. Then we can better determine how close you can reasonably get to that.

This is for doctors who...god forbid...cannot be burdened with having to keep track of separate accounts. (It is kind of a pain in the rear.)


Understood. However, any problems will be blamed on you. If there is a security beach caused by doctors sharing a single account and writing the password on a post-it and taping it to the monitor (this is exactly what will happen, by the way), it will be your fault. You can impose behaviors on the users under the guise of "required by the software". If they don't like it, have a "woe is me" act rehearsed and a reasonable backup plan.

Nov 28, 2010 11:28 AM in response to etresoft

MrHoffman wrote:
I'd look to get the Mac OS X FileVault encryption approved for use on generic devices, though that might or might not get past the auditors. If it does, you're good to go.


Unfortunately FileVault does not meet our needs. We are supposed to adhere to the HiTech Act.
http://www.hipaasurvivalguide.com/hitech-act-text.php

We use Sophos for our Windows encryption. We are just starting to support apple devices and are looking to keep Sophos. I am looking at SecureDoc now. At first it seemed even more Windows based than Sophos did, but I think I am going to give it a second look. But for now Sophos is what we have.

BobHarris wrote:
You of course put that into an 'expect' script. The 'su' command will
prompt for the password to $USER. You would provide the new password.


I think the problem here is it would again, require user interaction through the command line which is what I am trying to avoid. But I do appreciate the effort.


etresoft wrote:
Could you explain a bit more about what you are actually trying to accomplish - "the big picture"?


I would be happy to. I work for a health care system where a perfect environment is far from what we have. Passwords are already taped to monitors and under keyboards. (Because that is much more hidden.)

We are just starting to support Apple products and we are looking into full disk encryption. We currently use Sophos SafeGuard for our Windows encryption solution and we are looking at Sophos for our Apple solution as well. Sophos for Apple is very simple in that you can have two levels of user accounts, Admin and User, POA is required and cannot be disabled. No management console or logging.

We are also evaluating JAMF Casper Suite to deploy the SafeGuard encryption to the Apple devices. We deploy the encryption client first. After a reboot I deploy a set of scripts. The scripts work as follows.

Prompts user to create an encryption account password using applescript and shell script. Script creates encryption Admin account, User account, and Recovery account. Script starts encryption process. Full disk encryption is the only option. (Which we want anyways.) No reporting is available so the script creates log files which are copied upon completion. (Which I will have some questions about, but thats a whole other topic.) When this script creates the encryption User account, it uses the $USER variable to create the SafeGuard account using the same name as the OSX shortname. The users will be instructed to set the password the same as their current login password. This will make the SafeGuard and OSX accounts the same as far as name and password. We will be enabling auto logon in OSX because the POA cannot be disabled and we do not want the doctors/users to be prompted w/ two logins. This will still leave the need for 2 passwords though. This is the reason for me wanting to create the script that sets both passwords. It technically works but I am not comfortable with the lack of error control when setting the OSX (unix) account. I am completely comfortable with setting the Sophos account info.

I am also comfortable with the fact that I do not have any passwords hard coded into my scripts. I guess I am unclear as to what can be done to intercept that password from the applescript to the shell script? I will certainly take that into account if you are saying that it is a risk, but I am honestly more concerned about there passwords getting out of sync. The doctors are not sharing the accounts, (not in this situation, that too is a whole other topic.) but in this scenario it is one user w/ 2 seperate accounts to logon to a device.
I think that the doctors having two passwords and/or accounts to remember would lead them to write it on a sticky note and hang it on there monitor more so than with just one account.

MrHoffman wrote:
As you've realized, you're really doing the vendor's work here, which means you're increasing the >size of the target that both the auditors and the attackers will seek; this vendor doesn't seem to >particularly have Mac support


You are absolutely right. Most of there answers were..."It will be in the next release. Oh next year..." Sometimes we just have to work with what we got. (Until someone chalks up the cash to do otherwise.)

etresoft wrote:
Understood. However, any problems will be blamed on you.


LOL, maybe I should just scrap this an make them deal with two accounts...

Nov 28, 2010 11:59 AM in response to iDam81

Run a solution based on FileVault past the HIPAA auditors. (Seriously.) Tell then (or show them) what you need to do with the scripts to get the approved solution to work; if you have cogent auditors (and without intending offense toward your skills), that processing may scare them more.

I'm well aware of HIPAA and of OS-level security implementation; worked in both areas for many years. I'd work with the auditors here, and would ask them for guidance. (I'd also look for an OD tie-in, rather than trying to do this with a script. Integration might well require more documentation of the API into these Sophos widgets than is available, unfortunately.)

Nov 28, 2010 5:09 PM in response to iDam81

iDam81 wrote:
etresoft wrote:
Could you explain a bit more about what you are actually trying to accomplish - "the big picture"?


I would be happy to.
I work for a health care system ... yada yada yada...


That is not "the big picture". You just mentioned the software you are using for Windows that has an anemic Mac version, then got into details about scripts.

What are you trying to do? Do you want to encrypt your entire hard drive? Why?

You mentioned that FileVault was no good. Why not? It doesn't encrypt the OS, but does that need to be encrypted? You can easily prevent anyone from writing data anywhere on the machine other than their home directories. If you have MacOS X Server (or Active Directory for that matter), you can restrict them even more.

Do you want to comply with government regulations? Which ones? These? http://www.aishealth.com/Compliance/arra.html

I couldn't find the term "encrypt" in any of those three documents.

How are you going to certify compliance? Is someone going to do that for you or are you just doing your best effort. A simple solution is going to be best. In any case, a solution based on some scripts is going to be pretty fragile.

Nov 28, 2010 5:46 PM in response to etresoft

We are doing full disk encryption to comply with the HiTech Acts Breach Notification requirements. We are also looking for logging in case a device is stolen. We need to be able to provide proof that the device is encrypted. I mentioned Filevault not meeting our needs because it does not do full disk encryption and we can not prove that the device is encrypted. I don't want to prevent people from writing data to there drives at this time, I want to provide full disk encryption and logging. We literally just started supporting Apple devices so we have NOT brought them into our AD environment, and will not be for some time. We do not own an OS X server, but we are looking to, as well as the JAMF software suite, but those are down the line as well.

We are still in a long process of meeting the HiTech and HIPPA standards, but our current goal is to provide, and be able to prove, there is full disk encryption on mobile devices in case of theft.

http://www.hipaasurvivalguide.com/hitech-act-text.php

http://digitalbenefits.typepad.com/HITECH/sonn.pdf

All in all I think I am going to forget about the topic of this post and NOT provide the users a script to change both of there passwords as it seems to be more of a risk then a benefit. I certainly do appreciate all of the points that were brought forward and it certainly made me think twice about what I have been working on implementing. I think another look at WinMagic SecureDoc is due.

Also, I am not a security officer. I am a desktop engineer tasked with verifying the encryption that our CTO has defined meets our needs. Full disk encryption and logging.

Nov 28, 2010 7:51 PM in response to iDam81

I think you are still missing a few things. Who is going to certify or prove all of this? Are you concerned exclusively with theft? If so, you've eliminated all the hard stuff. In that case, I see no reason why FileVault would not meet your needs or why you couldn't prove it. If you really want full disk encryption, you can get that from PGP. There is currently a PGP bug with 10.6.5 but that wouldn't affect you nor should it have affected anyone else who knew anything about security.

These people know a thing or two about security: http://www.nsa.gov/ia/guidance/securityconfiguration_guides/operatingsystems.shtml

Nov 28, 2010 10:04 PM in response to BobHarris

@BobHarris

I noticed when I run expect script on its own and I set the password incorrect it returns:
passwd: authentication token failure


When I echo $? it returns 0 even though the passwords were incorrect. I believe that is because the script completed successfully though. But I should be able to query that return status in the script shouldn't I? I never see the return status because I never see the CLI. As I mentioned above the expect script runs from within the other script.

I tried adding the following to the end of the expect script:
if [ "$?" == "0" ], then
echo "yay"
else
echo "fail"
fi


I get the return of:
invalid command name "$?"
while executing
""$?" == "0" "
invoked from within
"if [ "$?" == "0" ], then"


Any ideas on how I could watch for that return code or what might be going on here?

Shell Script to set a user password from variables

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.