LDAP查找组

时间:2016-04-28 16:33:25

标签: php active-directory ldap memberof

我有一个关于Active Directory中组的用户成员资格以及使用PHP获取此类成员资格的问题。我的一个大问题/情况是我有一个网站,我正在尝试根据Active Directory中的组分配管理员,我知道如何检查帐户的状态成员但我的问题是有一些组那里没有显示,其中一个未显示的组是我需要的组。有没有办法可以检查谁是该组的成员,而不是检查该用户是否是该组的成员。或者,如果有人知道为什么某些组没有出现在我的搜索中,我宁愿以这种方式搜索成员资格,因为这将是一个简单的逻辑语句来检查用户是否在该组中,我的代码在下面并且它确实有效但是作为我说有些团体不会出现,我想我会在某处了解会员资格的存储方式,以及是否是直接会员资格,或者如果您是另一个团体成员的团体成员。我们用作默认组的一个组是域用户,但是在其中没有人具有memberOf数组,即使该组的成员资格是直接的,因为该组的成员中的所有用户都不是包含用户的其他安全组。

在这个程序的某个时刻,我需要将某些用户标记为"经理"对我来说最简单的方法是存储一个标志VIA会话变量,如果他们是某个经理组的成员,如上所述,我遇到的问题是用户没有出现在他们的某些组中,所以这个没有工作,可以访问经理的小组没有出现在我的MemberOf区域。在最后阶段我将不得不通过5-6组并将所有成员添加到数据库中,这是一个类似的问题,应该有一个类似的解决方案,所以如果我找到一个可能我可以杀死一石二鸟太。我的意思是这个问题是我需要抓住像“用户HR”这样的群体。然后通过givenname和surname以及其他字段的一些默认值将它们全部上传到数据库,但我不知道如何从组中获取用户,我知道如何抓住用户的组,但即使这样也没有#39 ; t抓住100%的群组,如果我可以撤销该命令并充当群组并检查我自己的会员,这将使事情变得非常简单,我们当前用于为我们做这一切的应用程序是在ASP.net但是10岁左右,并且有一个管理员帐户硬编码进入群组等等,即使这样做,我仍然不确定如何获得群组成员。

代码:

<?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";
}
?>

编辑:

我一直在尝试使用本教程:samjlevy.com我在很大程度上理解它,但我收到了一些错误:

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 =公司,DC =本地,所以它应该是我想要的组:CN = Group Looking For,OU = lowestLevel Ou,OU = Groups ,OU =公司,DC =公司,DC =本地

我是否必须将其用作我的$ ldap_dn?

编辑2 :(更新代码)

此代码显示用户所在的所有组并且工作得很好,有没有办法编写第二个页面,使用类似的页面来获取其中一个组并从中获取所有成员?< / p>

<?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之一。下面看一下布局的代码以及它的内容。

<?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被命名为&#39; CompanyName&#39;并且嵌套在其中的是诸如管理员计算机,联系人,组等等的OU ...我正在查看的OU是用户并且嵌套在我们的建筑物中的不同组织(他们使用我们的domian)和一个为此项目制作的额外OU。该项目的背景是员工inoutBoard,因此我们在该OU中有3个安全组,一个用于其他组织的成员,一个用于我们的组织成员,一个用于我们的组织和他们的组织的管理员,基本上如果他们忘记了,可以改变他人身份的人。我们理想的想做的是有一些同步按钮,可以检查这些组的成员,然后将它们上传到数据库以及一些默认值,如不在办公室的默认状态,没有描述或类似的东西。这些组也不包含人,它们包含其他安全组。这就是我们想要工作的东西,我们希望能够找到这些组的成员,如果我将$ ldap_dn设置为&#34; CN = Company,DC,我附加的代码有时会工作的第二位=公司,DC =本地&#34;它将打印Users OU中的所有用户,然后进入那里的所有OU并打印那些OU中的用户,除了我们实际需要的OU,即具有for的组的OU出局。如果我将该路径指定为$ ldap_dn,则只打印array()而不是其他内容。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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

$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以递归方式获取组。

您没有显示“域用户”组的原因是因为它是AD中的“特殊”主要组,存储在用户的primaryGroupId属性中。关于此的其他信息:

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