(.Net,ADSI)ActiveDirectoryでMemberOf属性に Domain Users がない
.NetからADSIを用いてActiveDirectoryのユーザ情報を取ってきてるんですが、ユーザの所属するグループの値が入っている MemberOf 属性に Domain Users がいません。
逆に、Domain Users の member にはデフォルトは全ユーザがいないといけないのに、Not Set になってます。
下記は ADSI Edit で Domain Users のオブジェクトを見たときのSSです。
e0091163_23305473.jpg

で、Active Directory ユーザーとコンピュータからユーザアカウント情報をよく見ると、Domain Users がプライマリグループになってました。(513がDomain Usersを表してるようです)
e0091163_23353371.jpg


調べると、プライマリグループはMemberOfやmemberに含まれない仕様のようです。

[ADSI] プライマリグループを取得する - ComponentGeek Article下記サイトには、このように書いてました。

ユーザのディレクトリオブジェクトにバインドすると、プロパティprimaryGroupIdにプライマリグループのSIDの一部(相対識別ID)が格納されています。プライマリグループのSIDを取得するには、属性objectSidのバイト値の最後4バイトをprimaryGroup属性値で置き換えることで取得します。

厄介な仕様ですね。

参考先のコピペになりますが、下記のように書けばプライマリグループのSIDを取得できます。(C#)

public GetADSI(){
DirectoryEntry mDrctEntry = new DirectoryEntry(@"LDAP://domaincontroller/DC=domainname,DC=jp", "administrator", "password" );
// LDAP検索オブジェクトを作成
DirectorySearcher drSearch = new DirectorySearcher(mDrctEntry);
// アカウントフィルターを設定 Userオブジェクトだけ取得するように
drSearch.Filter = "(ObjectCategory=user)";
 
// 検索する
SearchResultCollection scn = drSearch.FindAll();
if (scn == null || scn.Count <= 0) {
//なかった時
Utility.DispMessageBox(Utility.StrType.NotFoundUser);
return null;
}
 
//Userオブジェクト新規生成(Userオブジェクトはユーザアカウント情報を格納するエンティティクラスです)
foreach (SearchResult sResult in scn) {
if (sResult.Properties["primaryGroupId"].Count > 0) {
byte[] sid = CreatePrimaryGroupSID((byte[])sResult.Properties["objectSID"][0], (int)sResult.Properties["primaryGroupId"][0]);
usr.PrimaryGroupSID = SidToString2(sid);
}
}
}
 
/// <summary>
/// userのprimaryGroupId属性値はプライマリグループの相対識別値のみ
/// 含まれているので、userのobjectSidのバイト値の最後の4バイトをprimaryGroupId
/// のバイト値で置き換えることで取得する。
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public byte[] CreatePrimaryGroupSID(byte[] sid ,int primaryGroup) {
//byte[] sid = user.Properties["objectSid"][0] as byte[];
//int primaryGroup = (int)user.Properties["primaryGroupId"][0];

byte[] primaryGroupBytes = BitConverter.GetBytes(primaryGroup);
for (int i = 0; i < primaryGroupBytes.Length; ++i)
{
sid.SetValue(primaryGroupBytes[i], sid.Length - (primaryGroupBytes.Length - i));
}
return sid;
}
 
/// <summary>
/// SID配列を文字列に。
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public string SidToString2(byte[] sids){
//ポインタ定義
IntPtr pStringSid = IntPtr.Zero;
//APIを使って変換 第二引数ポインタに結果が入ってる
int ret = ConvertSidToStringSid(sids, ref pStringSid);
//結果となる文字列変数定義
string strSid = string.Empty;
if (ret != 0)
{
//ポインタの先にある文字列をマネージStringに変換。
strSid = Marshal.PtrToStringAnsi(pStringSid);
//メモリ解放
Marshal.FreeCoTaskMem(pStringSid);
}
return strSid;
}

[PR]
by jehoshaphat | 2010-04-12 23:36 | .Net開発 | Trackback | Comments(0)
トラックバックURL : http://jehupc.exblog.jp/tb/12470608
トラックバックする(会員専用) [ヘルプ]
※このブログはトラックバック承認制を適用しています。 ブログの持ち主が承認するまでトラックバックは表示されません。


<< (.Net)List<T... (.Net,ADSI)User... >>