代码之家  ›  专栏  ›  技术社区  ›  ScottCher

如何使用c和adodb查询Active Directory?

  •  2
  • ScottCher  · 技术社区  · 15 年前

    正在查找使用c_通过ADODB连接到Active Directory的示例。

    我的目标是能够基于用户属性(用户ID、电子邮件地址等)运行查找来验证用户在Active Directory中是否有效。

    [要强调的是,使用ADODB是一项要求,使用DirectoryServices不是有效的响应。]

    我当前的方法不起作用(cmd.execute位处的异常):

    object parms = null;
    object recs = null;
    ADODB.Connection conn = new ADODB.Connection();
    ADODB.Command cmd = new ADODB.Command();
    ADODB.Recordset rs = new ADODB.Recordset();
    
    conn.Open("Provider=ADsDSOObject",obfsUser,obfsPass,0);
    
    cmd.ActiveConnection = conn;
    cmd.CommandText = "<LDAP://OU=obfsOU,DC=obfsDC,DC=corp,DC=Net>;;name;subtree";
    rs = cmd.Execute(out recs, ref parms, 0);
    

    我不确定是否应该/在哪里提供服务器引用,也不确定通过引用传递给cmd.execute方法的参数应该是什么。通过ADODB从C连接到ActiveDirectory的文档不多。

    康涅狄格州将返回1,所以我相信我得到了一个活跃的连接。我认为问题在于传递给cmd.execute()方法的参数。

    3 回复  |  直到 15 年前
        1
  •  4
  •   tomo    15 年前

    Scottcher的答案是可行的,但是它有局限性,特别是你不能处理1000条记录的结果限制。要做到这一点, 只有 方法是使用一个命令对象,相信我,这是一个雷区,因为(a)在C接口上没有好的文档,(b)在撰写本文时,没有令人难以置信的完整解决方案可以在谷歌上搜索。

    我花了最后几天的时间来研究这个问题,我想把一些有用的东西还给我读过的所有资料来源,包括拼图的各种片段。

    首先,正如很多地方提到的(遗憾的是,只有vb示例!),如果您不做一些特殊的事情,那么所有ADSI查询的结果限制为1000行。避免这种情况的关键是在命令对象上设置“页面大小”属性。我们将在几秒钟内完成,但首先我们需要使用命令使基本查询工作。如果在这个线程中使用原始代码,您将在cmd.execute上得到一个异常,抱怨参数不匹配。您会认为作为引用对象传入空值就足够了,特别是因为LDAP语法(显然)没有参数。

    我在两个地方找到了答案。首先,尽管您没有显式地指定参数,但LDAP SQL语法中的“:”似乎足以使ADO认为需要参数。奇怪,但似乎是真的。其次,指定“无参数”情况的正确方法是将值设置为类型。缺少,而不是空,如:

    object parms = Type.Missing;

    这是让execute不引发异常的关键。

    现在,通过一个有效的命令,我们可以解决1000行的限制。这是通过在命令上指定“page-size”属性来实现的,但是,从C接口可以明显看出,它与C属性不同。您需要将它放入属性集合中,但这样做并不能公开一个好的集合接口。经过反复试验,正确的语法是:

    cmd.Properties["Page Size"].Value = 500;

    我不认为这是很重要的确切的页面大小是什么(仍在玩),但设置为某个足够告诉ADSI获得所有的结果。我真诚地希望这能帮助别人。

        2
  •  2
  •   ScottCher    15 年前

    这是可行的。

    希望这能帮助有同样需求和问题的人。

    [请注意,缺少adodb.command对象,并且查询使用了SQL格式而不是ADSI格式。]

    object recs;
    
    ADODB.Connection conn = new ADODB.Connection();
    ADODB.Recordset rs = new ADODB.Recordset();
    
    // You may need to provide user id and password instead of empty strings        
    conn.Open("Provider=ADsDSOObject", "", "", 0);
    
    // replace <> elements with your server name and OU/DC tree org
    string server = "<enter your server name here>";
    string start = "OU=<blah>,DC=<blah>,DC=<blah>,DC=<blah>";
    string where = "objectClass = '*'";
    string qry = string.Format("SELECT cn FROM 'LDAP://{0}/{1}' WHERE {2}", server, start, where);
    
    rs = conn.Execute(qry, out recs, 0);
    
    for (; !rs.EOF; rs.MoveNext())
    {
        Console.WriteLine(rs.Fields["cn"].Value.ToString());
    }
    
        3
  •  0
  •   marc_s HarisH Sharma    15 年前

    在Active Directory上查看Richard Mueller的网站-他专门在ADO搜索广告提示上有一个页面:

    http://www.rlmueller.net/ADOSearchTips.htm

    他的网站上也有大量优秀的参考资料,比如Excel表格,上面有所有的广告特性和特点。

    强烈推荐!

    马克