LDAP查找组PHP的成员 [英] LDAP Finding Members of a group PHP

查看:50
本文介绍了LDAP查找组PHP的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Active Directory中组的用户成员资格以及如何使用PHP抓取此类成员资格有疑问.我的大问题/情况是我有一个正在制作的网站,实际上我正在尝试根据Active Directory中的组分配管理员,并且我知道如何检查帐户的状态成员,但是我的问题是有一些组在那里没有显示,而没有显示的组之一就是我需要的组.有没有一种方法可以检查谁是该组的成员,而不是检查该用户是否是该组的成员.或者,如果有人知道为什么某些组没有出现在我的搜索中,我宁愿以这种方式搜索成员身份,因为这将是一个简单的逻辑语句,以检查用户是否在该组中,我的代码在下面,并且可以正常工作,但是我说有些小组没有出现,我想我读过一些有关成员存储方式的信息,以及它是直接成员还是您是另一个小组成员的小组成员.我们用作默认组的一个组是域用户,但该组的成员资格是直接的,因此那里的memberOf数组中没有该用户,因为该组的成员是所有用户,而不是包含该用户的其他安全组.

I have a question regarding user membership of groups in Active directory and grabbing such memberships with PHP. My big question/situation is that I have a site I am making and essentially I am trying to assign administrators based off of groups in Active directory and I know how to check member of status on an account but my problem is that there are some groups that aren't displayed there, and one of the groups that is not displayed is the group I need. Is there a way I can check who is a member of that group instead of checking if that user is a member of that group. Alternatively if someone knows why certain groups are not appearing in my search I would prefer to search membership that way because then it would be a simple logic statement to check if the user is in that group, my code is below and it does work but as I said there are certain groups that don't appear and I think I read somewhere about how membership is stored and also if it is a direct membership or if you are a member of a group that is a member of another group. One group that we use as our default group is Domain users but no one has that in there memberOf array even though that group's membership is direct as in the members of that group are all users not other security groups containing the users.

在该程序的某个时刻,我需要将某些用户标记为经理",而我这样做的最简单方法是,如果他们是某个管理者组的成员,则存储标志VIA会话变量.上面我遇到的问题是用户没有出现在他们的某些组中,因此这是行不通的,可以访问管理员的组没有出现在我的MemberOf区域中.在最后阶段,我将不得不经过5-6个小组并将所有成员添加到数据库中,这是一个类似的问题,并且应该具有类似的解决方案,因此,如果我发现其中一只掉下来,也许我可以用一只石头杀死两只鸟也.我这个问题的意思是,我将需要抓取诸如"users HR"之类的组,然后按给定名称和姓氏以及其他字段的一些默认值将它们全部上载到数据库,但是我不知道如何从一个组中抓住用户,我知道如何抓住一个用户组,但即使这样也不能抓住100%的组,如果我可以颠倒该顺序并充当该组并检查我自己的成员,这将使事情变得简单,我们目前用来为我们完成所有操作的应用程序位于ASP.net中,但已有10年左右的历史了,并且已经硬编码了一个管理员帐户来访问组,依此类推,即使这样做,我仍然不确定如何会成为一个小组的成员.

At some point in this program I need to mark certain users as "managers" and the easiest way for me to do so would be to store a flag VIA session variable if they are a member of a certain manager group, as stated above the problem I am running into is users are not appearing in some of their groups so this isn't working, the group that would give access to managers is not appearing in my MemberOf area. During the final stage I will have to go through 5-6 groups and add all the members to the database, it is a similar problem and should have a similar solution so maybe I can kill two birds with 1 stone if I figure that one out too. What I mean by this problem is that I will need to grab a group such as something like 'users HR' and then upload them all to the database by givenname and surname and some default values for other fields but I don't know how to grab users from a group, I know how to grab groups of a user but even that doesn't grab 100% of the groups and if I can reverse that order and act as the group and check my own members that would make things real easy, our current application that we are using to do all this for us is in ASP.net but 10 years old or so and has an administrator account hard coded in to access groups and so on, even doing that I still am not sure how I would get members of a group.

代码:

<?php
$ldap = ldap_connect("192.168.1.**");
$ldap_dn = "DC=************,DC=local";
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option( $ldap, LDAP_OPT_PROTOCOL_VERSION, 3 );
$access = NULL;
if ($bind = ldap_bind($ldap, "***********\\" . $_POST['username'], $_POST['password'])) {
    $filter = "(sAMAccountName=" . $_POST['username'] . ")";
    $attr = array("memberof","givenname","sn","mail");
    $result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
    $entries = ldap_get_entries($ldap, $result);
    $givenname = $entries[0]['givenname'][0] . " " . $entries[0]['sn'][0];
    ldap_unbind($ldap);
    //var_dump($entries[0]["sn"][0]);
    //var_dump($givenname);
    //var_dump($entries[0]);
    // check groups
    foreach($entries[0]['memberof'] as $grps) {
        // is manager, break loop
        //if (strpos($grps, $ldap_manager_group)) { $access = 2; break; }
        // is user
        //var_dump($grps);
        if (strpos($grps, "****** * *** *****")) $access = "****** *";
        if (strpos($grps, "*** Group")) $access = "***";
        if (strpos($grps, "*** Group")) $access = "***";
        if (strpos($grps, "***")) $access = "***";
        if (strpos($grps, "*** Group")) $access = "***";
        if (strpos($grps, "***")) $access = "***";
    }
    if ($access != NULL) {
        // establish session variables
        $_SESSION['user'] = $_POST['username'];
        $_SESSION['access'] = $access;
        $_SESSION['givenname'] = $givenname;
        $_SESSION['email'] = $entries[0]['mail'][0];
        return true;
        } else {
        //echo "No rights?";
        // user has no rights
        return false;
    }
} else {
  //header("Location: login.php?Error=Invalid Identity");
    echo "Elese Here";
}
?>

我一直在尝试使用本教程:

I have been trying to use this tutorial: samjlevy.com and I understand it for the most part but I am getting a few errors:

Warning: ldap_search(): Search: Operations error in C:\inetpub\wwwroot\InOutBoard\test.php on line 62

Warning: ldap_get_entries() expects parameter 2 to be resource, boolean given in C:\inetpub\wwwroot\InOutBoard\test.php on line 63

Warning: array_shift() expects parameter 1 to be array, null given in C:\inetpub\wwwroot\InOutBoard\test.php on line 66

Warning: Invalid argument supplied for foreach() in C:\inetpub\wwwroot\InOutBoard\test.php on line 72
Array ( )

它们似乎都与搜索有关,因为它不起作用,它会返回一个NULL值集,从而不允许其他部分运行.我不确定我的$ ldap_dn是否正确,因为我使用的是上面php代码中的相同代码.我的布局如下(我是新手,我相信这是正确的):DC = company,DC = local,所以应该是我想要的组:CN =正在寻找的组,OU =最低级别的Ou,OU =组,OU = company,DC = Company,DC = local

They all seem to be with the search because it isn't working it's return a NULL set to result which isn't going to allow other parts to run. I am not sure if my $ldap_dn is correct as I am using the same one from the php code above. My layout is as follows (I am new to this I believe this is correct): DC=company,DC=local and so it should be for the group I want: CN=Group Looking For,OU=lowestLevel Ou,OU=Groups,OU=company,DC=Company,DC=local

我必须将其用作我的$ ldap_dn吗?

Would I have to use that as my $ldap_dn?

编辑2 :(更新的代码)

这段代码显示了用户所在的所有组,并且运行良好,是否有办法编写第二页,使用相似的页面来获取其中一个组并从中获取所有成员?

This code is displaying all the groups that a user is in and works very well, is there a way to write a second page that uses a similar page to take one of those groups and grabs all the members out of it?

<?php

$ldap = ldap_connect("192.168.1.**");
$ldap_dn = "DC=Company,DC=local";
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option( $ldap, LDAP_OPT_PROTOCOL_VERSION, 3 );
$access = NULL;
if ($bind = ldap_bind($ldap, "**********\\" . $_POST['username'], $_POST['password'])) {
    $filter = "(sAMAccountName=" . $_POST['username'] . ")";
    $attr = array("memberof","givenname","sn","mail","distinguishedname");
    $result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
    $entries = ldap_get_entries($ldap, $result);
    $givenname = $entries[0]['givenname'][0] . " " . $entries[0]['sn'][0];
    //ldap_unbind($ldap);
    //var_dump($entries[0]["sn"][0]);
    //var_dump($givenname);
    //var_dump($entries[0]);
    var_dump($entries[0]['distinguishedname'][0]);

    $gFilter = "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=".$entries[0]['distinguishedname'][0]."))";
    $gAttr = array("cn");
    $result1 = ldap_search($ldap, $ldap_dn, $gFilter, $gAttr) or exit("Unable to search LDAP server");
    $groups = ldap_get_entries($ldap, $result1);
    var_dump($groups);
    // check groups
    foreach($entries[0]['memberof'] as $grps) {
        // is manager, break loop
        //if (strpos($grps, $ldap_manager_group)) { $access = 2; break; }

        // is user
        //var_dump($grps);
        if (strpos($grps, "****** * *** *****")) $access = "****** *";
        if (strpos($grps, "*** Group")) $access = "***";
        if (strpos($grps, "*** Group")) $access = "***";
        if (strpos($grps, "***")) $access = "***";
        if (strpos($grps, "*** Group")) $access = "***";
        if (strpos($grps, "***")) $access = "***";

    }

    if ($access != NULL) {
        // establish session variables
        $_SESSION['user'] = $_POST['username'];
        $_SESSION['access'] = $access;
        $_SESSION['givenname'] = $givenname;
        $_SESSION['email'] = $entries[0]['mail'][0];
        return true;
        } else {
        //echo "No rights?";
        // user has no rights
        return false;
    }
} else {
  //header("Location: login.php?Error=Invalid Identity");
    echo "Elese Here";
}
?>

第二页:应该在该页中查找看起来像是在尝试这样做的组成员,但不会选择组的成员,而是选择我们的一个OU.在下面查找代码以获取布局及其要获取的内容.

Second Page: This page is supposed to find members of a group which looks like it may be trying to do so but not picking out members of groups but one of our OU's instead. Look below to code for a layout and what it's grabbing.

<?php
function get_members($group=FALSE,$inclusive=FALSE) {
    $ldap_host = "192.168.1.***";
    $ldap_dn = "OU=******,OU=*****,OU=**********,DC=Company,DC=local";
    $ldap_usr_dom = "@".$ldap_host;
    $user = "*******";
    $password = "******";
    $keep = array(
        "samaccountname",
        "distinguishedname"
    );
    $ldap = ldap_connect($ldap_host) or die("Could not connect to LDAP");
   ldap_bind($ldap, "REGION5SYSTEMS\\" . $user, $password) or die("Could not bind to LDAP");ry
    if($group) $query = "(&"; else $query = ""; 
    $query .= "(&(objectClass=user)(objectCategory=person))";
    if(is_array($group)) {
        // Looking for a members amongst multiple groups
            if($inclusive) {
                $query .= "(|";
            } else {
                $query .= "(&";
            }
            foreach($group as $g) $query .= "(memberOf=CN=$g,$ldap_dn)";
            $query .= ")";
    } elseif($group) {
        $query .= "(memberOf=CN=$group,$ldap_dn)";
    }
    if($group) $query .= ")"; else $query .= "";
    $results = ldap_search($ldap,$ldap_dn,$query);
    $entries = ldap_get_entries($ldap, $results);
    array_shift($entries);
    $output = array(); // Declare the output array
    $i = 0; // Counter
    // Build output array
    foreach($entries as $u) {
        foreach($keep as $x) {
            // Check for attribute
            if(isset($u[$x][0])) $attrval = $u[$x][0]; else $attrval = NULL;
            $output[$i][$x] = $attrval;
        }
        $i++;
    }

    return $output;
}

// Example Output
print_r(get_members()); // Gets all users in 'Users'
print_r(get_members("Group I'm search for")); // Gets all members of 'Test Group'
?>

因此,我们的DC为DC = CompanyName,DC = Local,然后我们有文件夹和OU,并且其中一个OU被命名为"CompanyName",并且嵌套在其中的是OU,例如Admins Computers,Contacts,Groups等.我正在查看的OU是用户和嵌套在其中的用户,它们是我们建筑物中的不同组织(他们使用我们的domian),并且为此项目制作了一个额外的OU.该项目的背景是inoutBoard的一名员工,因此该OU中有3个安全组,一个用于其他组织的成员,一个用于我们的组织成员,一个用于我们组织及其组织的经理人员,基本上是可以更改的人员其他人的身份(如果他们忘记这样做的话).我们理想地希望做的是具有某种同步按钮,该按钮可以检查这些组的成员,然后将其上传到数据库,以及一些默认值,例如不在办公室的默认状态,无描述或类似内容..这些组也不包含人员,而是包含其他安全组.那就是我们想要的工作,我们希望能够找到那些组的成员,如果我将$ ldap_dn设置为"CN = Company,DC = Company,DC = Local",有时我附上的第二段代码有时会起作用它会打印出用户OU中的所有用户,然后进入那里的所有OU,并从那些OU中打印用户,但我们实际需要的OU是带有进出板组的OU.如果我将该路径指定为$ ldap_dn,则仅打印array()而没有其他内容.有想法吗?

So our DC is DC=CompanyName,DC=Local and we then have folders and OU's and One of the OU's is named 'CompanyName' and nested in it are OU's such as Admins Computers, Contacts, Groups, ect ect... The OU I am looking at is Users and nested within that are different organizations in our building (They use our domian) and one extra OU that is made for this project. Background on the project is a employee inoutBoard and so we have 3 Security groups in that OU, one for other organization's members, one for our organizations members and one for those who are managers from both our Org and their org, basically people who can change status's of others if they forget to do so. What we would ideally want to do is have some sort of sync button which could go check members of those groups and then upload them to the database as well as some default values such as default status of out of office and no description or anything like that. Those groups do not contain people either, they contain other security groups. That's what we want to work, we want to be able to find the members of those groups, the second bit a code I attached will work sometimes, if I set $ldap_dn to "CN=Company,DC=Company,DC=Local" it will print all users in the Users OU and then go into all the OU's there and print the users from those OU's except the OU that we actually need which is that OU that has the groups for the in out board. If I specify that path as the $ldap_dn it just prints array() and nothing else. Any Idea?

推荐答案

memberOf 属性将仅包含直接组成员身份,因此不会列出递归成员身份.但是,您可以像这样专门查询用户的递归组成员身份(以便在绑定之后直接修改代码):

The memberOf attribute will only contain direct group memberships, so recursive memberships will not be listed. However, you could specifically query for the recursive group memberships of a user like so (to adapt your code a bit directly after the bind):

$filter = "(sAMAccountName=" . $_POST['username'] . ")";
$attr = array("givenname","sn","mail", "distinguishedname");
$result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
$entries = ldap_get_entries($ldap, $result);

$gFilter = "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:=".$entries[0]['distinguishedname'][0]."))";
$gAttr = array("cn");
$result = ldap_search($ldap, $ldap_dn, $gFilter, $gAttr) or exit("Unable to search LDAP server");
$groups = ldap_get_entries($ldap, $result);

目前尚未测试,但这是执行此操作的常规过滤器和过程.获取用户的DN,然后使用匹配规则OID 1.2.840.113556.1.4.1941 递归获取组.

Not tested at the moment, but that is the general filter and process for doing it. Get the DN of the user then use the matching rule OID 1.2.840.113556.1.4.1941 to get groups recursively.

之所以没有显示域用户"组,是因为这是AD中的一个特殊"主要组,存储在用户的 primaryGroupId 属性中.有关此的其他信息:

The reason you are not getting the "Domain Users" group to show up is because that is a "special" primary group in AD, stored within the primaryGroupId attribute of a user. Additional info on that here:

https://support.microsoft.com/en-us/kb/297951

这篇关于LDAP查找组PHP的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆