douba6365 2010-06-07 21:20 采纳率: 100%
浏览 138
已采纳

使用LDAP函数在PHP中获取Active Directory tokenGroups属性

Greetings,

I already have a working connection to the AD and can search and retrieve information from it. I've even developed a recursive method by which one can retrieve all groups for a given user. However, I'd like to avoid the recursion if possible. One way to do this is to get the tokenGroups attribute from the AD for the user, which should be a list of the SIDs for the groups that the specified user has membership, whether that membership be direct or indirect.

When I run a search for a user's AD information, though, the tokenGroups attribute isn't even in it. I tried specifically requesting that information (i.e., specifying it using the fourth parameter to ldap_search) but that didn't work, either.

Thanks, David Kees


  • 写回答

1条回答 默认 最新

  • doubi6669 2010-06-10 13:44
    关注

    Solved my own problem and thought I'd put the answer here so that others might find it. The issue was using the ldap_search() function. The answer was to use the ldap_read() function instead of ldap_search(). The difference is the scope of the request. The search function uses a scope of "sub" (i.e., subtree) while the read function uses "base." The tokenGroups information can only be found when using a scope of "base" so using the correct PHP function was the key.

    As I mentioned above, I was working from someone else code in perl to create my solution and the perl script used a function named "search" to do it's LDAP requests which lead me down wrong path.

    Thanks to those who took a peek at the question!

    --

    As per the requests in the comments, here's the basics of the solution in code. I'm extracting from an object that I use so this might not be 100% but it'll be close. Also, variables not declared in this snipped (e.g. $server, $user, $password) are for you to figure out; I won't know your AD credentials anyway!

    $ldap = ldap_connect($server);
    ldap_bind($ldap, $user, $password);
    $tokengroups = ldap_read($ldap, $dn, "CN=*", array("tokengroups")));
    $tokengroups = ldap_get_entries($ldap, $tokengroups);
    

    At this point, $tokengroups is our results as an array. it should have count index as well as some other information. To extract the actual groups, you'll need to do something like this:

    $groups = array();
    if($tokengroups["count"] > 0) {
        $groups = $tokengroups[0]["tokengroups"];
        unset($groups["count"]);
    
        // if you want the SID's for your groups, you can stop here.
        // if you want to decode the SID's then you can do something like this.
        // the sid_decode() here: http://www.php.net/manual/en/function.unpack.php#72591
    
        foreach($groups as $i => &$sid) {
            $sid = sid_decode($sid);
    
            $sid_dn = ldap_read($ldap, "<SID=$sid>", "CN=*", array("dn"));
            if($sid_dn !== false) {
                $group = ldap_get_entries($ldap, $sid_dn);
                $group = $group["count"] == 1 ? $group[0]["dn"] : NULL;
                $groups[$i] = $group;
            }
        }
    }
    

    That's the basics. There's one caveat: you'll probably need to work with the individual or individuals who manage AD accounts at your organization. The first time I tried to get this running (a few years ago, so my memory is somewhat fuzzy) the account that I was given did not have the appropriate authorization to access the token groups information. I'm sure there are other ways to do this, but because I was porting someone else's code for this specific solution, this was how I did it.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装