added check for url
[mirror/userdir-ldap-cgi.git] / update.cgi
1 #!/usr/bin/perl
2
3 # $Id: update.cgi,v 1.3 1999/10/23 04:01:44 tausq Exp $
4 # (c) 1999 Randolph Chung. Licensed under the GPL. <tausq@debian.org>
5
6 use lib '.';
7 use strict vars;
8 #use Apache::Registry;
9 use CGI;
10 use Util;
11 use URI::Escape;
12 use Net::LDAP qw(:all);
13
14 my %config = &Util::ReadConfigFile;
15
16 my $query = new CGI;
17 my $proto = ($ENV{HTTPS} ? "https" : "http");
18
19 my $id = $query->param('id');
20 my $authtoken = $query->param('authtoken');
21 my $password = &Util::CheckAuthToken($authtoken);
22 my $editdn = $query->param('editdn');
23
24 if (!($id && $password)) {
25   print "Location: $proto://$ENV{SERVER_NAME}/$config{webloginurl}\n\n";
26   exit;
27
28
29 my $ldap;
30
31 sub DieHandler {
32   $ldap->unbind if (defined($ldap));
33 }
34
35 $SIG{__DIE__} = \&DieHandler;
36
37 $ldap = Net::LDAP->new($config{ldaphost});
38 my $auth = 0;
39 my $mesg;
40 $mesg = $ldap->bind($editdn, password => $password);
41 $mesg->sync;
42 $auth = ($mesg->code == LDAP_SUCCESS);
43
44 if (!$auth) {
45   $ldap->unbind;
46   &Util::HTMLError("You have not been authenticated. Please <a href=\"$proto://$ENV{SERVER_NAME}/$config{webloginurl}\">Login</a>");
47 }
48
49 # Authenticated....
50 # Get our entry...
51 $mesg = $ldap->search(base   => $editdn,
52                       filter => "uid=*");
53 $mesg->code && &Util::HTMLError($mesg->error);
54   
55 my $entries = $mesg->as_struct;
56 if ($mesg->count != 1) {
57   # complain and quit
58 }
59   
60 my @dns = keys(%$entries);
61 my $entry = $entries->{$dns[0]};
62
63 if (!($query->param('doupdate'))) {
64   # Not yet update, just fill in the form with the current values
65   my %data;
66   
67   # Fill in %data
68   # First do the easy stuff - this catches most of the cases
69   foreach (keys(%$entry)) {
70     $data{$_} = $entry->{$_}->[0];
71   }
72   
73   # Now we have to fill in the rest that needs some processing...
74   $data{id} = $id;
75   $data{authtoken} = $authtoken;
76   $data{editdn} = $editdn;
77   $data{staddress} = $entry->{postaladdress}->[0];
78   $data{staddress} =~ s/\$/\n/;
79   $data{countryname} = &Util::LookupCountry($data{c});
80   if ($data{labeledurl} !~ /^https?:\/\//i) {
81     &Util::HTMLError("Malformed URL entered");
82   }
83   
84   $data{email} = join(", ", @{$entry->{emailforward}});  
85
86   # finally we can send output...
87   my ($sub, $substr);
88   &Util::HTMLSendHeader;
89   open (F, "<$config{webupdatehtml}") || &Util::HTMLError($!);
90   while (<F>) {
91     s/~(.+?)~/$data{$1}/g;
92     print;
93   }
94   close F;
95   
96 } else {
97   # Actually update stuff...
98   my ($newpassword, $newstaddress);
99   
100   if ($query->param('newpass') && $query->param('newpassvrfy')) {
101     if ($query->param('newpass') ne $query->param('newpassvrfy')) {
102       # passwords don't match...
103       &Util::HTMLError("The passwords you specified do not match. Please go back and try again.");
104     }    
105     # create a md5 crypted password
106     $newpassword = '{crypt}'.crypt($query->param('newpass'), &Util::CreateCryptSalt(1));
107     
108     LDAPUpdate($ldap, $editdn, 'userPassword', $newpassword);
109     &Util::UpdateAuthToken($authtoken, $query->param('newpass'));
110   }  
111
112   $newstaddress = $query->param('staddress');
113   $newstaddress =~ s/\n/\$/m;
114   
115   my ($lat, $long);
116   ($lat, $long) = &Util::CheckLatLong($query->param('latitude'), 
117                                       $query->param('longitude'));
118   
119   LDAPUpdate($ldap, $editdn, 'postalAddress', $newstaddress);
120   LDAPUpdate($ldap, $editdn, 'l', $query->param('l'));
121   LDAPUpdate($ldap, $editdn, 'latitude', $lat);
122   LDAPUpdate($ldap, $editdn, 'longitude', $long);
123   LDAPUpdate($ldap, $editdn, 'c', $query->param('country'));
124   LDAPUpdate($ldap, $editdn, 'postalcode', $query->param('postalcode'));
125   LDAPUpdate($ldap, $editdn, 'telephoneNumber', $query->param('telephonenumber'));
126   LDAPUpdate($ldap, $editdn, 'facsimileTelephoneNumber', $query->param('facsimiletelephonenumber'));
127   LDAPUpdate($ldap, $editdn, 'loginShell', $query->param('loginshell'));
128   LDAPUpdate($ldap, $editdn, 'emailForward', $query->param('email'));
129   LDAPUpdate($ldap, $editdn, 'privatesub', $query->param('privatesub'));
130   LDAPUpdate($ldap, $editdn, 'ircNick', $query->param('ircnick'));
131   LDAPUpdate($ldap, $editdn, 'labeledUrl', $query->param('labeledurl'));
132   LDAPUpdate($ldap, $editdn, 'onvacation', $query->param('onvacation'));
133
134   # when we are done, reload the page with the updated details.
135   my $url = "$proto://$ENV{SERVER_NAME}/$config{webupdateurl}?id=$id&authtoken=$authtoken&editdn=";
136   $url .= uri_escape($editdn, "\x00-\x40\x7f-\xff");
137   print "Location: $url\n\n";  
138 }
139
140 $ldap->unbind;
141
142 sub LDAPUpdate {
143   my $ldap = shift;
144   my $dn = shift;
145   my $attr = shift;
146   my $val = shift;
147   my $mesg;
148   
149   if (!$val) {
150     $mesg = $ldap->modify($dn, delete => { $attr => [] });
151   } else {
152     $val = [ $val ] if (!ref($val));
153     $mesg = $ldap->modify($dn, replace => { $attr => $val });
154     $mesg->code && &Util::HTMLError("error updating $attr: ".$mesg->error);
155   }
156 }