ActiveDirectoryのプライマリグループの取得

Net:LDAPでActiveDirectoryアクセスするとプライマリグループがmemberOfに入っていない為取得できない。以下対策の為の調査。

プライマリグループが設定されているAttribute

それぞれのユーザーのprimaryGroupID

primaryGroupID:513

上記の例:513のIDが格納されている場所

Domain UsersのobjectSid(バイナリで格納)=> ドメインSID

objectSid:01 05 00 00 00 00 00 05 15 ...(中略)... 01 02 00 00

オブジェクトを識別するSIDとは?

上記objectSidを『S-1-5-21-……-513』の様な形式で取得する(バイナリ=>テキスト変換)

(調査中)

  • 案1:eric dot brison at anakeen dot com (written by php)
//An simple function to decode active directory sid
function sid_decode($osid) {
  $sid=false;
  $u=unpack("H2rev/H2b/nc/Nd/V*e",$osid);
  if ($u) {
    $n232=pow(2,2);
    unset($u["b"]); // unused
    $u["c"]= $n232*$u["c"]+$u["d"];
    unset($u["d"]);
    $sid="S";
    foreach ($u as $v) {
      if ($v < 0) $v=$n232 + $v;
      $sid.= "-".$v;
    }
  }
  return $sid;
}
// example
$osid64="AQUAAAAAAAUVAAAA3DixrE8XmGks/zdlAwIAAA==";
print sid_decode(base64_decode($osid64));

// display :S-01-5-21-2897295580-1771575119-1698168620-515
  • 案1に基く実行例 for Perl

ActiveDirectoryのSIDをLDAPで参照すると可変長のバイナリ値が取得される。以下に示すようにunpackして更に加工するとテキスト形式のSIDに変換できる。
検証ツール::Lookup SID Version 1.00

#01 05 00 00 00 00 00 05 15 00 00 00 74 66 6B BE 7F 71 0F 78 3A 1E 18 31 63 04 00 00
#H2 H2 n**** N********** V********** V********** V********** V********** V**********
#01 05 0     5           21          3194709620  2014278015  823664186   1123
#実行例: S-1-5-21-3194709620-2014278015-823664186-1123
#正 解: S-1-5-21-3194709620-2014278015-823664186-1123
my @u = unpack("H2H2nNV*", $entry->get_value('objectSid'));	#バイナリ -> テキスト変換 (php) H2rev/H2b/nc/Nd/V*e
if($#u>=0){
	#以下、何をやっているのかはワタクシには理解不可能(サンプルをそのまま引用)。
	my $n232=2**2;
	$u[2]=$n232*$u[2]+$u[3];
	splice(@u, 3, 1);	#要素削除(N)
	splice(@u, 1, 1);	#要素削除(二番目のH2)
	foreach my $v (@u) {
		if ($v < 0) {$v = $n232 + $v;}
		$v=int($v);
	}
}
print "S-".join("-", @u);