Skip navigation
This discussion is archived

Shell Script to set a user password from variables

6811 Views 23 Replies Latest reply: Nov 29, 2010 9:48 PM by iDam81 RSS
1 2 Previous Next
iDam81 Calculating status...
Currently Being Moderated
Nov 27, 2010 9:07 PM
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
  • BobHarris Level 6 Level 6 (12,535 points)
    Currently Being Moderated
    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'
    MacBook/10.6.4, iMac/i7/10.6.2, PowerMac/G5/10.4.11(deceased), Mac mini/10.5.6, iPod Touch(4thGen)/32GB/4.1, iBook/G4, MacBook Pro, iMac/Core2Duo
  • BobHarris Level 6 Level 6 (12,535 points)
    Currently Being Moderated
    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
    MacBook/10.6.4, iMac/i7/10.6.2, PowerMac/G5/10.4.11(deceased), Mac mini/10.5.6, iPod Touch(4thGen)/32GB/4.1, iBook/G4, MacBook Pro, iMac/Core2Duo
  • MrHoffman Level 6 Level 6 (11,745 points)
    Currently Being Moderated
    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.)
  • MrHoffman Level 6 Level 6 (11,745 points)
    Currently Being Moderated
    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.
  • BobHarris Level 6 Level 6 (12,535 points)
    Currently Being Moderated
    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.
    MacBook/10.6.4, iMac/i7/10.6.2, PowerMac/G5/10.4.11(deceased), Mac mini/10.5.6, iPod Touch(4thGen)/32GB/4.1, iBook/G4, MacBook Pro, iMac/Core2Duo
  • etresoft Level 7 Level 7 (23,915 points)
    Currently Being Moderated
    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.
    MacBook Pro, Mac OS X (10.6.4), + iPad + MacBook 2007
  • MrHoffman Level 6 Level 6 (11,745 points)
    Currently Being Moderated
    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.)
  • etresoft Level 7 Level 7 (23,915 points)
    Currently Being Moderated
    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.
    MacBook Pro, Mac OS X (10.6.4), + iPad + MacBook 2007
  • etresoft Level 7 Level 7 (23,915 points)
    Currently Being Moderated
    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
    MacBook Pro, Mac OS X (10.6.4), + iPad + MacBook 2007
1 2 Previous Next

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.