My boss asked me to install a program that could be used to edit LDAP User Properties. I've decided to build my own, and ended up with those four files:
Filename: prop_login.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My Company - LDAP User Props Editor Login</title> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> <meta name="author" content="Luis Campos de Carvalho"> <link rel="stylesheet" type="text/css" href="[%style%]" /> </head> <body> <br> <br> <br> <br> <br> <form action="[%action%]" method="post"> <table border="0" align="center" class="outer"> <tbody> <tr> <td valign="top" class="inner"> </td> <td valign="middle" class="center"> <table border="0" class="inner" align="center"> <tbody> <tr align="center"> <td valign="top" rowspan="1" colspan="2"> <br> <span class="bold"> My Company - LDAP Prop User Editor Login </span> </td> </tr> <tr> <td valign="top"> </td> <td valign="top"> </td> </tr> <tr> <td valign="top" class="right"> Usuário: </td> <td valign="top" class="center"> <input type="text" name="username" size="20"> </td> </tr> <tr> <td valign="top" class="right"> Senha: </td> <td valign="top" class="center"> <input type="password" name="passwd" size="20"> </td> </tr> <tr> <td valign="top"> </td> <td valign="top"> </td> </tr> <tr align="center"> <td valign="top" rowspan="1" colspan="2"> <input type="image" src="[%login_img_url%]" name="login" value="Entrar"> </td> </tr> </tbody> </table> </td> </tr> [%IF message %] <tr><td colspan="3" style="width: 500;"></td></tr> <tr> <td colspan="3" align="center" valign="middle"> <font color="#FF3300"> <b>[% message %]</b> </font> </td> </tr> [% END %] </tbody> </table> </form> </body> </html>
Filename: prop_edit.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <script> function markChanged( object ) { if( document.formObject.changeHandler.value == '' ) { document.formObject.changeHandler.value = object.name }else{ document.formObject.changeHandler.value = document.formObjec +t.changeHandler.value + ";" + object.name } } </script> <title>My Company - LDAP User Props Editor</title> <meta http-equiv="content-type" content="text/html; charset=ISO-88 +59-1"> <meta name="author" content="Luis Campos de Carvalho"> <link rel="stylesheet" type="text/css" href="[%style%]" /> </head> <body> <form name="formObject" action="[%action%]" method="GET"> <input type="hidden" name="changeHandler" value=""> <table border="0" class="frame"> <tbody> <tr> <td class="spacer"> </td> <td class="center"> <table border="0" align="center" class="center"> <tbody> <tr> <td class="spacer center"> </td> <td colspan="2" class="center"> <span class="bold center title"> My Company </span> </td> </tr> [%IF message %] <tr> <td class="space center"> </td> <td colspan="2" class="center"> [% message %] </td> <td class="space center"> </td> </tr> [%END%] <tr> <td class="spacer center"> </td> <td colspan="2" class="center"> <span class="bold"> [ [% displayName %] ] </span> </td> <td class="spacer center"> </td> </tr> <tr> <td class="spacer"> </td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> Departamento: </span> </td> <td class="item left">[% department %]</td> <td class="spacer center"> </td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> User ID: </span> </td> <td class="item left">[% uid %]</td> </tr> <tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> E-Mail: </span> </td> <td class="item left">[% mail %]</td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> Iniciais: </span> </td> <td class="item left"> <input type="text" size="5" maxlength="3" value="[% initials %]" name="initials" onChange="markChanged( this )"> </td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> Celular: </span> </td> <td class="item left"> <input type="text" size="17" maxlength="17" value="[% mobile %]" name="mobile" onChange="markChanged( this )"> </td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> Pager: </span> </td> <td class="item left"> <input type="text" size="17" maxlength="25" value="[% pager %]" name="pager" onChange="markChanged( this )"> </td> </tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold"> Tel. Residencial: </span> </td> <td class="item left"> <input type="text" size="17" maxlength="17" value="[% homePhone %]" name="homePhone" onChange="markChanged( this )"> </td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold">Senha: </span> </td> <td class="item left"> <input type="password" size="18" maxlength="20" name="user_passwd" onChange="markChanged( this )"> </td> </tr> <tr> <td class="spacer center"> </td> <td class="item right"> <span class="bold">Confirme Senha: </span> </td> <td class="item left"> <input type="password" size="18" maxlength="20" name="user_passwd2" onChange="markChanged( this )"> </td> </tr> <!-- Sample row <tr> <td class="spacer center"> </td> <td class="item"> <span class="bold"> </span> </td> <td class="item">[%%]</td> </tr> --> <tr> <td class="spacer center"> </td> <td class="item center"> <input type="image" src="[% apply_image_url %]" name="enviar" value="enviar"> </td> <td class="item center"> <input type="image" src="[% logout_image_url %]" name="logout" value="logout"> </td> </tr> </tbody> </table> </td> <td valign="top" style="width: 5%;"> </td> </tr> </tbody> </table> </form> </body> </html>
Filename: style.css
body { font-face: "Verdana"; } table.outer{ width:50%; text-align:left; margin-left:auto; margin-right:auto; } td.right{text-align:right;} td.spacer{ width: 5%; } td.inner{width:5%;} td.item{ width: 45%; } .center{text-align:center;} .title { font-size: 150%; } .left { text-align: left; } table.inner{ width:95%; background-color:rgb(0,204,204); text-align:left; margin-left:auto; margin-right:auto; } span.bold{ font-weight:bold; } table.frame{ width: 95%; background-color:rgb(0,204,204); text-align:center; margin-left:auto; margin-right:auto; }
Filename: index.pl
#!/usr/bin/perl use warnings; use strict; use CGI; use CGI::Session; use CGI::Carp qw( fatalsToBrowser ); use Template; use constant LDAP_SERVER => 'ldap.mycompany.com'; use constant CSS_URL => 'http://intranet.mycompany.com/style.css'; use constant ENTRAR_IMG => 'http://intranet.mycompany.com/images/entr +ar.gif'; use constant SAIR_IMG => 'http://intranet.mycompany.com/images/sair +.gif'; use constant APLICAR_IMG => 'http://intranet.mycompany.com/images/apli +car.gif'; my $cgi = new CGI; my $session = new CGI::Session( 'driver:File', $cgi, {Directory=>'/tmp +'} ); my $tmpl = new Template( { INCLUDE_PATH=> '/home/lcampos/src/ldap' +} ); if( $cgi->param( 'logout' ) ){ print STDERR "MODO: LOGOUT\n"; # usuario deu logout, despacha. $session->delete(); print $cgi->redirect( $cgi->url( full=>1, query=>0 ) ); }elsif( $session->param( 'logged_in' ) && ! $cgi->param( 'enviar' ) ){ print STDERR "MODO: LDAP_EDIT_LOOP\n"; # Usuario logado, processa alteracoes. change_ldap_loop( $cgi, $session, $tmpl ); }elsif( $session->param( 'logged_in' ) && $cgi->param( 'enviar' ) ){ print STDERR "MODO: LDAP_COMMIT_EDITION\n"; # Usuario pediu para aplicar mudancas commit_edition( $cgi, $session, $tmpl ); }elsif( $cgi->param( 'username' ) && $cgi->param( 'passwd' ) ){ print STDERR "MODO: LDAP_EDITOR_AUTH\n"; # usuario tentanto logar, autentica... authenticate_user( $cgi, $session, $tmpl ); }else{ print STDERR "MODO: ASK_FOR_CREDENTIALS\n"; # usuario acabou de chegar, pede credenciais. show_login_form( $cgi, $session, $tmpl ); } sub show_login_form{ my( $cgi, $session, $tmpl, $message ) = ( shift, shift, shift, shift + ); print $cgi->header(); $tmpl->process( 'prop_login.html', { action => $cgi->url( full=>1, query=>0 ), style => CSS_URL, login_img_url => ENTRAR_IMG, message => $message || '', } ) || confess $tmpl->error(); } # # Obtem o 'Distinguished Name' deste usuario no sistema, # atraves de um query LDAP anonimo. # sub get_dn{ my( $ldap, $username ) = ( new Net::LDAP( LDAP_SERVER ), shift ); return undef unless $ldap && $username; my $msg = $ldap->bind; confess $msg->error_name if $msg->is_error(); my $search = $ldap->search( base => 'dc=integral,dc=com,dc=br', filter => "(&(objectClass=person)(uid=$username))" ); confess "Muitos usuarios com mesmo identificador?!?!" if $search->count() > 1; my $entry = $search->pop_entry(); confess "Usuario nao encontrado" unless $entry; my $dn = $entry->dn(); $ldap->unbind(); return $dn; } sub commit_edition{ my( $cgi, $session, $tmpl ) = ( shift, shift, shift ); my $ldap = new Net::LDAP( LDAP_SERVER ); my $dn = $session->param( 'dn' ); my $msg = $ldap->bind( $dn, password => $session->param( 'passwd' ) + ); confess $msg->error_name if $msg->is_error(); my $search = $ldap->search( base => 'dc=integral,dc=com,dc=br', filter => "(&(objectClass=person)(uid=" . $session->param('username')."))" ); confess $search->error_name if $search->is_error; confess "Muitos registros descobertos sob um mesmo DN!??!" if $search->count() > 1; my $entry = $search->pop_entry(); undef $search; undef $msg; my @changed = do{ my %changed = map {$_=>1} split qr/;/, $cgi->param( 'changeHandler +' ); keys %changed; }; my $message; # Determina a alteracao de senha do usuario; my $passwd_changed = grep m/user_passwd2?/, @changed; @changed = grep ! m/user_passwd2?/, @changed; unshift @changed, 'userPassword' if $passwd_changed; # Processa cada valor alterado, trata de acordo... foreach my $value( @changed ){ my $new = $cgi->param( $value ); # Alterar senhas eh excecao: processa separado. if( $value eq 'userPassword' ){ my( $p1, $p2 ) = ( $cgi->param( 'user_passwd' ), $cgi->param( 'user_passwd2' ) ); if ( $p1 ne $p2 ) { $message = $cgi->font( {color=>"#CC3300"}, "Senhas digitadas não conferem" ); last; }else{ $entry->replace( userPassword => $p1 ); } }else{ if( $new ){ if( $entry->exists( $value ) ){ $entry->replace( $value => $cgi->param( $value ) ); }else{ $entry->add( $value => $cgi->param( $value ) ); } }else{ $entry->delete( $value ); } } } # Atualiza valores apenas quando nao existem erros. if( @changed && ! $message ){ $msg = $entry->update( $ldap ); confess $msg->error_name . "\n" . $msg->error if $msg->is_error; $message = $cgi->font( { color=>"#0033CC"}, "Atualizado com sucess +o." ); } # Exibe HTML print $session->header; $tmpl->process( 'prop_edit.html', { style => CSS_URL, action => $cgi->url( -full=>1, -query=>0 ), message => $message, displayName => $entry->get_value( 'displayName' ), department => $entry->get_value( 'ou' ), initials => $entry->get_value( 'initials' ) || '', mail => $entry->get_value( 'mail' ), mobile => $entry->get_value( 'mobile' ) || '', pager => $entry->get_value( 'pager' ) || '', uid => $entry->get_value( 'uid' ), homePhone => $entry->get_value( 'homePhone' ) || '', apply_image_url => APLICAR_IMG, logout_image_url => SAIR_IMG, } ) or confess $tmpl->error(); } # # Processa alteracoes realizadas por um # usuario jah logado no sistema # sub change_ldap_loop{ my( $cgi, $session, $tmpl ) = ( shift, shift, shift ); my $ldap = new Net::LDAP( LDAP_SERVER ); my $dn = $session->param( 'dn' ); my $msg = $ldap->bind( $dn, password => $session->param( 'passwd' ) + ); confess $msg->error_name if $msg->is_error(); my $search = $ldap->search( base => 'dc=integral,dc=com,dc=br', filter => "(&(objectClass=person)(uid=" . $session->param('username')."))" ); confess $search->error_name if $search->is_error; confess "Muitos registros descobertos sob um mesmo DN!??!" if $search->count() > 1; my $entry = $search->pop_entry(); undef $search; undef $msg; # update displayName key. unless( $entry->exists( 'displayName' ) ){ (my $displayName = join ' ', map $entry->get_value( $_ ), qw,cn sn +,) =~ s/[\"\']//g; $entry->exists( 'displayName' )? $entry->replace( displayName => $displayName ) : $entry->add( displayName => $displayName ); my $msg = $entry->update( $ldap ); $msg->is_error() && confess $msg->error_name; } print $session->header; $tmpl->process( 'prop_edit.html', { style => CSS_URL, action => $cgi->url( -full=>1, -query=>0 ), displayName => $entry->get_value( 'displayName' ) || '', department => $entry->get_value( 'ou' ) || '', initials => $entry->get_value( 'initials' ) || '', mail => $entry->get_value( 'mail' ) || '', mobile => $entry->get_value( 'mobile' ) || '', pager => $entry->get_value( 'pager' ) || '', uid => $entry->get_value( 'uid' ), homePhone => $entry->get_value( 'homePhone' ) || '', apply_image_url => APLICAR_IMG, logout_image_url => SAIR_IMG, } ) or confess $tmpl->error(); } # # Tenta autenticar usuarios pelos parametros passados no CGI. # sub authenticate_user{ my( $cgi, $session, $tmpl ) = ( shift, shift, shift ); my( $username, $passwd ) = map $cgi->param($_), qw,username passwd,; use Net::LDAP; my $dn = get_dn( $username ) or confess "Nao consegui encontrar o Registro LDAP do usuario $use +rname"; my $ldap = new Net::LDAP( LDAP_SERVER ) or confess "Desculpe, nao consegui conectar com o LDAP."; my $msg = $ldap->bind( $dn, password => $passwd ); do{ show_login_form( $cgi, $session, $tmpl, "Login Inválido" ); return; } if $msg->error_name eq 'LDAP_INVALID_CREDENTIALS'; confess $msg->error_name if $msg->is_error; $session->param( 'logged_in', 'YES' ); $session->param( 'username', $cgi->param( 'username' ) ); $session->param( 'passwd', $cgi->param( 'passwd' ) ); $session->param( 'dn', $dn ); $session->expire( 'logged_in' => '+10m' ); $session->expire( '+30m' ); # chegar ate aqui da acesso ao sistema de alteracao. change_ldap_loop( $cgi, $session, $tmpl ); }
"In few words, translating PerlMonks documentation and best articles to other languages is like building a bridge to join other Perl communities into PerlMonks family. This makes the family bigger, the knowledge greather, the parties better and the life easier." -- monsieur_champs
|
---|