Home
TeamSite
Changing the Solaris user password
nnguyen
We are facing an issue where our IT department is forcing us to change user passwords on our Solaris box every 90 days. This is awkward, because our users are only familiar with their TeamSite password, and there is not provision within TeamSite to change the password. The IT department is issuing a "passwd -f" command on the TeamSite box, which will force the password change, this weekend. Also, the existing security rules "prevent" the TeamSite Support Group (us) from changing the user passwords and sending them out to them, but the users themselves have to change their own password.
I found a thread that spoke of writing custom code to achieve this functionality, but have had no success getting it to work. The IT Department is implementing this change this weekend, so any help getting this up and running would be greatly appreciated. Thanks in advance.
Find more posts tagged with
Comments
Migrateduser
Can they and do they have the skills to telnet in? If so I think you can set their shell to /usr/bin/passwd, which may let them change their password without actually logging in. Not sure if that would help in your specific case though.
nnguyen
Having them use Telnet really is not an option. The Teamsite interface makes it easy for them to access the backing store without having to even know that they have a Unix account. Our headaches would increase exponentially if we introduced telnet for the users in our environment.
Migrateduser
What about a CGI that captures the current and new and repeat new passwords and user name as a hidden field:
Current: _____________
New: _____________
Repeat New: ______________
Then takes those inputs and behind the scenes opens a telnet session and changes the passwd as that user?
open(TELNET,"|telnet <server>");
select TELNET; $|=1; select STDOUT;
print TELNET $username . "\n";
print TELNET $oldpw . "\n";
print TELNET "passwd\n";
print TELNET $newpw . "\n";
print TELNET $repeatpw . "\n";
print TELNET "exit\n";
close TELNET;
This is an extremely simplified version of what I would do. I'd have some error checking to make sure the new password and repeat password are the same. I'd make sure that the current password is valid. If anyone has a better idea, I'm all ears. This was the best I could come up with in 15 minutes of thought.
- Jason
Adam Stoller
Or - combine the ideas already suggested - have a custom menu item that run's telnet to the server where they have /bin/passwd set as their login shell.
Also, some folks have been able to write network programs that utilize 'expect' to perform the information interchange without putting the password in clear-text - at least I believe that can be done (haven't had to do it myself, so I don't know for sure)
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
daudy
Try this.
The EXPECT script to change user password.
#!/usr/local/bin/expect --
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>"}
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
-----end of EXPECT script------
-----HTML FORM TO CAPTURE LOGIN-ID, OLD PASSWORD, NEW PASSWORD----
<HTML>
<head>
<title>Change your login password</title>
<script language="JavaScript">
<!--
function MM_callJS(jsStr) { //v2.0
return eval(jsStr)
}
function MM_findObj(n, d) { //v4.0
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d)&&d.all) x=d.all; for (i=0;!x&&i<d.forms.length;i++) x=d.forms
;
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers
.document);
if(!x && document.getElementById) x=document.getElementById(n); return x;
}
function MM_validateForm() { //v4.0
var i,p,q,nm,test,num,min,max,errors='',args=MM_validateForm.arguments;
for (i=0; i<(args.length-2); i+=3) { test=args[i+2]; val=MM_findObj(args
);
if (val) { nm=val.name; if ((val=val.value)!="") {
if (test.indexOf('isEmail')!=-1) { p=val.indexOf('@');
if (p<1 || p==(val.length-1)) errors+='- '+nm+' must contain an e-mail address.\n';
} else if (test!='R') {
if (isNaN(val)) errors+='- '+nm+' must contain a number.\n';
if (test.indexOf('inRange') != -1) { p=test.indexOf(':');
min=test.substring(8,p); max=test.substring(p+1);
if (val<min || max<val) errors+='- '+nm+' must contain a number between '+min+' and '+max+'.\n';
} } } else if (test.charAt(0) == 'R') errors += '- '+nm+' is required.\n'; }
} if (errors) alert('The following error(s) occurred:\n'+errors);
document.MM_returnValue = (errors == '');
}
//-->
</script>
</head>
<body bgcolor="#FFCCCC">
<form method=post
action="/iw-bin/expect/passwd.cgi" onSubmit="MM_validateForm('name','','R','name','','R','old','','R','new1','','R','new2','','R');return document.MM_returnValue">
<h2><font face="Arial, Helvetica, sans-serif" size="3">Change your login password.</font></h2>
<table width="60%" border="0" cellspacing="0" cellpadding="0">
<tr bgcolor="#CC9999">
<td><font face="Arial, Helvetica, sans-serif" size="3">Username</font></td>
<td> <font face="Arial, Helvetica, sans-serif" size="3">
<input name="name">
</font></td>
</tr>
<tr>
<td><font face="Arial, Helvetica, sans-serif" size="3">Old password</font></td>
<td> <font face="Arial, Helvetica, sans-serif" size="3">
<input type=password name="old">
</font></td>
</tr>
<tr bgcolor="#CC9999">
<td><font face="Arial, Helvetica, sans-serif" size="3">New password</font></td>
<td> <font face="Arial, Helvetica, sans-serif" size="3">
<input type=password name="new1">
</font></td>
</tr>
<tr>
<td><font face="Arial, Helvetica, sans-serif" size="3">New password</font></td>
<td> <font face="Arial, Helvetica, sans-serif" size="3">
<input type=password name="new2">
</font></td>
</tr>
<tr bgcolor="#CC9999">
<td><font face="Arial, Helvetica, sans-serif" size="3"> </font></td>
<td><font face="Arial, Helvetica, sans-serif" size="3"> </font></td>
</tr>
</table>
<table width="60%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td> </td>
</tr>
</table>
<p><font face="Arial, Helvetica, sans-serif" size="3">New password must be entered
twice to avoid typos.<br>
Password must be at least 6 characters long. <br>
Password must contain at least 2 alphabet and 1 numeric or special character.
</font></p>
<p><br>
<input type=submit value="Change password" onClick="MM_validateForm('name','','R','old','','R','new1','','R','new2','','R');return document.MM_returnValue">
<input type="reset" name="Reset" value="Reset">
<input type="button" name="Close" value="Close" onClick="MM_callJS('window.close()')">
</p>
</form>
</body>
</html>