tpokorra / KolabScripts

some scripts useful for Kolab3 and higher, written by TBits.net, including patches already submitted to Kolab Bugzilla
14 stars 13 forks source link

lastLogin: does not update the timestamp in ldap with Kolab 3.3 #39

Closed tpokorra closed 10 years ago

tpokorra commented 10 years ago

current debugging: /usr/lib/python2.6/site-packages/pykolab/auth/ldap/__init__.py (https://git.kolab.org/pykolab/tree/pykolab/auth/ldap/__init__.py), in set_entry_attributes: log.error(sys.exc_info()[0]) log.error(sys.excinfo()[1]) log.error(("Could not update dn %r:\n%r") % (dn, modlist))

shows:

ERROR <class 'ldap.INSUFFICIENT_ACCESS'>
ERROR INSUFFICIENT_ACCESS({'info': "Insufficient 'write' privilege to the 'tbitsKolabLastLogin' attribute of entry 'uid=test2,ou=people,dc=test,dc=pokorra,dc=de'.\n", 'desc': 'Insufficient access'},)

but cn=Directory Manager is used in _bind

But I can modify the value on the command line:

cat > ./ldapparam.txt <<END
dn: uid=test,ou=People,dc=test,dc=pokorra,dc=de
changetype: modify
replace: tbitskolablastlogin
tbitskolablastlogin: 1410252386
END

ldapmodify -x -h localhost -D "cn=Directory Manager" -w $password -f ./ldapparam.txt

I have changed /usr/lib/python2.6/site-packages/pykolab/auth/ldap/auth_cache.py hours=1 to minutes=1 for testing.

tpokorra commented 10 years ago

if there is no lastlogin yet:

ERROR <class 'ldap.PROTOCOL_ERROR'>
ERROR PROTOCOL_ERROR({'info': 'no values given', 'desc': 'Protocol error'},)
ERROR Could not update dn u'uid=test3,ou=People,dc=test,dc=pokorra,dc=de':
[(0, 'tbitskolablastlogin', 1410274268)]
tpokorra commented 10 years ago

see http://www.python-ldap.org/doc/html/ldap.html modify_s

tpokorra commented 10 years ago
ldapsearch -x -h localhost -D "cn=Directory Manager" -w "$password" -b "uid=test2,ou=people,dc=test,dc=pokorra,dc=de" "*"
ldapsearch -x -h localhost -D "cn=Directory Manager" -w "$password" -b "dc=test,dc=pokorra,dc=de" aci

cat > ./ldapparam.txt <<END
dn: dc=test,dc=pokorra,dc=de
changetype: modify
add: aci
aci: (targetattr = "tbitsKolabLastLogin") (version 3.0;acl "LastLoginPermission";allow
  (read,compare,search,write)(userdn = "ldap:///cn=Directory Manager");)
END

ldapmodify -x -h localhost -D "cn=Directory Manager" -w $password -f ldapparam.txt
tpokorra commented 10 years ago

what about latest version python-ldap? https://pypi.python.org/pypi/python-ldap/ shows 2.4.16. we have installed: python-ldap-2.4.6-15.el6.kolab_3.4.x86_64

wget https://pypi.python.org/packages/source/p/python-ldap/python-ldap-2.4.16.tar.gz tar xzf python-ldap-2.4.16.tar.gz cd python-ldap-2.4.16 yum install gcc openldap-devel python-devel python setup.py build python setup.py install

verify installation: easy_install python-ldap # shows: 2.4.16

but it does not solve the ldap.PROTOCOL_ERROR nor the ldap.INSUFFICIENT_ACCESS

tpokorra commented 10 years ago

now I have written a small python test script, that does the same thing:

import _ldap
import ldap
import ldap.async
import ldap.controls
import sys
import time

class MyTest:
   def __init__(self):
        self.ldap = ldap.ldapobject.ReconnectLDAPObject(
                'ldap://localhost:389',
                trace_level=0,
                retry_max=200,
                retry_delay=3.0
            )

        self.ldap.protocol_version = 3
        self.ldap.supported_controls = []

        bind_dn='cn=Directory Manager'
        bind_pw='test'
        try:
            self.ldap.simple_bind_s(bind_dn, bind_pw)
        except ldap.SERVER_DOWN:
           print("server down.")
        except ldap.INVALID_CREDENTIALS:
           print("Invalid DN, username and/or password.")

        dn="uid=test2,ou=People,dc=test,dc=pokorra,dc=de"
        modlist=[(ldap.MOD_REPLACE, 'tbitsKolabLastLogin', str(int(time.time())))]
        try:
           if self.ldap.modify_s(dn, modlist):
             print("modification was successful!")
        except:
           print("Could not update dn %r:\n%r" % (dn, modlist))
           print("%r" % (sys.exc_info()[0]))
           print("%r" % (sys.exc_info()[1]))
           print("%r" % (sys.exc_info()[2]))
           print("--------")

        dn="uid=test2,ou=People,dc=test,dc=pokorra,dc=de"
        modlist=[(ldap.MOD_DELETE, 'tbitskolablastlogin', None)]
        try:
           if self.ldap.modify_s(dn, modlist):
             print("delete was successful!")
        except:
           print("Could not update dn %r:\n%r" % (dn, modlist))
           print("%r" % (sys.exc_info()[0]))
           print("%r" % (sys.exc_info()[1]))
           print("%r" % (sys.exc_info()[2]))
           print("--------")

        dn="uid=test2,ou=People,dc=test,dc=pokorra,dc=de"
        modlist=[(ldap.MOD_ADD, 'tbitskolablastlogin', str(int(time.time())))]
        try:
           if self.ldap.modify_s(dn, modlist):
             print("add was successful!")
        except:
           print("Could not update dn %r:\n%r" % (dn, modlist))
           print("%r" % (sys.exc_info()[0]))
           print("%r" % (sys.exc_info()[1]))
           print("%r" % (sys.exc_info()[2]))
           print("--------")

myApp=MyTest()

it seems it works if the timestamp is passed as a string. it fails if it is an integer.

tpokorra commented 10 years ago

ok, the problem was that the call self.ldap.simple_bind_s with the dn of the user: https://git.kolab.org/pykolab/tree/pykolab/auth/ldap/__init__.py#n221 therefore we were not connected with directory manager anymore!