Ejemplo n.º 1
0
/**
* sync LDAP Groups against the DB
*/
function sync_LDAP_groups()
{
    global $c;
    $ldapDriver = getStaticLdap();
    if (!$ldapDriver->valid) {
        return;
    }
    $mapping = $c->authenticate_hook['config']['group_mapping_field'];
    //$attributes = array('cn','modifyTimestamp','memberUid');
    $attributes = array_values_mapping($mapping);
    $ldap_groups_tmp = $ldapDriver->getAllGroups($attributes);
    if (sizeof($ldap_groups_tmp) == 0) {
        return;
    }
    $member_field = $mapping['members'];
    foreach ($ldap_groups_tmp as $key => $ldap_group) {
        $group_mapping = $ldap_group[$mapping['username']];
        $ldap_groups_info[$group_mapping] = $ldap_group;
        if (is_array($ldap_groups_info[$group_mapping][$member_field])) {
            unset($ldap_groups_info[$group_mapping][$member_field]['count']);
        } else {
            $ldap_groups_info[$group_mapping][$member_field] = array($ldap_groups_info[$group_mapping][$member_field]);
        }
        unset($ldap_groups_tmp[$key]);
    }
    $db_groups = array();
    $db_group_members = array();
    $qry = new AwlQuery("SELECT g.username AS group_name, member.username AS member_name FROM dav_principal g LEFT JOIN group_member ON (g.principal_id=group_member.group_id) LEFT JOIN dav_principal member  ON (member.principal_id=group_member.member_id) WHERE g.type_id = 3");
    $qry->Exec('sync_LDAP', __LINE__, __FILE__);
    while ($db_group = $qry->Fetch()) {
        $db_groups[$db_group->group_name] = $db_group->group_name;
        $db_group_members[$db_group->group_name][] = $db_group->member_name;
    }
    $ldap_groups = array_keys($ldap_groups_info);
    // users only in ldap
    $groups_to_create = array_diff($ldap_groups, $db_groups);
    // users only in db
    $groups_to_deactivate = array_diff($db_groups, $ldap_groups);
    // users present in ldap and in the db
    $groups_to_update = array_intersect($db_groups, $ldap_groups);
    if (sizeof($groups_to_create)) {
        $c->messages[] = sprintf(i18n('- creating groups : %s'), join(', ', $groups_to_create));
        $validUserFields = get_fields('usr');
        foreach ($groups_to_create as $k => $group) {
            $user = (object) array();
            if (isset($c->authenticate_hook['config']['default_value']) && is_array($c->authenticate_hook['config']['default_value'])) {
                foreach ($c->authenticate_hook['config']['default_value'] as $field => $value) {
                    if (isset($validUserFields[$field])) {
                        $user->{$field} = $value;
                        dbg_error_log("LDAP", "Setting usr->%s to %s from configured defaults", $field, $value);
                    }
                }
            }
            $user->user_no = 0;
            $ldap_values = $ldap_groups_info[$group];
            foreach ($mapping as $field => $value) {
                dbg_error_log("LDAP", "Considering copying %s", $field);
                if (isset($validUserFields[$field])) {
                    $user->{$field} = $ldap_values[$value];
                    dbg_error_log("LDAP", "Setting usr->%s to %s from LDAP field %s", $field, $ldap_values[$value], $value);
                }
            }
            if ($user->fullname == "") {
                $user->fullname = $group;
            }
            if ($user->displayname == "") {
                $user->displayname = $group;
            }
            $user->username = $group;
            $user->updated = "now";
            /** @todo Use the 'updated' timestamp from LDAP for groups too */
            $principal = new Principal('username', $group);
            if ($principal->Exists()) {
                $principal->Update($user);
            } else {
                $principal->Create($user);
            }
            $qry = new AwlQuery("UPDATE dav_principal set type_id = 3 WHERE username=:group ", array(':group' => $group));
            $qry->Exec('sync_LDAP', __LINE__, __FILE__);
            Principal::cacheDelete('username', $group);
            $c->messages[] = sprintf(i18n('- adding users %s to group : %s'), join(',', $ldap_groups_info[$group][$mapping['members']]), $group);
            foreach ($ldap_groups_info[$group][$mapping['members']] as $member) {
                $qry = new AwlQuery("INSERT INTO group_member SELECT g.principal_id AS group_id,u.principal_id AS member_id FROM dav_principal g, dav_principal u WHERE g.username=:group AND u.username=:member;", array(':group' => $group, ':member' => $member));
                $qry->Exec('sync_LDAP_groups', __LINE__, __FILE__);
                Principal::cacheDelete('username', $member);
            }
        }
    }
    if (sizeof($groups_to_update)) {
        $c->messages[] = sprintf(i18n('- updating groups : %s'), join(', ', $groups_to_update));
        foreach ($groups_to_update as $group) {
            $db_members = array_values($db_group_members[$group]);
            $ldap_members = array_values($ldap_groups_info[$group][$member_field]);
            $add_users = array_diff($ldap_members, $db_members);
            if (sizeof($add_users)) {
                $c->messages[] = sprintf(i18n('- adding %s to group : %s'), join(', ', $add_users), $group);
                foreach ($add_users as $member) {
                    $qry = new AwlQuery("INSERT INTO group_member SELECT g.principal_id AS group_id,u.principal_id AS member_id FROM dav_principal g, dav_principal u WHERE g.username=:group AND u.username=:member", array(':group' => $group, ':member' => $member));
                    $qry->Exec('sync_LDAP_groups', __LINE__, __FILE__);
                    Principal::cacheDelete('username', $member);
                }
            }
            $remove_users = @array_flip(@array_flip(array_diff($db_members, $ldap_members)));
            if (sizeof($remove_users)) {
                $c->messages[] = sprintf(i18n('- removing %s from group : %s'), join(', ', $remove_users), $group);
                foreach ($remove_users as $member) {
                    $qry = new AwlQuery("DELETE FROM group_member USING dav_principal g,dav_principal m WHERE group_id=g.principal_id AND member_id=m.principal_id AND g.username=:group AND m.username=:member", array(':group' => $group, ':member' => $member));
                    $qry->Exec('sync_LDAP_groups', __LINE__, __FILE__);
                    Principal::cacheDelete('username', $member);
                }
            }
        }
    }
    if (sizeof($groups_to_deactivate)) {
        $c->messages[] = sprintf(i18n('- deactivate groups : %s'), join(', ', $groups_to_deactivate));
        foreach ($groups_to_deactivate as $group) {
            $qry = new AwlQuery('UPDATE dav_principal SET user_active=FALSE WHERE username=:group AND type_id = 3', array(':group' => $group));
            $qry->Exec('sync_LDAP', __LINE__, __FILE__);
            Principal::cacheFlush('username=:group AND type_id = 3', array(':group' => $group));
        }
    }
}
Ejemplo n.º 2
0
function process_ace($grantor, $by_principal, $by_collection, $ace)
{
    global $cache_delete_list, $request;
    $elements = $ace->GetContent();
    $principal_node = $elements[0];
    $grant = $elements[1];
    if ($principal_node->GetNSTag() != 'DAV::principal') {
        $request->MalformedRequest('ACL request must contain a principal, not ' . $principal->GetNSTag());
    }
    $grant_tag = $grant->GetNSTag();
    if ($grant_tag == 'DAV::deny') {
        $request->PreconditionFailed(403, 'grant-only');
    }
    if ($grant_tag == 'DAV::invert') {
        $request->PreconditionFailed(403, 'no-invert');
    }
    if ($grant->GetNSTag() != 'DAV::grant') {
        $request->MalformedRequest('ACL request must contain a principal for each ACE');
    }
    $privilege_names = array();
    $xml_privs = $grant->GetPath("/DAV::grant/DAV::privilege/*");
    foreach ($xml_privs as $k => $priv) {
        $privilege_names[] = $priv->GetNSTag();
    }
    $privileges = privilege_to_bits($privilege_names);
    $principal_content = $principal_node->GetContent();
    if (count($principal_content) != 1) {
        $request->MalformedRequest('ACL request must contain exactly one principal per ACE');
    }
    $principal_content = $principal_content[0];
    switch ($principal_content->GetNSTag()) {
        case 'DAV::property':
            $principal_property = $principal_content->GetContent();
            if ($principal_property[0]->GetNSTag() != 'DAV::owner') {
                $request->PreconditionFailed(403, 'recognized-principal');
            }
            if (privilege_to_bits('all') != $privileges) {
                $request->PreconditionFailed(403, 'no-protected-ace-conflict', 'Owner must always have all permissions');
            }
            continue;
            // and then we ignore it, since it's protected
            break;
        case 'DAV::unauthenticated':
            $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users');
            break;
        case 'DAV::href':
            $principal_type = 'href';
            $grantee = new DAVResource(DeconstructURL($principal_content->GetContent()));
            $grantee_id = $grantee->getProperty('principal_id');
            if (!$grantee->Exists() || !$grantee->IsPrincipal()) {
                $request->PreconditionFailed(403, 'recognized-principal', 'Principal "' + $principal_content->GetContent() + '" not found.');
            }
            $sqlparms = array(':to_principal' => $grantee_id);
            $where = 'WHERE to_principal=:to_principal AND ';
            if (isset($by_principal)) {
                $sqlparms[':by_principal'] = $by_principal;
                $where .= 'by_principal = :by_principal';
            } else {
                $sqlparms[':by_collection'] = $by_collection;
                $where .= 'by_collection = :by_collection';
            }
            $qry = new AwlQuery('SELECT privileges FROM grants ' . $where, $sqlparms);
            if ($qry->Exec('ACL', __LINE__, __FILE__) && $qry->rows() == 1 && ($current = $qry->Fetch())) {
                $sql = 'UPDATE grants SET privileges=:privileges::INT::BIT(24) ' . $where;
            } else {
                $sqlparms[':by_principal'] = $by_principal;
                $sqlparms[':by_collection'] = $by_collection;
                $sql = 'INSERT INTO grants (by_principal, by_collection, to_principal, privileges) VALUES(:by_principal, :by_collection, :to_principal, :privileges::INT::BIT(24))';
            }
            $sqlparms[':privileges'] = $privileges;
            $qry = new AwlQuery($sql, $sqlparms);
            if ($qry->Exec('ACL', __LINE__, __FILE__)) {
                Principal::cacheDelete('dav_name', $grantee->dav_name());
                Principal::cacheFlush('principal_id IN (SELECT member_id FROM group_member WHERE group_id = ?)', array($grantee_id));
            }
            break;
        case 'DAV::authenticated':
            $principal_type = 'authenticated';
            if (bindec($grantor->GetProperty('default_privileges')) == $privileges) {
                continue;
            }
            // There is no change, so skip it
            $sqlparms = array(':privileges' => $privileges);
            if (isset($by_collection)) {
                $sql = 'UPDATE collection SET default_privileges=:privileges::INT::BIT(24) WHERE collection_id=:by_collection';
                $sqlparms[':by_collection'] = $by_collection;
            } else {
                $sql = 'UPDATE principal SET default_privileges=:privileges::INT::BIT(24) WHERE principal_id=:by_principal';
                $sqlparms[':by_principal'] = $by_principal;
            }
            $qry = new AwlQuery($sql, $sqlparms);
            if ($qry->Exec('ACL', __LINE__, __FILE__)) {
                /**
                 *  Basically this has changed everyone's permissions now, so...
                 */
                Principal::cacheFlush('TRUE');
            }
            break;
        case 'DAV::all':
            //      $principal_type = 'all';
            $request->PreconditionFailed(403, 'allowed-principal', 'May not set privileges for unauthenticated users');
            break;
        default:
            $request->PreconditionFailed(403, 'recognized-principal');
            break;
    }
}