1#!/usr/bin/perl
2
3################################################################################
4#
5# changepass.pl - A program to allow users to change their passwords
6#                 via a web browser.
7# Terry Davis
8# 
9# URLs
10#	Net::LDAP - http://
11#	usermod and this file - http://www.cloudamster.com/cloudmaster/projects
12#
13# Release History:
14#	Version 0.1 - initial write
15#
16# ToDo:
17#	... the ToDo section is on the ToDo list...
18#
19# Limitations:
20#	The password cannot contain single and double quotes.....welcome to quoting hell....
21#
22# Notes:
23#       This code is largely based on work done by Danny Sauer - http://www.cloudamster.com/cloudmaster/projects
24#       His work is not licensed and is marked as 'freely distributable'.
25#       Thank you to Danny for his hard work on the initial work.
26#
27################################################################################
28
29use CGI qw(:standard);
30use Net::LDAP;
31
32# CONFIGURATION SECTION
33$masterLDAP = "ldap.idealx.org";
34$basedn = "dc=IDEALX,dc=org";
35$masterPw = "";
36$masterDN = "cn=manager,$basedn";
37$ldap_path = "/usr/bin";
38$ldap_opts = "-x";
39$ldappasswd = "$ldap_path/ldappasswd $ldap_opts -h $masterLDAP -D '$masterDN' -w '$masterPw'";
40$usersdn = "ou=Users,$basedn";
41# END CONFIGURATION
42
43
44
45# DONT EDIT ANYTHING BELOW THIS LINE
46$logtag = "Login:";
47$passtag = "Current password:";
48$npasstag1 = "New password:";
49$npasstag2 = "Retype new pasword:";
50$error = "";
51$color = "<FONT color='red'>";
52$stopcolor = "</FONT>";
53
54if(param()){
55	nologin() unless ($username = param('login'));
56	nopass() unless ($oldpass = param('oldpass'));
57	nonewpass(1) unless ($newpass1 = param('newpass'));
58	nonewpass(2) unless ($newpass2 = param('newpass2'));
59	verifyuser($username) or die "bad user";
60	verifypass($username, $oldpass) or die "bad pass";
61	testnewpass($newpass1, $newpass2) or die "bad new pass";
62	changepass($username, $newpass1) or die "couldn't change pass";
63	printsuccess();
64}else{
65	printpage();
66}
67exit(0);
68
69sub verifyuser{
70	local $user = shift;
71	$ldap = Net::LDAP->new($masterLDAP) or die "can't make new LDAP object: $@";
72	$ldap->bind();
73	if (0 < $ldap->search(base => $basedn, filter => "(uid=$user)")->count){
74		return 1;
75	}
76	$logtag = $color . $logtag . $color;
77	$error = "No such user";
78	printpage();
79	return 0;
80}
81
82sub verifypass{
83	$uid = shift;
84	$pass = shift;
85	$ldap = Net::LDAP->new($masterLDAP) or die "can't make new LDAP object: $@";
86	$binddn = "uid=$uid,ou=People,$basedn";
87	return 1 if($ldap->bind( $binddn, password => $pass)->code == 0);
88	if($ldap->bind()){
89		$passtag = $color . $passtag . $color;
90		$error = "Incorrect password";
91		printpage();
92		return 0;
93	}else{
94		print header, start_html(-title=>"LDAP dead");
95		print h2("<CENTER>The LDAP server is temporarily unavailable."),
96			p,"Please try again later</CENTER>";
97		return 0;
98	}die "Something (or someone) is defective, contact your friendly Systems Administrator";
99}
100
101sub testnewpass{
102	$p1 = shift; $p2 = shift;
103	if ($p1 ne $p2){
104		$npasstag1 = $color . $npasstag1 . $color;
105		$npasstag2 = $color . $npasstag2 . $color;
106		$error = "Passwords don't match ($p1 vs $p2)";
107		printpage();
108		return 0;
109	}
110        if ($p1 =~ /"/ ){
111                $npasstag1 = $color . $npasstag1 . $color;
112                $npasstag2 = $color . $npasstag2 . $color;
113                $error = "Passwords cannot contain double quotes. Sorry";
114                printpage();
115                return 0;
116        }
117        if ($p1 =~ /'/ ){
118                $npasstag1 = $color . $npasstag1 . $color;
119                $npasstag2 = $color . $npasstag2 . $color;
120                $error = "Passwords cannot contain single quotes. Sorry";
121                printpage();
122                return 0;
123        }
124	return 1;
125}
126
127sub changepass{
128	local $user = shift;
129	local $newpass = shift;
130	local $dn = "uid=$user,$usersdn";
131	system "$ldappasswd $dn -s '$newpass' > /dev/null";
132	`/usr/bin/sudo /usr/bin/smbpasswd $user "$newpass"`;	
133	exit(1);
134}
135
136sub nologin{
137	$logtag = $color . $logtag . $color;
138	$error = "You need to enter a Login Name";
139	printpage();
140	exit(1);
141}
142
143sub nopass{
144	$passtag = $color . $passtag . $color;
145	$error = "Please enter your old password";
146	printpage();
147	exit(1);
148}
149
150sub nonewpass{
151	$f=shift;
152	$npasstag1 = $color . $npasstag1 . $color if($f==1);
153	$npasstag2 = $color . $npasstag2 . $color if($f==2);
154	$error = "You need to enter your new password";
155	$error .= " twice" if($f==2);
156	printpage();
157	exit(1);
158}
159
160sub printpage{
161	print header,
162	      start_html(-title=> "Password Change Page",
163	                 -author=> 'tdavis@birddog.com',
164			 -BGCOLOR=> 'WHITE'),
165	      h3('Password Change Page'),
166	      startform(-method=>'POST'),
167	      "<TABLE BORDER=0 WIDTH=50%>",
168	      "<font size=2>",
169	      "<TR><TD>",
170	      $logtag,
171	      "</TD><TD>",
172	      textfield(-name=>'login', -default=>$login, 
173	                -size=>15, -maxlength=>20),
174	      "</TD><TR><TD>",
175	      $passtag,
176	      "</TD><TD>",
177	      password_field(-name=>'oldpass', -size=>15, -maxlength=>25),
178	      "</TD><TR><TD>",
179	      $npasstag1,
180	      "</TD><TD>",
181	      password_field(-name=>'newpass', -size=>15, -maxlength=>25),
182	      "</TD><TR><TD>",
183	      $npasstag2,
184	      "</TD><TD>",
185	      password_field(-name=>'newpass2', -size=>15, -maxlength=>25),
186	      "</TD><TR><TD></TD><TD>",
187	      submit(-name=>"change"),reset(),
188	      "</TD></TR></TABLE>",
189	      "</font>",
190	      endform(),
191	      "<FONT color='red'>$error</FONT>",
192	      end_html;
193}
194
195sub printsuccess(){
196	print header,
197	      start_html(-title=> "Success",
198		             -BGCOLOR=> 'WHITE'),
199		  h1("Password Succesfully Changed"),
200		  "<br>",
201		  end_html;
202}
203