• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1028
  • Last Modified:

passwd and expect

jlevie...

Thanks for all your help....

I have a couple of more questions until my expect book gets in...

I am using the same passwd.cgi that comes with expect.  I am running on a Solaris 5.7 machine.

I have to change the following line:

spawn /bin/su $var(name) -c "/bin/yppasswd $var(name)"

to

spawn /bin/su $var(name) -c "/bin/passwd $var(name)"

to get the script to start working.

However, I am getting the following response in my browser.

Passwd Change Acknowledgment
Error: Password:

Do you have any ideas...??

Thanks again...
0
afpcos
Asked:
afpcos
  • 14
  • 10
  • 2
  • +1
1 Solution
 
jlevieCommented:
I'm looking at it...
0
 
jlevieCommented:
I found it. Which version of expect do you have? I'm looking at 5.31 and I can post the change if we're both using the same version.
0
 
afpcosAuthor Commented:
Yes.. I am using 5.31...
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
afpcosAuthor Commented:
Yes.. I am using 5.31...
0
 
jlevieCommented:
Okay, I'll put the change up in a bit.
0
 
afpcosAuthor Commented:
jlevie...

Good morning....

Were you going to post the change here or on the expect web site.

Thanks...!!!
0
 
jlevieCommented:
It'll be here, I ran out of time last night and didn't get to test it as a cgi... very soon, I promise...
0
 
afpcosAuthor Commented:
Thanks...

I just wanted to make sure I was looking in the right place...

See ya
0
 
afpcosAuthor Commented:
Thanks...

I just wanted to make sure I was looking in the right place...

See ya
0
 
jlevieCommented:
Okay, here tis. Replace the expect code in passwd.cgi with what follows.

---Snip, Snip..---
# Change following line appropriately for your site.
# Solaris 2.6 & later needs the -r option to specify which
# password service (files, nis, nisplus) see man passwd.
spawn /bin/su $var(name) -c "/bin/passwd -r files $var(name)"

expect {
    "Unknown login:" {
      errormsg "unknown user: $var(name)"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } "Password:"
}
send "$var(old)\r"
expect {
    "unknown user" {
      errormsg "unknown user: $var(name)"
      exit
    } "Sorry" {
      errormsg "Old password incorrect"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } -re "(New P|Enter login p)assword:"
}
send "$var(old)\r"
expect {
    default {
      errormsg "$expect_out(buffer)"
    } "New password:"
}
send "$var(new1)\r"
expect -re "(N|Re-enter n)ew password:"
send "$var(new2)\r"
expect -re (.*)\r\n {
      set error $expect_out(1,string)
}
close
wait
0
 
afpcosAuthor Commented:
jlevie...

I made the changes you suggested.

The script seems to be executing all the way through the code now.

However, the password is not being changes.

Unless you have any other ideas, I guess I will have to wait for the book.
0
 
jlevieCommented:
Are you using files, NIS, or NIS+?
0
 
ahoffmannCommented:
(keep me informed;-)
0
 
afpcosAuthor Commented:
I am using files.

I think I have narrowed it down.

After this line:

expect -re (.*)\r\n {
set error $expect_out(1,string)
}

I had to type:

wait
expect eof

For it to work.

However, the code you suggested cut out the last display that tells the user if there was an error or if it was successfull.  I need this for the users.

When I add that back in between the wait and the expect eof, it still changes the password, but it does not display the message.

I am still working on this.

If you have a solution in the next day or so I will increase your points and accept the answer.  If not,  in a couple of days...I will accept the answer as is because it was a very good lead to the answer.

Again...Thank you!!!

I am new to Unix and expect...you were a great help.
0
 
jlevieCommented:
Do you have these lines:

if {[info exists error]} {
        errormsg "$error"
} else {
        successmsg "Password changed successfully."
}

after the code I sent? There were in the original and are responsible for the displaying the last error or the success message.
0
 
afpcosAuthor Commented:
Yes...

It looks like the problem is that even when the password is changed, it is going through the first part of the last if and displaying

Error:

I tried displaying the error variable prior to going into the if statement and it is null.

It should be going through the else statement and displaying "Password changed successfully.".
0
 
afpcosAuthor Commented:
Yes...

It looks like the problem is that even when the password is changed, it is going through the first part of the last if and displaying

Error:

I tried displaying the error variable prior to going into the if statement and it is null.

It should be going through the else statement and displaying "Password changed successfully.".
0
 
afpcosAuthor Commented:
Yes...

It looks like the problem is that even when the password is changed, it is going through the first part of the last if and displaying

Error:

I tried displaying the error variable prior to going into the if statement and it is null.

It should be going through the else statement and displaying "Password changed successfully.".
0
 
afpcosAuthor Commented:
jlevie...

Just received my book.

This is what I did to make it work for me.

wait -nowait

if [llength $error]>0 {
        errormsg "$error"
} else {
        successmsg "Password changed successfully."
}

expect eof

I changed the wait to wait -nowait because
where the user did not type the second new password correctly it took forever for the error message to come back.

I also read about if statements and changed it to [llength $error]>0.

I am new at this, so unless you see anything here with these changes that I could improve on or will have problems with, I will accept your answer.

Thanks...
0
 
jlevieCommented:
I don't think the "wait -nowait" is the solution. That, "causes the wait to return immediately with the indication of a successful wait".

Let me look at something else, I just found what might be a slight variation in the behaviour of "passwd" (when presented with an invalid second password) depending on what patches are installed. I think I need a more general closure section.   Shortly...
0
 
paulqnaCommented:
Is this what you mean...:

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

spawn /usr/bin/passwd $1
expect "New password:"
send "$2\r"
expect "Re-enter password:"
send "$2\r"
0
 
jlevieCommented:
I've made some progess. Interestingly, I've found lots of ways to get it to fail amoung my 2.6, 2.7, & 2.8 systems. I think I've pretty well sorted out and accounted for the differences, but I'd like to do one last round of tests before I post the results. Say tomorrow as it's late and the regression test takes a while to work through all the ways I know it can fail.
0
 
ahoffmannCommented:
try a
  sleep 1
as last command in your expect script
0
 
afpcosAuthor Commented:
jlevie....

I will await your post.

Again thank you for your help.

My experience is in Visual Basic, Access, and Informix database.

Maybe some dat I can return the favor.

Have a nice weekend.  

I will check back on Monday...
0
 
jlevieCommented:
I think I've got it now, at least I can't find a way to cause it to fail in "playtoy mode". A replacement passwd.cgi follows. Below that is a "playtoy" that can be run from the command line to check out the expect script without having to go through a web server.

---snip,snip - begin passwd.cgi---
#!/depot/path/expect --

# This is a CGI script to process requests created by the accompanying
# passwd.html form.  This script is pretty basic, although it is
# reasonably robust.  (Purposely intent users can make the script bomb
# by mocking up their own HTML form, however they can't expose or steal
# passwords or otherwise open any security holes.)  This script doesn't
# need any special permissions.  The usual (ownership nobody) is fine.
#
# With a little more code, the script can do much more exotic things -
# for example, you could have the script:
#
# - telnet to another host first (useful if you run CGI scripts on a
#   firewall), or
#
# - change passwords on multiple password server hosts, or
#
# - verify that passwords aren't in the dictionary, or
#
# - verify that passwords are at least 8 chars long and have at least 2
#   digits, 2 uppercase, 2 lowercase, or whatever restrictions you like,
#   or
#
# - allow short passwords by responding appropriately to passwd
#
# and so on.  Have fun!
#
# Don Libes, NIST

puts "Content-type: text/html\n"      ;# note extra newline

puts "
<head>
<title>Passwd Change Acknowledgment</title>
</head>

<h2>Passwd Change Acknowledgment</h2>
"

proc cgi2ascii {buf} {
    regsub -all {\+} $buf { } buf
    regsub -all {([\\["$])} $buf {\\\1} buf
    regsub -all -nocase "%0d%0a" $buf "\n" buf
    regsub -all -nocase {%([a-f0-9][a-f0-9])} $buf {[format %c 0x\1]} buf
    eval return \"$buf\"
}

foreach pair [split [read stdin $env(CONTENT_LENGTH)] &] {
      regexp (.*)=(.*) $pair dummy varname val
      set val [cgi2ascii $val]
      set var($varname) $val
}

log_user 0

proc errormsg {s} {puts "<h3>Error: $s</h3>"}
proc successmsg {s} {puts "<h3>$s</h3>"}

# Need to su first to get around passwd's requirement that passwd cannot
# be run by a totally unrelated user.  Seems rather pointless since it's
# so easy to satisfy, eh?
#
# Change following appropriately for your site.
#
# 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...)
#

spawn /bin/su $var(name) -c "/bin/passwd -r files $var(name)"
#spawn /bin/su $var(name) -c "/usr/bin/passwd"

sleep 1
expect {
    "Unknown (login|id):" {
      errormsg "unknown user: $var(name)"
      exit
    } -re "(.*) does not exist" {
      errormsg "unknown user: $var(name)"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } "Password:"
}
send "$var(old)\r"
sleep 1
expect {
    "Sorry" {
      errormsg "Old password incorrect"
      exit
    } "incorrect passwd" {
      errormsg "Old password incorrect"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } -re "(.*)(login|UNIX) password:"
}
send "$var(old)\r"
sleep 1
expect {
    "Sorry" {
      errormsg "Old password incorrect"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } -re "New (.*)password:"
}
send "$var(new1)\r"
sleep 1
expect {
    -re "passwd.SYSTEM.(.*)" {
      errormsg "$expect_out(buffer)"
      exit
    } -re "BAD(.*)" {
      errormsg "$expect_out(buffer)"
      exit
    } default {
      errormsg "Unknown error from passwd"
      exit
    } -re "Re(.*) password:"
}
send "$var(new2)\r"
sleep 1
expect {
    -re "passwd(.*) try again" {
      errormsg "$expect_out(buffer)"
      exit
    } -re "Sorry,(.*)" {
      errormsg "$expect_out(buffer)"
      exit
    } default {
      errormsg "Unknown error from passwd"
      exit
    } -re "(.*) successfully changed (.*)" {
      successmsg "Password successfully changed"
      exit
    } -re "(.*) updated successfully" {
      successmsg "Successfully updated password"
      exit
    }
}
close
wait

---snip,snip - begin playtoy ---
#!/usr/local/bin/expect --

set var(name) gork
set var(old) passpass
set var(new1) @SU5nfYt
set var(new2) @SU5nfYt

proc errormsg {s} {send_error "!!$s!!"}
proc successmsg {s} {send_error "<$s>"}

#
# This is a playtoy for testing the passwd.cgi script without actually
# having to use a web server. The tcl code above fills in the variables
# that the cgi would have and redirects the output to our terminal.
# Everything below can be simply pasted over the expect script
# portion of passwd.cgi.

# Need to su first to get around passwd's requirement that passwd cannot
# be run by a totally unrelated user.  Seems rather pointless since it's
# so easy to satisfy, eh?

# Change following appropriately for your site.
#
# 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...)
#

spawn /bin/su $var(name) -c "/bin/passwd -r files $var(name)"
#spawn /bin/su $var(name) -c "/usr/bin/passwd"

sleep 1
expect {
    "Unknown (login|id):" {
      errormsg "unknown user: $var(name)"
      exit
    } -re "(.*) does not exist" {
      errormsg "unknown user: $var(name)"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } "Password:"
}
send "$var(old)\r"
sleep 1
expect {
    "Sorry" {
      errormsg "Old password incorrect"
      exit
    } "incorrect passwd" {
      errormsg "Old password incorrect"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } -re "(.*)(login|UNIX) password:"
}
send "$var(old)\r"
sleep 1
expect {
    "Sorry" {
      errormsg "Old password incorrect"
      exit
    } default {
      errormsg "$expect_out(buffer)"
      exit
    } -re "New (.*)password:"
}
send "$var(new1)\r"
sleep 1
expect {
    -re "passwd.SYSTEM.(.*)" {
      errormsg "$expect_out(buffer)"
      exit
    } -re "BAD(.*)" {
      errormsg "$expect_out(buffer)"
      exit
    } default {
      errormsg "Unknown error from passwd"
      exit
    } -re "Re(.*) password:"
}
send "$var(new2)\r"
sleep 1
expect {
    -re "passwd(.*) try again" {
      errormsg "$expect_out(buffer)"
      exit
    } -re "Sorry,(.*)" {
      errormsg "$expect_out(buffer)"
      exit
    } default {
      errormsg "Unknown error from passwd"
      exit
    } -re "(.*) successfully changed (.*)" {
      successmsg "Password successfully changed"
      exit
    } -re "(.*) updated successfully" {
      successmsg "Successfully updated password"
      exit
    }
}
close
wait

0
 
afpcosAuthor Commented:
Adjusted points from 50 to 100
0
 
afpcosAuthor Commented:
jlevie...

Sorry it took me so long to accept your answer.

I was tied up in another project.

Thanks again!!!

afpcos....
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

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