#!/usr/bin/perl # # $Id: htpasswd.pl,v 1.1 2004/03/28 23:17:30 ueli Exp $ # # (c) 2003 by ueli@heuer.org # # use lib "/home/default/includes"; use CGI qw/:standard/; use CGI::Pretty qw( :html4 ); use Crypt::Cracklib; use DBI; require "htpasswd.inc"; # DB-username/passwort dieser user MUSS schreibrechte haben # htpasswd.inc defines $dbsource, $dbuser and $dbpassword # $dbsource should be a DBI-Resource # --- htpasswd.inc --- # as an Example you may use following: #$dbuser='htadmin'; #$dbhost='localhost'; #$dbpassword='geheim'; #$dbname='htpasswd'; #$dbsource = "DBI:mysql:database=$dbname;host=$dbhost:"; #1; # --- eof htpasswd.inc --- # wo liegt die server config (ohne $includes !!!) $SERVER_CONF='/etc/httpd2/httpd.conf'; $CRACKLIB = '/var/cache/cracklib/cracklib_dict'; $server_ip=$ENV{'SERVER_ADDR'}; if ($server_ip =~ /:/) { $server_ip = "[$server_ip]"; } $db = DBI->connect( $dbsource, $dbuser, $dbpassword) || do { print header(-Location=>"http://$server_ip/htpasswd/nodb.php"); exit(0); }; # fetch some global values ($server,$domain)=get_servername(server_name()); $master_user = remote_user(); $script = script_name(); $user=param('user'); $password=param('password'); $host_group=get_host_group(); if ( $master_user eq '' ) { print header,h1("zu dumm, das geht einfach nicht ohne username und passwort"); exit(0); } # prepare some queries ... # $check_member_h = $db->prepare("select user_name from user_group where user_name = ? and user_group = ? and host_group = ?"); $user_h = $db->prepare("select user_name,isadmin from user_info where host_group = ? order by isadmin desc,user_name"); $is_master_h = $db->prepare("select isadmin from user_info,host_info where user_info.host_group=host_info.host_group and host=? AND user_name = ?"); $get_password_h = $db->prepare("select user_passwd from user_info,host_info where user_info.host_group=host_info.host_group and host=? AND user_name = ?"); $check_user_h = $db->prepare ("select user_name from user_info where user_name = ? and host_group = ?"); $|=1; # do ddatabase jobs bevor any header is sent ... if (param) { $doit = param('doit'); $salt = sprintf("%c%c",int(rand(95))+33,int(rand(95))+33); if ($doit eq 'saveuser') { $old_passwd = get_password($user); if ( is_admin($master_user) ) { if ( param('delete') == 1 ) { # delete user from user and group table if ( $user ne $master_user ) { # delete only "other" users, NOT myself! $delete_user_h = $db->prepare ("delete from user_info where user_name = ? and host_group = ?"); $delete_group_member_h = $db->prepare ("delete from user_group where user_name = ? and host_group = ?"); $delete_user_h->execute($user,$host_group); $delete_group_member_h->execute($user,$host_group); print header(-Location=>"$script?action=deleted&user=$user"); exit (0); } else { $error{'user'} = "I do not like suicid :(
I do not delete myself!"; } } else { $passwd_ok = 1==0; $admin = param('admin')+0; if ( $password eq "" ) { $passwd = $old_passwd; $passwd_ok = 1==1; } else { if (check($password,$CRACKLIB)) { $passwd=crypt($password,$salt); $passwd_ok = 1==1; } } if ( $passwd_ok ) { $update_adminuser_h = $db->prepare("update user_info set user_passwd = ?,isadmin=? where user_name = ? and host_group = ?"); $update_adminuser_h->execute($passwd ,$admin ,$user,$host_group); print header(-Location=>"$script?action=saved&user=$user"); exit (0); } else { $error{'user'} = "Bad Password (e.g. password was too easy to guess)"; } } } else { if (param('password') eq param('password1')) { if ( check($password,$CRACKLIB)) { $passwd=crypt($password,$salt); $update_user_h = $db->prepare("update user_info set user_passwd = ? where user_name = ? and host_group = ?"); $update_user_h->execute($passwd,$user,$host_group); print header(-Location=>"$script?action=saved&user=$user"); exit (0); } else { $error{'user'} = "Bad Password (e.g. password was too easy to guess)"; } } else { $error{'user'} = "Password missmatch"; } } } elsif ($doit eq 'adduser') { if (!user_exists($user)) { # be sure, the username is something usefull if ( $user =~ /[a-z0-9\-_]+/i ) { if ( check($password,$CRACKLIB)) { $passwd = crypt($password,$salt); $isadmin = (param('isadmin')==1)+0; $add_user_h = $db->prepare ("insert into user_info(user_name,user_passwd,isadmin,host_group,changed,created) values (?,?,?,?,now(),now())"); $add_user_h->execute($user,$passwd,$isadmin,$host_group); print header(-Location=>"$script?action=added&user=$user"); exit(0); } else { $error{'user'} = "Bad Password (e.g. password was too easy to guess)"; } } else { $error{'user'} = "Bad username"; } } else { $error{'adduser'} = "User \"$user\" exists"; } } elsif ( $doit eq 'savegroup') { $delete_group_h = $db->prepare("delete from user_group where user_group = ? and host_group = ?"); $insert_group_h = $db->prepare("insert into user_group(user_name,user_group,host_group,changed,created) values (?,?,?,now(),now())"); $group = param('group'); @member = param('member'); $db->do('begin'); $db->do('lock tables user_group write'); $delete_group_h->execute($group,$host_group); for ($i=0;$i<=$#member;$i++) { $insert_group_h->execute($member[$i],$group,$host_group); } $db->do('unlock tables'); $db->do('commit'); print header(-Location=>"$script?action=grouplist"); exit(0); } elsif ( $doit eq 'addgroup') { $insert_group_h = $db->prepare("insert into user_group(user_name,user_group,host_group,changed,created) values (?,?,?,now(),now())"); $group = param('group'); @member = param('member'); if ( $group =~ /[a-z0-9\-_]+/i ) { if ( ! group_exist($group)) { for ($i=0;$i<=$#member;$i++) { $insert_group_h->execute($member[$i],$group,$host_group); } print header(-Location=>"$script?action=grouplist"); exit(0); } else { $error{'addgroup'} = "Group \"$group\" exists"; } } else { $error{'addgroup'} = "Group \"$group\" is not allowed (wrong name)"; } } } print header; print start_html(-title=>"Manage htpasswd entries for the site http://$server/", -style=>{-src=>"http://$server_ip/htpasswd/styles/htpasswd.css"}); print h3("Manage htpasswd entries for the site http://$server/"); print p,"You're logged in as user \"$master_user\"."; # [ ",a({-href=>"http://$server$script?logout=true&bye=$master_user"},"logout"),"]"; if (param) { @action = param('action'); if (defined (@action)) { for ($i=0;$i<=$#action;$i++) { if ($action[$i] eq 'list' ) { print p,b("List user"); if ( is_admin($master_user) ) { $user_h->execute($host_group); #print p,$user_h->rows," found"; while (($user,$isadmin) = $user_h->fetchrow) { print br; if ($isadmin > 0 ) { print img{src=>"http://$server_ip/htpasswd/star.gif",alt=>"admin"}; } else { print img{src=>"http://$server_ip/htpasswd/empty.gif",alt=>""}; } print " ",link_user($user); } } else { print br,b("Sorry, but only administrators can see all users"); } } if ($action[$i] eq 'add' ) { print p,b("Add user"); if ( is_admin($master_user) ) { print start_form(-method=>"post",-action=>"$script"); if ($error{'adduser'}) { print span({-class=>'error'},$error{'adduser'}),p; } print input({-type=>'hidden',-name=>'action',-value=>'add'}), input({-type=>'hidden',-name=>'doit',-value=>'adduser'}), "new username",br,input({-name=>'user',-type=>'text',-size=>30,-maxlength=>30,-value=>$user}), br,"password",br,input({-name=>'password',-type=>'text',-size=>12,-maxlength=>12}), br,checkbox(-name=>'admin',-checked=>0,-value=>1,-label=>"user is an administrator"), p,submit({-class=>'center',-value=>'add user now'}),end_form; if ( $error{'adduser'} ) { $user = undef; } } else { print br,b("Sorry, but only administrators can add users"); } } if ($action[$i] eq 'grouplist' ) { print p,b("List groups"); if ( is_admin($master_user) ) { $group_h = $db->prepare("select user_group,user_name from user_group,host_info where user_group.host_group=host_info.host_group and host=? order by user_group,user_name"); $group_h->execute($server); $old_group=""; while (($group,$user) = $group_h->fetchrow) { if ($old_group ne $group) { print br,a({href=>"$script?group=$group"},$group),b("» "), link_user($user); $old_group=$group; } else { print ", ",link_user($user); } } } else { print br,b("Sorry, but only administrators can see all groups"); } } if ($action[$i] eq 'groupadd' ) { if ( is_admin($master_user) ) { print p,b("Add a new group"); $user_h->execute($host_group); $k=0; @user_list=undef; while ( ($user,$isadmin) = $user_h->fetchrow) { if ( $user ne "" ) { $user_list[$k++] = $user; } } print start_form(-method=>"post",-action=>"$script"), input({-type=>'hidden',-name=>'doit',-value=>'savegroup'}), b("Groupname:"),br, input({-type=>'text',-name=>'group',-value=>"$group"}), p,scrolling_list({-name=>'member',-values=>\@user_list, -default=>'',-multiple=>true}), p,submit({-class=>'center',-value=>'change now'}),end_form; } else { print p,b("Sorry, but only administrators can add groups"); } } if ($action[$i] eq 'saved' ) { print p,b,"Modify user \"$user\"", p,"Settings of user ",link_user($user)," are changed"; $user=undef; } if ($action[$i] eq 'added' ) { print p,b,"Add user \"$user\"", p,"User ",link_user($user)," added"; $user=undef; } if ($action[$i] eq 'deleted' ) { print p,b,"Delete user \"$user\"", p,"User $user deleted."; $user=undef; } } } if ( $user ne "" ) { print p,b("Modify user \"$user\""); if ( $error{'user'} ) { print p,span({-class=>'error'},$error{'user'}),p; } if ( $user eq $master_user || is_admin($master_user) ) { print start_form(-method=>"post",-action=>"$script"), input({-type=>'hidden',-name=>'user',-value=>"$user"}), input({-type=>'hidden',-name=>'doit',-value=>"saveuser"}); if (is_admin($master_user)) { print b($user),"\'s new password:",br,input({-name=>'password',-type=>'text',-size=>12,-maxlength=>12}), br,checkbox(-name=>'admin',-checked=>is_admin($user),-value=>1,-label=>"user is an administrator"); if ( $user ne $domain && $user ne $master_user ) { # don't delet master user! print br,checkbox(-name=>'delete',-checked=>0,-value=>1,-label=>"Delete user"); } else { print br, sprintf ("I'll not delete %s", $user eq $domain ? "the master user" : "myself"); } } else { print "Please type your new password:",br,input({-name=>'password',-type=>'password',-size=>12,-maxlength=>12}); print br,"Please type your new password again:",br,input({-name=>'password1',-type=>'password',-size=>12,-maxlength=>12}); } print p,submit({-class=>'center',-value=>'change now'}),end_form; } else { print br,b("Sorry, but only administrators can change other users"); } } $group=param('group'); if ( $group ne "" ) { print p,b("Modify group \"$group\""); if ( $user eq $master_user || is_admin($master_user) ) { print p,"Please select the members of the group",br,"if there are no members, the group will be deleted."; $user_h->execute($host_group); $j=0; while ( ($user,$isadmin) = $user_h->fetchrow) { $user_list[$k++] = $user; if (user_member($user,$group)) { $user_sel[$j++] = $user; } } print start_form(-method=>"post",-action=>"$script"), input({-type=>'hidden',-name=>'group',-value=>"$group"}), input({-type=>'hidden',-name=>'doit',-value=>'savegroup'}), p,scrolling_list({-name=>'member',-values=>\@user_list, -default=>\@user_sel,-multiple=>true}), p,submit({-class=>'center',-value=>'change now'}),end_form; } else { print br,b("Sorry, but only administrators can change group members"); } } } else { $label{'list'} = 'list all user'; $label{'add'} = 'add a user'; $label{'grouplist'} = 'list all groups'; $label{'groupadd'} = 'add a group'; print p,b("Do following:"), br; # print list, group, add only if you are an administrator if (is_admin($master_user) ) { print start_form, checkbox_group(-name=>'action', -values=>['list','add','grouplist','groupadd'], -defaults=>['list'], -linebreak=>'true', -labels=>\%label), p, submit('Do it now'), end_form; } else { print a({href=>"$script?user=$master_user"},"change password"); } } print hr({-width=>400,-align=>'left',-size=>1,-noshade}), "[ ",a({-href=>'/'},$server),"]   ", "[ ",a({href=>$script},"Manage htpasswd"),"]", hr({-width=>400,-align=>'left',-size=>1,-noshade}), span({-class=>'copy'},"© 2003 by ueli(at)heuer.org"); print end_html; # check if $user is a domainadmin or not # return true if $user is an admin sub is_admin { local ($user,$dummy) = @_; $is_master_h->execute($server,$user); ($is_admin) = $is_master_h->fetchrow; return ($is_admin == 1); } sub get_host_group { $get_host_group_h = $db->prepare("select host_group from host_info where host = ?"); $get_host_group_h->execute($server); ($host_group) = $get_host_group_h->fetchrow; return $host_group; } sub get_password { local ($user,$dummy) = @_; $get_password_h->execute($server,$user); ($crypt_pw) = $get_password_h->fetchrow; return $crypt_pw; } sub link_user { local ($user,$dummy) = @_; if ( user_exists($user)) { return a({href=>"$script?user=$user"},$user); } else { return span({-class=>'error',-title=>"User does not exists"},$user); } } sub user_member { local ($user,$group,@dummy) = @_; $check_member_h->execute ($user,$group,$host_group); return ($check_member_h->rows > 0); } sub user_exists { local ($user,$dummy) = @_; $check_user_h->execute($user,$host_group); return ($check_user_h->rows > 0); } sub get_servername { # da apache2 server_name falsch (?) zurückliefert, bleibt nur der weg via configdatei # eventuell sieht das dann mit mod_perl etwas anderst aus ... local ($ser,$dummy) = @_; open CONF, "< $SERVER_CONF"; while () { next if /\s*#/; next if (! /; next if /\s*#/; if (/ServerName\s+([\w\.\-]*)\s*/i ) { $hostname = $1; $hostname =~ /^([a-z0-9\-]*)\.([a-z0-9\-]*\.[a-z]{2,4})$/; $host = $1; $domain = $2; } if (/ServerAlias/i ) { if (/\s+$ser\s*/i ) { $found = 1==1; } } } if (( $hostname =~ /$ser/i ) || $found ) { close CONF; return ($hostname,$domain); } } close CONF; return (undef,undef); }