eGroupware

eGroupWare + smbldap-tools integration with SQL hack

By default, smbldap-populate will add groups 'Domain User' with gidnumber 513, and 'Administrators' with gidnumber 544. This can map with eGroupWare's default groups 'Default' and 'Admins'. On the other hand, smbldap-populate will add default administrator account 'root' with uidnumber 0, where it is invalid for eGroupWare (eGroupWare count account id with AUTO_INCREMENT, where starting from 1 and so 0 is invalid). We need some tricks in order to integrate them:


Main difference between nis.schema and rfc2307bis.schema

I give some indeed study for eGroupWare + LDAP, compare its use between nis.schema and rfc2307bis.schema, slapcat and diff their result:

@@ -65,13 +65,15 @@ modifyTimestamp: 20090220182044Z
dn: cn=Default,ou=Group,dc=example,dc=com
objectClass: top
objectClass: posixGroup
+objectClass: groupOfNames
gidNumber: 1
cn: Default
-structuralObjectClass: posixGroup
+structuralObjectClass: groupOfNames
entryUUID: f627d08e-93c6-102d-9537-29575a5ac953
creatorsName: cn=admin,dc=example,dc=com
createTimestamp: 20090220182056Z
memberUid: postmaster
memberUid: tester
+member: uid=postmaster,ou=People,dc=example,dc=com
+member: uid=tester,ou=People,dc=example,dc=com
entryCSN: 20090220182056.968007Z#000000#000#000000
modifiersName: cn=admin,dc=example,dc=com
modifyTimestamp: 20090220182056Z

We can find that:

  1. Need to add the new objectClass: groupOfNames for each group.
  2. Need to replace all structuralObjectClass: posixGroup as structuralObjectClass: groupOfNames.
  3. Need to add required member attribute, e.g. member: uid=postmaster,ou=People,dc=example,dc=com.
  4. (HIDDEN RULE!) We need at least ONE member for each group!. eGroupWare web GUI will not allow group without any member, e.g. you can't create group without member, or delete the last member from a group.

So it is time to study how to patch smbldap-tools with rfc2307bis.schema support. May need some backtrace from eGroupWare logic, e.g. how to support both schema and dynamically switch the use of different syntax :D

Some code snippet from eGroupWare (/var/www/egroupware/phpgwapi/inc/class.accounts_ldap.inc.php):

                        // read the entry first, to check if the dn (account_lid) has changed
                        $sri = $is_group ? ldap_search($this->ds,$this->group_context,'gidnumber='.abs($data['account_id'])) :
                                ldap_search($this->ds,$this->user_context,'uidnumber='.$data['account_id']);
                        $old = ldap_get_entries($this->ds, $sri);

                        if (!$old['count'])
                        {
                                unset($old);
                        }
                        else
                        {
                                $old = $this->_ldap2array($old[0]);
                                foreach($old['objectclass'] as $n => $class)
                                {
                                        $old['objectclass'][$n] = strtolower($class);
                                }

                        $groupOfNames = in_array('groupofnames',$old ? $old['objectclass'] : $to_write['objectclass']);
                        if (!$old && $groupOfNames || $members)
                        {
                                $to_write = array_merge($to_write,$this->set_members($members,
                                        $data['account_id'],$groupOfNames,$dn));
                        }

        function set_members($members,$gid,$groupOfNames=null,$use_cn=null)
        {
                //echo "<p>accounts_ldap::set_members(".print_r($members,true).",$gid)</p>\n";
                if (!($cn = $use_cn) && !($cn = $this->id2name($gid))) return false;

                // do that group is a groupOfNames?
                if (is_null($groupOfNames)) $groupOfNames = $this->id2name($gid,'groupOfNames');

                $to_write = array('memberuid' => array());
                foreach((array)$members as $key => $member)
                {
                        if (is_numeric($member)) $member = $this->id2name($member);

                        if ($member)
                        {
                                $to_write['memberuid'][] = $member;
                                if ($groupOfNames) $to_write['member'][] = 'uid='.$member.','.$this->user_context;
                        }
                }
                if ($groupOfNames && !$to_write['member'])
                {
                        // hack as groupOfNames requires the member attribute
                        $to_write['member'][] = 'uid=dummy'.','.$this->user_context;
                }
                if ($use_cn) return $to_write;

                // set the member email addresses as forwards
                if ($this->id2name($gid,'account_email') &&     ($objectclass = $this->id2name($gid,'mailAllowed')))
                {
                        $forward = $this->group_mail_classes[$objectclass];

                        $to_write[$forward] = array();
                        foreach($members as $key => $member)
                        {
                                if (($email = $this->id2name($member,'account_email'))) $to_write[$forward][] = $email;
                        }
                }
                if (!ldap_modify($this->ds,'cn='.ldap::quote($cn).','.$this->group_context,$to_write))
                {
                        echo "ldap_modify(,'cn=$cn,$this->group_context',".print_r($to_write,true)."))\n";
                        return false;
                }
                return true;
        }


eGroupware + LDAP on Debian lenny mini-HOWTO

NOTE! This is just my personal research progress log. Don't use it as production. If you are asking for some other update details, please refer to LDAP + Samba PDC + PAM/NSS on Debian Lenny HOWTO


Syndicate content