在Linux上实现SVN用户密码自助修改

1.首先本文是在一篇百度经验的基础上修改而成,将网址记录上,以示尊重。

https://jingyan.baidu.com/article/48b37f8dd4bbb31a646488c2.html

 

2.设计思想

SVN的用户密码都保存在一个密码文件中,SVN管理员通过调用htpasswd命令来实现用户密码的新增,修改。

自助用户修改的设计思想就是把这个密码文件修改方法公共给用户们使用; 具体的说,就是一个CGI网页来封装htpasswd修改用户命令,用户在网页上输入新用户密码后,CGI调用htpasswd命令来修改用户。

至于为什么要用CGI,哈哈,因为简单啊,Perl在Linux上原生就有,不用安装。

如果你熟PHP,那你就用PHP来封装,如果你熟JAVA那你就JAVA封装,原理都一样

最关键的那个命令:

/usr/bin/htpasswd -b $authuserfile $User $UserNewPwd

$authuserfile 密码文件所在路径,必须是绝对路径

$User 用户名

$UserNewPwd 用户新密码

 

2.安装Perl的CGI库

yum install perl-CGI

 

3.创建Cig配置文件

cd /var/www/cgi-bin

vi ChangePasswd.ini

[path]
authuserfile=/data/svn/conf/http_passwd
logfile=/var/www/cgi-bin/ChangePasswd.log
[setup]
pwdminlen=6
[html]
title=SVN Password Modification
description=SVN Password Modification
yourname=User Name
oldpwd=Old Password
newpwd1=New Password
newpwd2=Confirm New Password
btn_change=Modification
btn_reset=Reset

changepwdok=Password reset complete
changepwdfailed=Password modification failed
servererror=Server error, please contact the administrator
passmustgreater=The new password digit must be greater than 6 digits
twopassnotmatched=Two password entries must be the same
entername=Please enter your username
enterpwd=Please enter your password
errorpwd=Your password is incorrect
back=Back

4.创建CGI文件

注:我隐去了原有密码校验

cd /var/www/cgi-bin

vi ChangePasswd.cgi

#!/usr/bin/perl -w

use strict;

use CGI;

my $time        = localtime;

my $remote_id   = $ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR};

my $admin_email = $ENV{SERVER_ADMIN};

 

my $cgi = new CGI;

my $pwd_not_alldiginal = "PASSWD CAN'T BE ALL NUMBERS";

my $pwd_not_allchar = "PASSWD CAN'T BE ALL LETTERS";

my $user_not_exists ="USER DOES NOT EXIST";

my $file_not_found ="FILE DOES NOT EXIST,PLEASE CONTACT THE MANAGER";

 

my $authuserfile;

my $logfile;

my $pwdminlen;

my $title;

my $description;

my $yourname;

my $oldpwd;

my $newpwd1;

my $newpwd2;

my $btn_change;

my $btn_reset;

 

my $changepwdok;

my $changepwdfailed;

my $oldpwderror;

my $passmustgreater;

my $twopassnotmatched;

my $entername;

my $enterpwd;

my $errorpwd;

my $back;

 

&IniInfo;

 

if ($cgi -> param())

{#8

my $User = $cgi->param('UserName');

#my $UserPwd = $cgi->param('OldPwd');

my $UserNewPwd = $cgi->param('NewPwd1');

my $MatchNewPwd = $cgi->param('NewPwd2');

 

if (!$User)

     {&Writer_Log("Enter no user name");

       &otherhtml($title,$entername,$back);}

#elsif (!$UserPwd )

#    {&Writer_Log("Enter no OldPasswd");

#     &otherhtml($title,$enterpwd,$back); }

elsif (length($UserNewPwd)<$pwdminlen)

    {&Writer_Log("Password's length must greater than".$pwdminlen);

     &otherhtml($title,$passmustgreater.$pwdminlen,$back);}

else

{if($authuserfile)

{#6

open UserFile, "<$authuserfile" or die "open file failed.$!";

while (<UserFile>)

    {#5

       my $varstr=$_;

 

       if($varstr =~/($User)/)

    {#3

     my $eqpos =index($varstr, ":");

     my $UserName = substr($varstr,0,$eqpos);

     my $cryptpwd = substr($varstr,$eqpos + 1,13);

   

     next if($UserName ne $User);

       

     #if(crypt($UserPwd,$cryptpwd) eq $cryptpwd)
     if(1)

     {#a

      my $rc = system("/usr/bin/htpasswd -b $authuserfile $User $UserNewPwd");

      if ($rc == 0)

         {#1

            &Writer_Log( $User.".Change Passwd");

            &otherhtml($title,$changepwdok,$back);

          }#1

       else

          {#2

           &Writer_Log( $User.".Change Passwd Failed");

           &otherhtml($title,$changepwdfailed,$back);

          }#2

       exit;

     }#a

     else

     {#b

      &Writer_Log("Old Passwd is Incorrect ");

      &otherhtml($title,$errorpwd,$back);

     }#b

     exit;      

    }#3

       else

    {#4

     if(eof)

     { &Writer_Log($User.".no this user");

       &otherhtml($title,$user_not_exists,$back);

       exit;

     }

     else

     {next;}

    }#4  

     }#5

   close UserFile;

}#6

else

{#7

   &Writer_Log($authuserfile.".no found");

   &otherhtml($title,$file_not_found,$back);

}#7

}

}#8

else

{&Index_Html;}

 

sub IniInfo{

my $inifile = "/var/www/cgi-bin/ChangePasswd.ini";

open CGI_INI_FILE, "<$inifile" or die "open file failed.$!";;

while (<CGI_INI_FILE>)

{

my $eqpos =index($_,'=');

my $len = length($_);

 

if ($_ =~/authuserfile/)

{$authuserfile= substr($_, $eqpos + 1, $len - $eqpos -2);}

elsif ($_ =~/logfile/)

{$logfile= substr($_, $eqpos + 1);}

elsif ($_ =~/pwdminlen/)

{$pwdminlen= substr($_, $eqpos + 1);}

elsif ($_ =~/title/)

{$title = substr($_, $eqpos + 1);}

elsif ($_ =~/description/)

{$description = substr($_, $eqpos + 1);}

elsif ($_ =~/yourname/)

{$yourname = substr($_, $eqpos + 1);}

#elsif ($_ =~/oldpwd/)

#{$oldpwd= substr($_, $eqpos + 1);}

elsif ($_ =~/newpwd1/)

{$newpwd1= substr($_, $eqpos + 1);}

elsif ($_ =~/newpwd2/)

{$newpwd2= substr($_, $eqpos + 1);}

elsif ($_ =~/btn_change/)

{$btn_change = substr($_, $eqpos + 1);}

elsif ($_ =~/btn_reset/)

{$btn_reset = substr($_, $eqpos + 1);}

elsif ($_ =~/changepwdok/)

{$changepwdok = substr($_, $eqpos + 1);}

elsif ($_ =~/changepwdfailed/)

{$changepwdfailed = substr($_, $eqpos + 1);}

elsif ($_ =~/oldpwderror/)

{$oldpwderror = substr($_, $eqpos + 1);}

elsif ($_ =~/passmustgreater/)

{$passmustgreater = substr($_, $eqpos + 1);}

elsif ($_ =~/twopassnotmatched/)

{$twopassnotmatched = substr($_, $eqpos + 1);}

elsif ($_ =~/entername/)

{$entername = substr($_, $eqpos + 1);}

elsif ($_ =~/enterpwd/)

{$enterpwd= substr($_, $eqpos + 1);}

elsif ($_ =~/errorpwd/)

{$errorpwd= substr($_, $eqpos + 1);}

elsif ($_ =~/back/)

{$back = substr($_, $eqpos + 1);}

}

close CGI_INI_FILE;

}

 

sub Index_Html

{

print "Content-type: text/html\n\n";

print <<END_OF_PAGE;

<html >

<head>

<title>$title</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

</head>

<body>

 

<HR>

 

<center><h1>$description</h1>

</center>

<form method="POST" enctype="multipart/form-data" action="/cgi-bin/ChangePasswd.cgi">

<br>

<TABLE>

<TR><TD>$yourname</TD><TD><input type="text" name="UserName" /></TD></TR>

<TR><TD>$newpwd1</TD><TD><input type="password" name="NewPwd1" /></TD></TR>

<TR><TD>$newpwd2</TD><TD><input type="password" name="NewPwd2" /></TD></TR>

</TABLE>

<br>

<TABLE>

<TR><TD><input type="submit" name="chgpasswd" value="$btn_change"> <input type="reset" value="$btn_reset"></TD></TR>

</TABLE>

</form>

<HR>

<font color="#FF0000; charset=utf-8">WARNING:YOUR NEWPASSWD MUST MORE THAN $pwdminlen CHARACTERS.</font>

 

</body>

</html>

END_OF_PAGE

}

 

sub otherhtml{

print "Content-type: text/html\n\n";

 

print <<END_OF_PAGE;

<html>

<head>

<meta http-equiv="Content-Language" content="zh-cn">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>$_[0]</title>

</head>

 

<body>

<p><font size="5">$_[1]</font></p>

<p><a href="/cgi-bin/ChangePasswd.cgi"><font size="4">$_[2]</font></a></p>

 

<HR>

</body>

 

</html>

END_OF_PAGE

}

 

sub Writer_Log{

if($logfile)

{

my $loginfo ="[".$time."] "." [".$remote_id."] "." || ".$_[0];

open LOGFILE,">>$logfile" or die "Couldn't open LOG FILE for writing: $!";

print LOGFILE ("$loginfo\n");

close LOGFILE;

}

}

 

5.设置文件权限和建立日志文件

cd /var/www/cgi-bin

touch ChangePasswd.log

chmod 755 ChangePasswd.cgi

chmod 666 ChangePasswd.log

6.重启Httpd服务

service httpd restart

7.验证功能

http://<SVN服务器IP>/cgi-bin/ChangePasswd.cgi

 

8.问题解决

服务器防火墙要关闭

服务器SeLinux服务要关闭

 

enjoy :)

 

posted @ 2019-03-28 17:41  bigdog  阅读(4980)  评论(0编辑  收藏  举报