home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / File / Passwd / Smb.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  13.0 KB  |  427 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * File::Passwd::Smb
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  10.  * that is available through the world-wide-web at the following URI:
  11.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  12.  * the PHP License and are unable to obtain it through the web, please
  13.  * send a note to license@php.net so we can mail you a copy immediately.
  14.  *
  15.  * @category   FileFormats
  16.  * @package    File_Passwd
  17.  * @author     Michael Wallner <mike@php.net>
  18.  * @author     Michael Bretterklieber <michael@bretterklieber.com>
  19.  * @copyright  2003-2005 Michael Wallner
  20.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  21.  * @version    CVS: $Id: Smb.php,v 1.18 2005/05/06 10:22:48 mike Exp $
  22.  * @link       http://pear.php.net/package/File_Passwd
  23.  */
  24.  
  25. /**
  26. * Requires File::Passwd::Common
  27. */
  28. require_once 'File/Passwd/Common.php';
  29.  
  30. /**
  31. * Requires Crypt::CHAP
  32. */
  33. require_once 'Crypt/CHAP.php';
  34.  
  35. /**
  36. * Manipulate SMB server passwd files.
  37. *
  38. * # Usage Example 1 (modifying existing file):
  39. * <code>
  40. * $f = &File_Passwd::factory('SMB');
  41. * $f->setFile('./smbpasswd');
  42. * $f->load();
  43. * $f->addUser('sepp3', 'MyPw', array('userid' => 12));
  44. * $f->changePasswd('sepp', 'MyPw');
  45. * $f->delUser('karli');
  46. * foreach($f->listUser() as $user => $data) {
  47. *   echo $user . ':' . implode(':', $data) ."\n";
  48. * }
  49. * $f->save();
  50. * </code>
  51. * # Usage Example 2 (creating a new file):
  52. * <code>
  53. * $f = &File_Passwd::factory('SMB');
  54. * $f->setFile('./smbpasswd');
  55. * $f->addUser('sepp1', 'MyPw', array('userid'=> 12));
  56. * $f->addUser('sepp3', 'MyPw', array('userid' => 1000));
  57. * $f->save();
  58. * </code>
  59. * # Usage Example 3 (authentication):
  60. * <code>
  61. * $f = &File_Passwd::factory('SMB');
  62. * $f->setFile('./smbpasswd');
  63. * $f->load();
  64. * if (true === $f->verifyPasswd('sepp', 'MyPw')) {
  65. *     echo "User valid";
  66. * } else {
  67. *     echo "User invalid or disabled";
  68. * }
  69. * </code>
  70. * @author   Michael Bretterklieber <michael@bretterklieber.com>
  71. * @author   Michael Wallner <mike@php.net>
  72. * @package  File_Passwd
  73. * @version  $Revision: 1.18 $
  74. * @access   public
  75. */
  76. class File_Passwd_Smb extends File_Passwd_Common
  77. {
  78.     /**
  79.     * Object which generates the NT-Hash and LAN-Manager-Hash passwds
  80.     * 
  81.     * @access protected
  82.     * @var object
  83.     */
  84.     var $msc;
  85.  
  86.     /**
  87.     * Constructor
  88.     *
  89.     * @access public
  90.     * @param  string $file  SMB passwd file
  91.     */
  92.     function File_Passwd_Smb($file = 'smbpasswd')
  93.     {
  94.         File_Passwd_Smb::__construct($file);
  95.     }
  96.     
  97.     /**
  98.     * Constructor (ZE2)
  99.     * 
  100.     * Rewritten because we want to init our crypt engine.
  101.     *
  102.     * @access public
  103.     * @param  string $file  SMB passwd file
  104.     */
  105.     function __construct($file = 'smbpasswd')
  106.     {
  107.         $this->setFile($file);
  108.         $this->msc = &new Crypt_CHAP_MSv1;
  109.     }     
  110.     
  111.     /**
  112.     * Fast authentication of a certain user
  113.     * 
  114.     * Returns a PEAR_Error if:
  115.     *   o file doesn't exist
  116.     *   o file couldn't be opened in read mode
  117.     *   o file couldn't be locked exclusively
  118.     *   o file couldn't be unlocked (only if auth fails)
  119.     *   o file couldn't be closed (only if auth fails)
  120.     *   o invalid encryption method <var>$nt_or_lm</var> was provided
  121.     *
  122.     * @static   call this method statically for a reasonable fast authentication
  123.     * @access   public
  124.     * @return   mixed   true if authenticated, false if not or PEAR_Error
  125.     * @param    string  $file       path to passwd file
  126.     * @param    string  $user       user to authenticate
  127.     * @param    string  $pass       plaintext password
  128.     * @param    string  $nt_or_lm   encryption mode to use (NT or LM hash)
  129.     */
  130.     function staticAuth($file, $user, $pass, $nt_or_lm = 'nt')
  131.     {
  132.         $line = File_Passwd_Common::_auth($file, $user);
  133.         if (!$line || PEAR::isError($line)) {
  134.             return $line;
  135.         }
  136.         @list(,,$lm,$nt) = explode(':', $line);
  137.         $chap            = &new Crypt_CHAP_MSv1;
  138.         
  139.         switch(strToLower($nt_or_lm)){
  140.             case FILE_PASSWD_NT: 
  141.                 $real       = $nt; 
  142.                 $crypted    = $chap->ntPasswordHash($pass); 
  143.                 break;
  144.             case FILE_PASSWD_LM: 
  145.                 $real       = $lm;
  146.                 $crypted    = $chap->lmPasswordHash($pass); 
  147.                 break;
  148.             default:
  149.                 return PEAR::raiseError(
  150.                     sprintf(FILE_PASSWD_E_INVALID_ENC_MODE_STR, $nt_or_lm),
  151.                     FILE_PASSWD_E_INVALID_ENC_MODE
  152.                 );
  153.         }
  154.         return (strToUpper(bin2hex($crypted)) === $real);
  155.     }
  156.     
  157.     /**
  158.     * Parse smbpasswd file
  159.     *
  160.     * Returns a PEAR_Error if passwd file has invalid format.
  161.     * 
  162.     * @access public
  163.     * @return mixed   true on success or PEAR_Error
  164.     */    
  165.     function parse()
  166.     {
  167.         foreach ($this->_contents as $line){
  168.             $info = explode(':', $line);
  169.             if (count($info) < 4) {
  170.                 return PEAR::raiseError(
  171.                     FILE_PASSWD_E_INVALID_FORMAT_STR,
  172.                     FILE_PASSWD_E_INVALID_FORMAT
  173.                 );
  174.             }
  175.             $user = array_shift($info);
  176.             if (!empty($user)) {
  177.                 array_walk($info, 'trim');
  178.                 $this->_users[$user] = @array(
  179.                     'userid'    => $info[0],
  180.                     'lmhash'    => $info[1],
  181.                     'nthash'    => $info[2],
  182.                     'flags'     => $info[3],
  183.                     'lct'       => $info[4],
  184.                     'comment'   => $info[5]
  185.                 );
  186.             }
  187.         }
  188.         $this->_contents = array();
  189.         return true; 
  190.     }
  191.     
  192.     /**
  193.     * Add a user
  194.     *
  195.     * Returns a PEAR_Error if:
  196.     *   o user already exists
  197.     *   o user contains illegal characters
  198.     *
  199.     * @throws PEAR_Error
  200.     * @return mixed true on success or PEAR_Error
  201.     * @access public
  202.     * @param  string    $user       the user to add
  203.     * @param  string    $pass       the new plaintext password
  204.     * @param  array     $params     additional properties of user
  205.     *                                + userid
  206.     *                                + comment
  207.     * @param  boolean   $isMachine  whether to add an machine account
  208.     */
  209.     function addUser($user, $pass, $params, $isMachine = false)
  210.     {
  211.         if ($this->userExists($user)) {
  212.             return PEAR::raiseError(
  213.                 sprintf(FILE_PASSWD_E_EXISTS_ALREADY_STR, 'User ', $user),
  214.                 FILE_PASSWD_E_EXISTS_ALREADY
  215.             );
  216.         }
  217.         if (!preg_match($this->_pcre, $user)) {
  218.             return PEAR::raiseError(
  219.                 sprintf(FILE_PASSWD_E_INVALID_CHARS_STR, 'User ', $user),
  220.                 FILE_PASSWD_E_INVALID_CHARS
  221.             );
  222.         }
  223.         if ($isMachine) {
  224.             $flags = '[W          ]';
  225.             $user .= '$';
  226.         } else {
  227.             $flags = '[U          ]';
  228.         }
  229.         $this->_users[$user] = array(
  230.             'flags'     => $flags,
  231.             'userid'    => (int)@$params['userid'],
  232.             'comment'   => trim(@$params['comment']),
  233.             'lct'       => 'LCT-' . strToUpper(dechex(time()))
  234.         );
  235.         return $this->changePasswd($user, $pass);
  236.     }
  237.  
  238.     /**
  239.     * Modify a certain user
  240.     * 
  241.     * <b>You should not modify the password with this method 
  242.     * unless it is already encrypted as nthash and lmhash!</b>
  243.     *
  244.     * Returns a PEAR_Error if:
  245.     *   o user doesn't exist
  246.     *   o an invalid property was supplied
  247.     * 
  248.     * @throws PEAR_Error
  249.     * @access public
  250.     * @return mixed true on success or PEAR_Error
  251.     * @param  string    $user   the user to modify
  252.     * @param  array     $params an associative array of properties to change
  253.     */
  254.     function modUser($user, $params)
  255.     {
  256.         if (!$this->userExists($user)) {
  257.             return PEAR::raiseError(
  258.                 sprintf(FILE_PASSWD_E_EXISTS_NOT_STR, 'User ', $user),
  259.                 FILE_PASSWD_E_EXISTS_NOT
  260.             );
  261.         }
  262.         if (!preg_match($this->_pcre, $user)) {
  263.             return PEAR::raiseError(
  264.                 sprintf(FILE_PASSWD_E_INVALID_CHARS_STR, 'User ', $user),
  265.                 FILE_PASSWD_E_INVALID_CHARS
  266.             );
  267.         }
  268.         foreach ($params as $key => $value){
  269.             $key = strToLower($key);
  270.             if (!isset($this->_users[$user][$key])) {
  271.                 return PEAR::raiseError(
  272.                     sprintf(FILE_PASSWD_E_INVALID_PROPERTY_STR, $key),
  273.                     FILE_PASSWD_E_INVALID_PROPERTY
  274.                 );
  275.             }
  276.             $this->_users[$user][$key] = trim($value);
  277.             $this->_users[$user]['lct']= 'LCT-' . strToUpper(dechex(time()));
  278.         }
  279.         return true;
  280.     }
  281.  
  282.     /**
  283.     * Change the passwd of a certain user
  284.     *
  285.     * Returns a PEAR_Error if <var>$user</var> doesn't exist.
  286.     * 
  287.     * @throws PEAR_Error
  288.     * @access public
  289.     * @return mixed true on success or PEAR_Error
  290.     * @param  string    $user   the user whose passwd should be changed
  291.     * @param  string    $pass   the new plaintext passwd
  292.     */
  293.     function changePasswd($user, $pass)
  294.     {
  295.         if (!$this->userExists($user)) {
  296.             return PEAR::raiseError(
  297.                 sprintf(FILE_PASSWD_E_EXISTS_NOT_STR, 'User ', $user),
  298.                 FILE_PASSWD_E_EXISTS_NOT
  299.             );
  300.         }
  301.         if (empty($pass)) {
  302.             $nthash = $lmhash = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
  303.         } else {
  304.             $nthash = strToUpper(bin2hex($this->msc->ntPasswordHash($pass)));
  305.             $lmhash = strToUpper(bin2hex($this->msc->lmPasswordHash($pass)));
  306.         }
  307.         $this->_users[$user]['nthash'] = $nthash;
  308.         $this->_users[$user]['lmhash'] = $lmhash;
  309.         return true;
  310.     }
  311.     
  312.     /**
  313.     * Verifies a user's password
  314.     * 
  315.     * Prefer NT-Hash instead of weak LAN-Manager-Hash
  316.     *
  317.     * Returns a PEAR_Error if:
  318.     *   o user doesn't exist
  319.     *   o user is disabled
  320.     *
  321.     * @return mixed true if passwds equal, false if they don't or PEAR_Error
  322.     * @access public        
  323.     * @param string $user       username
  324.     * @param string $nthash     NT-Hash in hex
  325.     * @param string $lmhash     LAN-Manager-Hash in hex
  326.     */
  327.     function verifyEncryptedPasswd($user, $nthash, $lmhash = '')
  328.     {
  329.         if (!$this->userExists($user)) {
  330.             return PEAR::raiseError(
  331.                 sprintf(FILE_PASSWD_E_EXISTS_NOT_STR, 'User ', $user),
  332.                 FILE_PASSWD_E_EXISTS_NOT
  333.             );
  334.         }
  335.         if (strstr($this->_users[$user]['flags'], 'D')) {
  336.             return PEAR::raiseError("User '$user' is disabled.", 0);
  337.         }
  338.         if (!empty($nthash)) {
  339.             return $this->_users[$user]['nthash'] === strToUpper($nthash);
  340.         }
  341.         if (!empty($lmhash)) {
  342.             return $this->_users[$user]['lm'] === strToUpper($lmhash);
  343.         }
  344.         return false;
  345.     }
  346.  
  347.     /**
  348.     * Verifies an account with the given plaintext password
  349.     *
  350.     * Returns a PEAR_Error if:
  351.     *   o user doesn't exist
  352.     *   o user is disabled
  353.     *
  354.     * @throws PEAR_Error
  355.     * @return mixed     true if passwds equal, false if they don't or PEAR_Error
  356.     * @access public        
  357.     * @param  string    $user username
  358.     * @param  string    $pass the plaintext password
  359.     */
  360.     function verifyPasswd($user, $pass)
  361.     {
  362.         $nthash = bin2hex($this->msc->ntPasswordHash($pass));
  363.         $lmhash = bin2hex($this->msc->lmPasswordHash($pass));
  364.         return $this->verifyEncryptedPasswd($user, $nthash, $lmhash);
  365.     }
  366.  
  367.     /**
  368.     * Apply changes and rewrite CVS passwd file
  369.     *
  370.     * Returns a PEAR_Error if:
  371.     *   o directory in which the file should reside couldn't be created
  372.     *   o file couldn't be opened in write mode
  373.     *   o file couldn't be locked exclusively
  374.     *   o file couldn't be unlocked
  375.     *   o file couldn't be closed
  376.     * 
  377.     * @throws PEAR_Error
  378.     * @access public
  379.     * @return mixed true on success or PEAR_Error
  380.     */
  381.     function save()
  382.     {
  383.         $content = '';
  384.         foreach ($this->_users as $user => $userdata) {
  385.             $content .= $user . ':' .
  386.                         $userdata['userid'] . ':' .
  387.                         $userdata['lmhash'] . ':' .
  388.                         $userdata['nthash'] . ':' .
  389.                         $userdata['flags']  . ':' .
  390.                         $userdata['lct']    . ':' .
  391.                         $userdata['comment']. "\n";
  392.         }
  393.         return $this->_save($content);
  394.     }
  395.     
  396.     /**
  397.     * Generate Password
  398.     *
  399.     * @static
  400.     * @access   public
  401.     * @return   string  The crypted password.
  402.     * @param    string  $pass The plaintext password.
  403.     * @param    string  $mode The encryption mode to use (nt|lm).
  404.     */
  405.     function generatePasswd($pass, $mode = 'nt')
  406.     {
  407.         $chap = &new Crypt_CHAP_MSv1;
  408.         $hash = strToLower($mode) == 'nt' ? 
  409.             $chap->ntPasswordHash($pass) :
  410.             $chap->lmPasswordHash($pass);
  411.         return strToUpper(bin2hex($hash));
  412.     }
  413.     
  414.     /**
  415.      * @ignore
  416.      * @deprecated
  417.      */
  418.     function generatePassword($pass, $mode = 'nt')
  419.     {
  420.         return File_Passwd_Smb::generatePasswd($pass, $mode);
  421.     }
  422. }
  423. ?>
  424.