【问题标题】:PHP LDAP get user SIDPHP LDAP 获取用户 SID
【发布时间】:2016-09-16 14:07:39
【问题描述】:

我不知道如何在 AD 中获取用户唯一标识符 (SID)。代码片段:

...    
$filter="(&(samaccountname=".$this->username.")(memberOf:1.2.840.113556.1.4.1941:=CN=GROUP_NAME,OU=Security,DC=something,DC=something))";
    $attribute = array("cn","objectsid","description", "group", "member", "samaccountname");
    $sr=ldap_search($this->conn_ldap, $this->ldap_dn, $filter, $attribute);

    if ($sr) 
    {

    $this->info = ldap_get_entries($this->conn_ldap, $sr);
    if ($this->info["count"] == 1){

    ldap_close($this->conn_ldap);
    return true;
    }
    ... 

我可以通过以下方式获取信息:

echo $this->info[0]["cn"][0];

echo $this->info[0]["objectsid"][0];

在第一个输出中,我可以在第二个中看到用户名,例如 0�@�d^�WL7�U 我相信sid应该像S-......

【问题讨论】:

标签: php active-directory ldap


【解决方案1】:

我在另一个网站上找到了解决方案(见下文)。 基本上这个函数是转换器并使 SID 可见:

public static function SIDtoString($ADsid)
{
   $sid = "S-";
   //$ADguid = $info[0]['objectguid'][0];
   $sidinhex = str_split(bin2hex($ADsid), 2);
   // Byte 0 = Revision Level
   $sid = $sid.hexdec($sidinhex[0])."-";
   // Byte 1-7 = 48 Bit Authority
   $sid = $sid.hexdec($sidinhex[6].$sidinhex[5].$sidinhex[4].$sidinhex[3].$sidinhex[2].$sidinhex[1]);
   // Byte 8 count of sub authorities - Get number of sub-authorities
   $subauths = hexdec($sidinhex[7]);
   //Loop through Sub Authorities
   for($i = 0; $i < $subauths; $i++) {
      $start = 8 + (4 * $i);
      // X amount of 32Bit (4 Byte) Sub Authorities
      $sid = $sid."-".hexdec($sidinhex[$start+3].$sidinhex[$start+2].$sidinhex[$start+1].$sidinhex[$start]);
   }
   return $sid;
}

https://www.null-byte.org/development/php-active-directory-ldap-authentication/

【讨论】:

    【解决方案2】:

    是旧帖子,但我做了一些我觉得有用的组合,这个函数是二进制到 SID 转换的终极函数:

    // Binary to SID
    function bin_to_str_sid($binary_sid) {
    
        $sid = NULL;
        /* 64bt PHP */
        if(strlen(decbin(~0)) == 64)
        {
            // Get revision, indentifier, authority 
            $parts = unpack('Crev/x/nidhigh/Nidlow', $binary_sid);
            // Set revision, indentifier, authority 
            $sid = sprintf('S-%u-%d',  $parts['rev'], ($parts['idhigh']<<32) + $parts['idlow']);
            // Translate domain
            $parts = unpack('x8/V*', $binary_sid);
            // Append if parts exists
            if ($parts) $sid .= '-';
            // Join all
            $sid.= join('-', $parts);
        }
        /* 32bit PHP */
        else
        {   
            $sid = 'S-';
            $sidinhex = str_split(bin2hex($binary_sid), 2);
            // Byte 0 = Revision Level
            $sid = $sid.hexdec($sidinhex[0]).'-';
            // Byte 1-7 = 48 Bit Authority
            $sid = $sid.hexdec($sidinhex[6].$sidinhex[5].$sidinhex[4].$sidinhex[3].$sidinhex[2].$sidinhex[1]);
            // Byte 8 count of sub authorities - Get number of sub-authorities
            $subauths = hexdec($sidinhex[7]);
            //Loop through Sub Authorities
            for($i = 0; $i < $subauths; $i++) {
                $start = 8 + (4 * $i);
                // X amount of 32Bit (4 Byte) Sub Authorities
                $sid = $sid.'-'.hexdec($sidinhex[$start+3].$sidinhex[$start+2].$sidinhex[$start+1].$sidinhex[$start]);
            }
        }
        return $sid;
    }
    

    现在您可以在任何 PHP 版本中放松和使用此功能。

    【讨论】:

      【解决方案3】:

      作为一个替代示例,这可以完全使用 PHP 的 unpack 函数来完成。 objectSid 二进制结构最好记录在this MSDN doc

      修订版(1 字节):一个 8 位无符号整数,用于指定 SID 的修订级别。此值必须设置为 0x01。

      SubAuthorityCount(1 字节):一个 8 位无符号整数,指定 SubAuthority 数组中的元素数。最大数量 允许的元素数为 15。

      IdentifierAuthority(6 字节):一个 SID_IDENTIFIER_AUTHORITY 结构 指示创建 SID 的权限。它 描述创建 SID 的实体。身份识别机构 值 {0,0,0,0,0,5} 表示由 NT SID 授权创建的 SID。

      SubAuthority(变量):无符号 32 位可变长度数组 唯一标识相对于主体的整数 标识符权威。它的长度由 SubAuthorityCount 决定。

      /**
       * Decode the binary SID into its readable form.
       *
       * @param string $value
       * @return string
       */
      function decodeSID($value)
      {
          # revision - 8bit unsigned int (C1)
          # count - 8bit unsigned int (C1)
          # 2 null bytes
          # ID - 32bit unsigned long, big-endian order
          $sid = @unpack('C1rev/C1count/x2/N1id', $value);
          $subAuthorities = [];
      
          if (!isset($sid['id']) || !isset($sid['rev'])) {
              throw new \UnexpectedValueException(
                  'The revision level or identifier authority was not found when decoding the SID.'
              );
          }
      
          $revisionLevel = $sid['rev'];
          $identifierAuthority = $sid['id'];
          $subs = isset($sid['count']) ? $sid['count'] : 0;
      
          // The sub-authorities depend on the count, so only get as many as the count, regardless of data beyond it
          for ($i = 0; $i < $subs; $i++) {
              # Each sub-auth is a 32bit unsigned long, little-endian order
              $subAuthorities[] = unpack('V1sub', hex2bin(substr(bin2hex($value), 16 + ($i * 8), 8)))['sub'];
          }
      
          # Tack on the 'S-' and glue it all together...
          return 'S-'.$revisionLevel.'-'.$identifierAuthority.implode(
              preg_filter('/^/', '-', $subAuthorities)
          );
      }
      

      【讨论】:

        【解决方案4】:

        这适用于 64 位系统,我认为更简洁。

        function bin_to_str_sid($binsid) {
            $parts = unpack('Crev/x/nidhigh/Nidlow', $binsid);
            $ssid = sprintf('S-%u-%d',  $parts['rev'], ($parts['idhigh']<<32) + $parts['idlow']);
            $parts = unpack('x8/V*', $binsid);
            if ($parts) $ssid .= '-';
            $ssid .= join('-', $parts);
            return $ssid;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-01
          • 1970-01-01
          • 2017-05-12
          • 2020-11-12
          相关资源
          最近更新 更多