Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 505
  • Last Modified:

Giving passwords from command line

Hi,

I need a utility that will enable me to assign passwords to users from command line.  I.e I want to be able to do something like this

paswd --newpass p asdf user

passwd command on the system is interactive and cannot assign passwords from command line.   We need a way thats reliable, quick and something that can work on a multi user system.

We keep passwords in the shadow file.  I'm working on SunOS 5.6.  We have thousands of users.

Thanks in advance
0
bozkirli
Asked:
bozkirli
  • 2
  • 2
1 Solution
 
tfewsterCommented:
Download and install "expect", a scripting language, from:  
http://dev.scriptics.com/ (sources, binaries, apps & more!)  

Create a shell script looking something like this:

#!/usr/local/bin/expect --

spawn /usr/bin/passwd $1
expect "New password:"
send "$2\r"
expect "Re-enter password:"
send "$2\r"

Execute this script with the username and new password as command line
parameters.

The shadow password file won't be a problem, as you're still using the
standard "passwd" command, but using expect to dummy the input.

For a good manual & examples for expect scripts, look at:
http://www.oreilly.com/catalog/expect/chapter/ch03.html 
0
 
jlevieCommented:
Expanding on tfewster's comment...

You need expect and an expect script to set the password. Solaris 2.6 & above have a fancier passwd command than previous versions, which you might need to take advantage of. The expect script below can selectively set a user's password in any of the authentication services Solaris supports via passwd. As a bonus, it also works on Linux

---snip, snip, - begin newpass---
#!/usr/bin/expect --
#
# NAME
#       newpass - set user's passwd from the command line non-interactively
#
# SYNOPSIS
#       newpass user password [files|nis|nisplus]
#
# DESCRIPTION
#       When run as root, this script will interact with passwd and set
#       "password" for the specified "user". The script knows about both
#       Solaris and Linux and, in the case of Solaris, can explicitly
#       set the password in any of the three possible services
#       (files, nis, or nisplus). If not specified, the system default
#       for authentication is used.
#
# Author: Jim Levie (jlevie@bellsouth.net)
#
log_user 0
set LinuxOS 0
set svc "default"
if {[exec uname -s] == "Linux"} { set LinuxOS 1 }
if {!$LinuxOS && $argc == 3} {
    if {[lindex $argv 2] == "files" || [lindex $argv 2] == "nis"
      || [lindex $argv 2] == "nisplus"} {
      set svc "[lindex $argv 2]"
    } else {
      send_error "Usage: newpass user passwd \[files|nis|nisplus\]\n"
      exit 1
    }
} elseif {$LinuxOS && $argc != 2} {
    send_error "Usage: newpass user passwd\n"
    exit 1
} elseif {$argc < 2 || $argc >3} {
    send_error "Usage: newpass user passwd \[files|nis|nisplus\]\n"
    exit 1
}
set user [lindex $argv 0]
set pass [lindex $argv 1]
#
# Solaris 2.6 & later needs the -r option to specify which
# password service (files, nis, nisplus) see man passwd.  Linux
# has passwd in a different location and doesn't need the
# service specification. (Note that I no longer have anything
# earlier than 2.6 to test with, you've been warned... there be
# dragons here).
#
# BIG NOTE!!! Linux has to have the "sleep 1" between each of
# the "expect/send" pairs. It puts out the prompt before it's actually
# ready to take input. You can comment them out for Solaris, but
# it doesn't hurt for them to be there and might be a plus
# busy server. (there be really big dragons here...)
#

if {$LinuxOS} {
    spawn -noecho /usr/bin/passwd $user
} else {
    if {$svc == "files"} {
      spawn /bin/passwd -r files $user
    } elseif {$svc == "nis"} {
      spawn /bin/passwd -r nis $user
    } elseif {$svc == "nisplus"} {
      spawn /bin/passwd -r nisplus $user
    } else {
      spawn /bin/passwd $user
    }
}

if {$LinuxOS} { sleep 1 }
expect {
    -re "(.*) does not exist" {
      send_error "unknown user: $user\n"
      exit 1
    } -re "(.*) Unknown user(.*)" {
      send_error "unknown user: $user\n"
      exit 1
    } default {
      send_error "$expect_out(buffer)"
      exit 1
    } -re "New (.*)password:"
}
send "$pass\r"
if {$LinuxOS} { sleep 1 }
expect {
    -re "passwd.SYSTEM.(.*)" {
      send_error "$expect_out(buffer)"
      exit 1
    } -re "BAD(.*)" {
      send_error "$expect_out(buffer)"
      exit 1
    } default {
      send_error "Unknown error from passwd\n"
      exit 1
    } -re "Re(.*) password:"
}
send "$pass\r"
if {$LinuxOS} { sleep 1 }
expect {
    -re "passwd(.*) try again" {
      send_error "$expect_out(buffer)"
      exit 1
    } -re "Sorry,(.*)" {
      send_error "$expect_out(buffer)"
      exit 1
    } default {
      send_error "Unknown error from passwd\n"
      exit 1
    } -re "(.*) successfully changed (.*)" {
      send_user "Password changed\n"
      exit 0
    } -re "(.*) updated successfully" {
      send_user "Password changed\n"
      exit 0
    }
}
close
wait
send_user "\n"

0
 
tfewsterCommented:
Nice one Jim - BTW, take a look at http://www.experts-exchange.com/jsp/qShow.jsp?ta=unixprog&qid=10306983  - another Q. on "expect" & I'm way out of my depth

  __|__
  \___/
~~~~~~~~
 O
  o
   .
  :(
0
 
canaliCommented:
I resolved the problem using a utility for creating the crypted new password and then changing shadow file or nis master passwod file with a script.

gcp.c compiled with gcc on a solaris 5.6
(generate crypted password) work fine

paswd bourne shell script
I adapted 4 you the bourn script

#paswd
#!/bin/sh
#backup shadow
cp /etc/shadow ./shadow.`date '+%d_%b_%y.%T'`
cat /dev/null>shadow.new
cat /etc/shadow|nawk -v USER=$1 -v NEWCRYPTPWD=`./gcp "$2"`  '{FS=":";OFS=":"}\
   $1 != USER {print $1,$2,$3,$4,$5,$6,$7>>"shadow.new"}\
   $1 == USER {print $1,""NEWCRYPTPWD"",$3,$4,$5,$6,$7>>"shadow.new"}'

/**************gcp.c**************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/timeb.h>

static      char      Salt[3];
static      void      GenSalt();

main(int argc, char *argv[])
{
char pwd[20], *p;

if ( argc != 2 ) {
    printf("Uso: %s password\n",argv[0]);
    exit(1);
}
GenSalt();
strcpy(pwd,argv[1]);
p = crypt(pwd,Salt);
printf("%s\n",p);
}

static void GenSalt()
{
    int cnt;
    long r;
    time_t t;
    struct timeb tb;

    //time(&t);
    ftime(&tb);
    t = tb.time + tb.millitm;
    srandom(t);
    memset(Salt,'\0',3);
    cnt = 0;
    while ( cnt < 2 ) {
        r = random() & 0x7f;
        if (( r >= 46 && r <= 57 ) || ( r>=65 && r <= 90 ) || ( r >= 97 && r <= 122 )) {
            Salt[cnt] = r;
            cnt++;
        }
    }
}

0
 
jlevieCommented:
Yeah, I've done that too, how are you going to handle NIS+, what about systems using MD5 authentication via pam? The expect script does as it uses the system password program...
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now