<?php
// Ready to use interface script to be called by PbP to control access to your content. Adds and
// removes users who registrate via PbP pinaccess. Your own parameters are passed via pinaccess
// to this script.
// This code comes without any warranty.

// Requires: 1) htaccess enabled via httpd and an htaccess file in your contents directory
//              linked to the htpasswd file.
//           2) executable passwd binary if you choose the "sys" encryption method (see below)
//              which should be default.

// If you plan to integrate the PbP users into your own user administration then you can use
// this script to exploit the interface.
//                                                  last revision *fa Jul 30 18:18:58 UTC 2005

//---------------------------- uncomment this for test in command line ----------------------
//$_REQUEST=array('username'=>$argv[1],'password'=>$argv[2],'mode'=>$argv[3]);
//foreach($_REQUEST as $k=>$v){print "$k=$v\n";}

//---------------------------- restrict access to PbP sites ----------------------
$Hosts_allowed=array('213.189.25.132','213.189.25.133','213.189.25.134','213.189.25.135','213.189.25.136','213.189.25.140');
if (!in_array($_SERVER['REMOTE_ADDR'],$Hosts_allowed)) exit();

//---------------------------- configure ------------------------------
// encryption method. 'crypt' and 'md5' if you got no system exec rights or cannot fork
// or the htpasswd binary cannot be run under your php due to other problems.
// if you can run the htpasswd binary choose 'sys' as most secure choice..

//$encMethod='crypt';     // des encryption (traditional)
$encMethod='md5';      // md5 encryption
//$encMethod='sys';      // use htpasswd prog (must be executable and fork must be enabled)
//$encMethod='plain';    // plain text (should be used for test only)

// parameter names (interface to PbP). If you change the values, please report to PbP support
$myParamNames=array('name_of_user_param'=>'username',  // may be changed
                    'password_param'    =>'password',  // may be changed
                    'mode_param'        =>'mode');     // may not be changed

// path and name of htpasswd file (only used if encryption method is 'sys')
$passwdFile="/tmp/.htpasswd";
$passwdcmd ='htpasswd';

?><pre><?
//--------------------------- check params
$retArray= checkParams($myParamNames);
if($retArray['state']=='error') terminate_script($retArray);

//--------------------------- the stuff
//--------------- check passwd file
if(!file_exists($passwdFile)) {
  $fp = @fopen($passwdFile, "w");
  if($fp) fclose($fp);
  else    terminate_script(array('state'=>'error','error'=>'unable2create'));
}elseif(!is_writeable($passwdFile)){
  terminate_script(array('state'=>'error','error'=>'not_writable'));
}

if($encMethod!='sys'){
  // encrypt methods crypt, md5, plain
    if     ($encMethod=='crypt'){
      $encrypted_pw=crypt($_REQUEST[$myParamNames['password_param']],rand(10,99));
    }elseif($encMethod=='md5'){
      $encrypted_pw=crypt($_REQUEST[$myParamNames['password_param']],'$1$pbpxjuly');
    }elseif($encMethod=='plain'){
      $encrypted_pw=      $_REQUEST[$myParamNames['password_param']];
    }

    // add(update), remove user
    // warning: there is no perfect locking available in php, so use this code under reserve  
    $file=file($passwdFile);
    $lines = count($file);
    $fp   =fopen($passwdFile,'w');
    flock($fp,LOCK_EX);
    for($i=0; $i<$lines; $i++){
      $account=explode(':',$file[$i]);
      if   ($account[0]!=$_REQUEST[$myParamNames['name_of_user_param']]) fwrite($fp, $file[$i]);
    }
    if($_REQUEST[$myParamNames['mode_param']]=='add')
       fwrite($fp, $_REQUEST[$myParamNames['name_of_user_param']].":$encrypted_pw\n");
    flock($fp,LOCK_UN);
    fclose($fp);

}else{
  // encrypt method sys, using the htpasswd binary
  $cmd="$passwdcmd -b"
       .' '  .($_REQUEST[$myParamNames['mode_param']]=='remove'?'-D':'')
       .' '  .$passwdFile
       ." '" .$_REQUEST[$myParamNames['name_of_user_param']]
       ."' '".$_REQUEST[$myParamNames['password_param']]."'";
  print $cmd."\n".`$cmd 2>&1`."\n";
}

terminate_script(array('state'=>'ok'));
exit();

function checkParams($P){
  $e=array();
  foreach($P as $k=>$v){
    if(empty($_REQUEST[$v])) array_push($e,"$v:missing");
  }
  if($e[0]) return(array('state'=>'error','error'=>implode("; ", $e)));
  else      return(array('state'=>'ok'));
}

function terminate_script($E){
  foreach($E as $k=>$v) print "$k=$v\n";
  exit();
}

?>