2011-12-19 16 views
12

मैं कुछ उपयोगकर्ताओं को अपने एलडीएपी डीबी में जोड़ने की कोशिश कर रहा हूं लेकिन मुझे कुछ त्रुटियां (अमान्य डीएन वाक्यविन्यास) मिलती हैं जब मैं कुछ विशेष पात्रों जैसे ",।" का उपयोग करता हूं। मुझे एक ऐसे समारोह की ज़रूरत है जो सभी पात्रों से बचें। मैं preg_quote कोशिश करता हूं लेकिन मुझे कुछ मामलों में कुछ त्रुटियां मिलती हैं।PHP ldap_add फ़ंक्शन डीडी सिंटैक्स में ldap विशेष वर्णों से बचने के लिए

अग्रिम धन्यवाद

कोड:

$user = 'Test , Name S.L'; 

    if(!(ldap_add($ds, "cn=" . $user . ",".LDAP_DN_BASE, $info))) { 

      include 'error_new_account.php'; 

    } 

उत्तर

25

संपादित जनवरी 2013:, डीएन तार में अग्रणी/रिक्ति बचने RFC 4514 प्रति के लिए समर्थन जोड़ा। इस मुद्दे को इंगित करने के लिए Eugenio पर धन्यवाद।

EDIT 2014: I added this function to PHP 5.6। नीचे दिया गया कोड अब पहले के PHP संस्करणों के लिए एक तरह के ड्रॉप-इन प्रतिस्थापन है।

if (!function_exists('ldap_escape')) { 
    define('LDAP_ESCAPE_FILTER', 0x01); 
    define('LDAP_ESCAPE_DN',  0x02); 

    /** 
    * @param string $subject The subject string 
    * @param string $ignore Set of characters to leave untouched 
    * @param int $flags Any combination of LDAP_ESCAPE_* flags to indicate the 
    *     set(s) of characters to escape. 
    * @return string 
    */ 
    function ldap_escape($subject, $ignore = '', $flags = 0) 
    { 
     static $charMaps = array(
      LDAP_ESCAPE_FILTER => array('\\', '*', '(', ')', "\x00"), 
      LDAP_ESCAPE_DN  => array('\\', ',', '=', '+', '<', '>', ';', '"', '#'), 
     ); 

     // Pre-process the char maps on first call 
     if (!isset($charMaps[0])) { 
      $charMaps[0] = array(); 
      for ($i = 0; $i < 256; $i++) { 
       $charMaps[0][chr($i)] = sprintf('\\%02x', $i);; 
      } 

      for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_FILTER]); $i < $l; $i++) { 
       $chr = $charMaps[LDAP_ESCAPE_FILTER][$i]; 
       unset($charMaps[LDAP_ESCAPE_FILTER][$i]); 
       $charMaps[LDAP_ESCAPE_FILTER][$chr] = $charMaps[0][$chr]; 
      } 

      for ($i = 0, $l = count($charMaps[LDAP_ESCAPE_DN]); $i < $l; $i++) { 
       $chr = $charMaps[LDAP_ESCAPE_DN][$i]; 
       unset($charMaps[LDAP_ESCAPE_DN][$i]); 
       $charMaps[LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr]; 
      } 
     } 

     // Create the base char map to escape 
     $flags = (int)$flags; 
     $charMap = array(); 
     if ($flags & LDAP_ESCAPE_FILTER) { 
      $charMap += $charMaps[LDAP_ESCAPE_FILTER]; 
     } 
     if ($flags & LDAP_ESCAPE_DN) { 
      $charMap += $charMaps[LDAP_ESCAPE_DN]; 
     } 
     if (!$charMap) { 
      $charMap = $charMaps[0]; 
     } 

     // Remove any chars to ignore from the list 
     $ignore = (string)$ignore; 
     for ($i = 0, $l = strlen($ignore); $i < $l; $i++) { 
      unset($charMap[$ignore[$i]]); 
     } 

     // Do the main replacement 
     $result = strtr($subject, $charMap); 

     // Encode leading/trailing spaces if LDAP_ESCAPE_DN is passed 
     if ($flags & LDAP_ESCAPE_DN) { 
      if ($result[0] === ' ') { 
       $result = '\\20' . substr($result, 1); 
      } 
      if ($result[strlen($result) - 1] === ' ') { 
       $result = substr($result, 0, -1) . '\\20'; 
      } 
     } 

     return $result; 
    } 
} 

तो आप क्या करेंगे:

$user = 'Test , Name S.L'; 
$cn = ldap_escape($user, '', LDAP_ESCAPE_DN); 
if (!ldap_add($ds, "cn={$cn}," . LDAP_DN_BASE, $info)) { 
    include 'error_new_account.php'; 
} 
+0

आपको बहुत अच्छा काम है। – Sbml

+0

@daverandom आपको रिक्त स्थान से बचने के लिए वर्णों में जोड़ना चाहिए (यदि वे एक विशेषता मान के पहले या अंतिम अक्षर हैं), तो क्या मैं सही हूँ? इसके अलावा, # चिह्न से बच जाना चाहिए अगर यह एक विशेषता मान का पहला अक्षर है। http://www-03.ibm.com/systems/i/software/ldap/underdn.html – Eugenio

+0

@ यूजीनियो दिलचस्प, क्या आप जानते हैं कि यह मानक एलडीएपी या आईबीएम विशिष्ट है या नहीं?मैंने पहले कभी भी उन शर्तों को कभी नहीं देखा है। डीएपी/एलडीएपी मानकों के दस्तावेज़ बहुत लंबे और अत्यधिक अमूर्त हैं, इस तरह की जानकारी पर थोड़ा नट्स ढूंढना बहुत मुश्किल है - और मुझे इस समय फिर से अपने हाथों को रखने में कठिनाई हो रही है: एस – DaveRandom

1

उन पात्रों एक प्रतिष्ठित नाम या रिश्तेदार विशिष्ट नाम के डेटा का हिस्सा बनने के भाग निकले चाहिए। \2a जैसे बैकस्लैश 2 हेक्स अंकों के साथ चरित्र (सभी एलडीएपी में) से बचें। कुछ और मानक मानक दस्तावेजों के अनुपालन में नहीं होगा। प्रतिष्ठित नामों के स्ट्रिंग प्रतिनिधित्व के संबंध में अधिक विशिष्ट जानकारी के लिए RFC4514 देखें।

2

पीएचपी 5.6 बीटा हाल ही में ldap_escape() समारोह जारी किया गया है और यह है प्रभाव में, हालांकि, इस संस्करण नहीं उत्पादन वर्तमान में तैयार है, आप बहुत अब के रूप में अपने विकास प्रयोजनों के लिए उपयोग कर सकते हैं।

2

यदि आप अभी तक PHP 5.6 पर नहीं हैं तो बस एक सिर ऊपर, आप नीचे बनाई गई विधियों का उपयोग करके सटीक PHP 5.6 फ़ंक्शन ldap_escape() दर्पण कर सकते हैं, ध्यान रखें कि यह कक्षा में उपयोग के लिए है। उपर्युक्त उत्तर ldap_escape फ़ंक्शन की तरह बिल्कुल निष्पादित नहीं करता है, क्योंकि इसमें कोई वर्ण नहीं होने पर सभी वर्णों को हेक्स स्ट्रिंग में नहीं बचाया जाता है, इसलिए यह PHP के पुराने संस्करणों के प्रतिस्थापन में ड्रॉप के लिए अधिक उपयुक्त होगा, एक वस्तु उन्मुख तरीके से।

मैंने क्या किया है इस पर एक आसान समझ के लिए प्रत्येक पंक्ति को दस्तावेज किया है। आउटपुट के लिए नीचे स्क्रॉल करें।

तरीके (PHP 5 के साथ संगत या अधिक):

// Value to escape 
$value = 'testing=+<>"";:#()*\x00'; 

$php = ldap_escape($value, $ignore = '*'); 

$man = $this->escapeManual($value, $ignore = '*'); 

echo $php; // \74\65\73\74\69\6e\67\3d\2b\3c\3e\22\22\3b\3a\23\28\29*\5c\78\30\30 
echo $man; // \74\65\73\74\69\6e\67\3d\2b\3c\3e\22\22\3b\3a\23\28\29*\5c\78\30\30 


$php = ldap_escape($value, $ignore = '*', LDAP_ESCAPE_DN); 

$man = $this->escapeManual($value, $ignore = '*', LDAP_ESCAPE_DN); 

echo $php; // testing\3d\2b\3c\3e\22\22\3b:\23()*\5cx00 
echo $man; // testing\3d\2b\3c\3e\22\22\3b:\23()*\5cx00 


$php = ldap_escape($value, $ignore = '*', LDAP_ESCAPE_FILTER); 

$man = $this->escapeManual($value, $ignore = '*', LDAP_ESCAPE_FILTER); 

echo $php; // testing=+<>"";:#\28\29*\5cx00 
echo $man; // testing=+<>"";:#\28\29*\5cx00 

Github सार लिंक:

/** 
* Escapes the inserted value for LDAP. 
* 
* @param string $value The value to escape 
* @param string $ignore The characters to ignore 
* @param int $flags The PHP flag to use 
* 
* @return bool|string 
*/ 
public function escapeManual($value, $ignore = '*', $flags = 0) 
{ 
    /* 
    * If a flag was supplied, we'll send the value 
    * off to be escaped using the PHP flag values 
    * and return the result. 
    */ 
    if($flags) { 
     return $this->escapeWithFlags($value, $ignore, $flags); 
    } 

    // Convert ignore string into an array 
    $ignores = str_split($ignore); 

    // Convert the value to a hex string 
    $hex = bin2hex($value); 

    /* 
    * Separate the string, with the hex length of 2, 
    * and place a backslash on the end of each section 
    */ 
    $value = chunk_split($hex, 2, "\\"); 

    /* 
    * We'll append a backslash at the front of the string 
    * and remove the ending backslash of the string 
    */ 
    $value = "\\" . substr($value, 0, -1); 

    // Go through each character to ignore 
    foreach($ignores as $charToIgnore) 
    { 
     // Convert the characterToIgnore to a hex 
     $hexed = bin2hex($charToIgnore); 

     // Replace the hexed variant with the original character 
     $value = str_replace("\\" . $hexed, $charToIgnore, $value); 
    } 

    // Finally we can return the escaped value 
    return $value; 
} 

/** 
* Escapes the inserted value with flags. Supplying either 1 
* or 2 into the flags parameter will escape only certain values 
* 
* 
* @param string $value The value to escape 
* @param string $ignore The characters to ignore 
* @param int $flags The PHP flag to use 
* @return bool|string 
*/ 
public function escapeWithFlags($value, $ignore = '*', $flags = 0) 
{ 
    // Convert ignore string into an array 
    $ignores = str_split($ignore); 

    $escapeFilter = ['\\', '*', '(', ')']; 
    $escapeDn = ['\\', ',', '=', '+', '<', '>', ';', '"', '#']; 

    switch($flags) 
    { 
     case 1: 
      // Int 1 equals to LDAP_ESCAPE_FILTER 
      $escapes = $escapeFilter; 
      break; 
     case 2: 
      // Int 2 equals to LDAP_ESCAPE_DN 
      $escapes = $escapeDn; 
      break; 
     case 3: 
      // If both LDAP_ESCAPE_FILTER and LDAP_ESCAPE_DN are used 
      $escapes = array_merge($escapeFilter, $escapeDn); 
      break; 
     default: 
      // Customize your own default return value 
      return false; 
    } 

    foreach($escapes as $escape) 
    { 
     // Make sure the escaped value isn't inside the ignore array 
     if(! in_array($escape, $ignores)) 
     { 
      $hexed = chunk_split(bin2hex($escape), 2, "\\"); 

      $hexed = "\\" . substr($hexed, 0, -1); 

      $value = str_replace($escape, $hexed, $value); 
     } 
    } 

    return $value; 
} 

टेस्ट (ध्यान रखें कि LDAP_ESCAPE स्थिरांक पीएचपी 5.6 में ही उपलब्ध हैं हो) : https://gist.github.com/stevebauman/0db9b5daa414d60fc266

संबंधित मुद्दे