From: Zhang H. <zhb...@gm...> - 2009-09-09 05:33:11
|
Hi, all. What's the best way to 'replace' value of attribute which can handle multiple values? Such as: dn: uid=myuid,dc=example,dc=com cn: cn1 cn: cn2 cn: cn3 My purpose is to get ldif like this (no cn=cn2 any more): dn: uid=myuid,dc=example,dc=com cn: cn1 cn: cn3 cn: cn4 I want to replace cn=cn2 by cn=cn4 if it exist, or add cn=cn4 directly if 'cn=cn2' donesn't exist. If cn=cn2 is not exist, [(ldap.MOD_DELETE, 'cn', 'cn2')] will raise an error. If cn=cn2 is not exist, [(ldap.MOD_ADD, 'cn', 'cn4')] will add cn=cn4, but can't delete 'cn=cn2'. Thanks very much. :) -- Best Regards. Zhang Huangbin - Open Source Mail Server Solution for Red Hat(R) Enterprise Linux, CentOS, Debian, Ubuntu: http://www.iredmail.org/ |
From: Michael S. <mi...@st...> - 2009-09-09 08:55:02
|
Zhang Huangbin wrote: > What's the best way to 'replace' value of attribute which can handle > multiple values? > > Such as: > > dn: uid=myuid,dc=example,dc=com > cn: cn1 > cn: cn2 > cn: cn3 > > My purpose is to get ldif like this (no cn=cn2 any more): > > dn: uid=myuid,dc=example,dc=com > cn: cn1 > cn: cn3 > cn: cn4 > > I want to replace cn=cn2 by cn=cn4 if it exist, or add cn=cn4 directly > if 'cn=cn2' donesn't exist. > > If cn=cn2 is not exist, [(ldap.MOD_DELETE, 'cn', 'cn2')] will raise an > error. Could you please post the error raised and mention with which server you're testing? I'd try [(ldap.MOD_DELETE, 'cn',['cn2'])] > If cn=cn2 is not exist, [(ldap.MOD_ADD, 'cn', 'cn4')] will add cn=cn4, > but can't delete 'cn=cn2'. Try this: [(ldap.MOD_ADD, 'cn',['cn4'])] In general for this to work the server has to have an EQUALITY matching rule defined for the attribute type in question and implement this matching rule. This should be the case for 'cn' alias 'commonName' but one never knows for sure. In web2ldap I have implemented a variant of the function ldap.modlist.modifyModlist() which looks at the schema to determine use of EQUALITY matching rule and generate the diff accordingly. Ciao, Michael. |
From: Zhang H. <zhb...@gm...> - 2009-09-09 09:22:28
|
Thanks for your reply, Michael. :) On Sep 9, 2009, at 4:54 PM, Michael Ströder wrote: >> If cn=cn2 is not exist, [(ldap.MOD_DELETE, 'cn', 'cn2')] will raise >> an >> error. > > Could you please post the error raised and mention with which server > you're > testing? > > I'd try [(ldap.MOD_DELETE, 'cn',['cn2'])] The same error if cn=cn2 not exist: ldap.NO_SUCH_ATTRIBUTE. > >> If cn=cn2 is not exist, [(ldap.MOD_ADD, 'cn', 'cn4')] will add >> cn=cn4, >> but can't delete 'cn=cn2'. > > Try this: [(ldap.MOD_ADD, 'cn',['cn4'])] It can't delete cn=cn2. And same error raised while cn=cn4 exists: ldap.TYPE_OR_VALUE_EXISTS. I created a function to perform similar request moment ago, but still looking for a better way: ------- class LDAPWrap: def __init__(self): ... skip some lines ... self.conn = ldap.initialize(xxx) ... skip some lines ... def addOrDelAttrValue(self, dn, attr, value, type): """Used to add or replace value of attribute which can handle multiple values. @type: add, delete. """ self.dn = ldap.filter.escape_filter_chars(dn) if type == 'add': try: self.conn.modify_s(self.dn, [(ldap.MOD_ADD, attr, value)]) return (True, 'SUCCESS') except ldap.TYPE_OR_VALUE_EXISTS: return (True, 'SUCCESS') except Exception, e: return (False, str(e)) elif type == 'delete': try: self.conn.modify_s(self.dn, [(ldap.MOD_DELETE, attr, value)]) return (True, 'SUCCESS') except ldap.NO_SUCH_ATTRIBUTE: return (True, 'SUCCESS') except Exception, e: return (False, str(e)) ----- Thanks very much :) -- Best Regards. Zhang Huangbin - Open Source Mail Server Solution for Red Hat(R) Enterprise Linux, CentOS, Debian, Ubuntu: http://www.iredmail.org/ |
From: Michael S. <mi...@st...> - 2009-09-09 10:02:51
|
Zhang Huangbin wrote: > On Sep 9, 2009, at 4:54 PM, Michael Ströder wrote: >>> If cn=cn2 is not exist, [(ldap.MOD_DELETE, 'cn', 'cn2')] will raise >>> an >>> error. >> Could you please post the error raised and mention with which server >> you're >> testing? >> >> I'd try [(ldap.MOD_DELETE, 'cn',['cn2'])] > > The same error if cn=cn2 not exist: ldap.NO_SUCH_ATTRIBUTE. And how about the diagnostic message? I'd test the code with trace_level=2. Ciao, Michael. |
From: Zhang H. <zhb...@gm...> - 2009-09-09 12:08:43
|
On Sep 9, 2009, at 6:02 PM, Michael Ströder wrote: > Zhang Huangbin wrote: >> On Sep 9, 2009, at 4:54 PM, Michael Ströder wrote: >>>> If cn=cn2 is not exist, [(ldap.MOD_DELETE, 'cn', 'cn2')] will raise >>>> an >>>> error. >>> Could you please post the error raised and mention with which server >>> you're >>> testing? >>> >>> I'd try [(ldap.MOD_DELETE, 'cn',['cn2'])] >> >> The same error if cn=cn2 not exist: ldap.NO_SUCH_ATTRIBUTE. > > And how about the diagnostic message? I'd test the code with > trace_level=2. bind dn: cn=vmailadmin,dc=iredmail,dc=org operation: [(ldap.MOD_DELETE, 'enabledService', 'forward')] ldif: ---- dn: mail=test22@a.cn,ou=Users,domainName=a.cn,o=domains,dc=iredmail,dc=org enabledService: smtp enabledService: imap enabledService: pop3 enabledService: deliver ---- Below is console log with 'trace_level=2': ------------ *** ldap://127.0.0.1:389 - SimpleLDAPObject.set_option ((17, 3),{}) *** ldap://127.0.0.1:389 - SimpleLDAPObject.set_option ((17, 3),{}) *** ldap://127.0.0.1:389 - SimpleLDAPObject.simple_bind (('cn=vmailadmin,dc=iredmail,dc=org', 'passwd', None, None),{}) => result: 1 *** ldap://127.0.0.1:389 - SimpleLDAPObject.result3 ((1, 1, -1),{}) => result: (97, [], 1, []) *** ldap://127.0.0.1:389 - SimpleLDAPObject.modify_ext (('mail=test22@a.cn ,ou=Users,domainName=a.cn,o=domains,dc=iredmail,dc=org', [(1, 'enabledService', 'forward')], None, None),{}) => result: 3 *** ldap://127.0.0.1:389 - SimpleLDAPObject.result3 ((3, 1, -1),{}) => LDAPError - NO_SUCH_ATTRIBUTE: {'info': 'modify/delete: enabledService: no such value', 'desc': 'No such attribute'} Traceback (most recent call last): File "/usr/lib/python2.4/site-packages/web.py-0.32-py2.4.egg/web/ application.py", line 242, in process return self.handle() File "/usr/lib/python2.4/site-packages/web.py-0.32-py2.4.egg/web/ application.py", line 233, in handle return self._delegate(fn, self.fvars, args) File "/usr/lib/python2.4/site-packages/web.py-0.32-py2.4.egg/web/ application.py", line 412, in _delegate return handle_class(cls) File "/usr/lib/python2.4/site-packages/web.py-0.32-py2.4.egg/web/ application.py", line 387, in handle_class return tocall(*args) File "/var/www/iredadmin/controllers/ldap/base.py", line 23, in proxyfunc return func(self, *args, **kw) File "/var/www/iredadmin/controllers/ldap/user.py", line 106, in POST data=i, File "/var/www/iredadmin/libs/ldaplib/core.py", line 149, in proxyfunc return func(self, *args, **kw) File "/var/www/iredadmin/libs/ldaplib/user.py", line 165, in update self.conn.modify_s(self.dn, [(ldap.MOD_DELETE, 'enabledService', 'forward')]) File "/usr/lib/python2.4/site-packages/python_ldap-2.3.9-py2.4- linux-x86_64.egg/ldap/ldapobject.py", line 328, in modify_s return self.result(msgid,all=1,timeout=self.timeout) File "/usr/lib/python2.4/site-packages/python_ldap-2.3.9-py2.4- linux-x86_64.egg/ldap/ldapobject.py", line 428, in result res_type,res_data,res_msgid = self.result2(msgid,all,timeout) File "/usr/lib/python2.4/site-packages/python_ldap-2.3.9-py2.4- linux-x86_64.egg/ldap/ldapobject.py", line 432, in result2 res_type, res_data, res_msgid, srv_ctrls = self.result3 (msgid,all,timeout) File "/usr/lib/python2.4/site-packages/python_ldap-2.3.9-py2.4- linux-x86_64.egg/ldap/ldapobject.py", line 438, in result3 ldap_result = self._ldap_call(self._l.result3,msgid,all,timeout) File "/usr/lib/python2.4/site-packages/python_ldap-2.3.9-py2.4- linux-x86_64.egg/ldap/ldapobject.py", line 96, in _ldap_call result = func(*args,**kwargs) NO_SUCH_ATTRIBUTE: {'info': 'modify/delete: enabledService: no such value', 'desc': 'No such attribute'} *** ldap://127.0.0.1:389 - SimpleLDAPObject.unbind_ext ((None, None),{}) 192.168.6.1:49306 - - [28/Jun/2009 14:42:21] "HTTP/1.1 POST /profile/user/forwarding/test22@a.cn " - 500 Internal Server Error ---------- -- Best Regards. Zhang Huangbin - Open Source Mail Server Solution for Red Hat(R) Enterprise Linux, CentOS, Debian, Ubuntu: http://www.iredmail.org/ |
From: Michael S. <mi...@st...> - 2009-09-09 14:11:26
|
Zhang Huangbin wrote: > NO_SUCH_ATTRIBUTE: {'info': 'modify/delete: enabledService: no such > value', 'desc': 'No such attribute'} This means the attribute 'enabledService' is not available in the entry at all. So you can't remove a certain attribute value from it. Ciao, Michael. |
From: Zhang H. <zhb...@gm...> - 2009-09-09 14:09:42
|
On Sep 9, 2009, at 9:32 PM, Michael Ströder wrote: > Zhang Huangbin wrote: >> NO_SUCH_ATTRIBUTE: {'info': 'modify/delete: enabledService: no such >> value', 'desc': 'No such attribute'} > > This means the attribute 'enabledService' is not available in the > entry at > all. So you can't remove a certain attribute value from it. > > Ciao, Michael. Attribute is present, but not contains value 'forwrad'. As i posted in previous mail, the ldif data before we invoke .modify_s () is: ---- dn: xxx enabledService: mail enabledService: smtp enabledService: pop3 enabledService: imap enabledService: deliver ---- -- Best Regards. Zhang Huangbin - Open Source Mail Server Solution for Red Hat(R) Enterprise Linux, CentOS, Debian, Ubuntu: http://www.iredmail.org/ |
From: Michael S. <mi...@st...> - 2009-09-09 13:57:39
|
Zhang Huangbin wrote: > > On Sep 9, 2009, at 9:32 PM, Michael Ströder wrote: > >> Zhang Huangbin wrote: >>> NO_SUCH_ATTRIBUTE: {'info': 'modify/delete: enabledService: no such >>> value', 'desc': 'No such attribute'} >> >> This means the attribute 'enabledService' is not available in the >> entry at >> all. So you can't remove a certain attribute value from it. >> > Attribute is present, but not contains value 'forwrad'. Then it will simply fail. If you have to handle such optional cases you probably have to sort that out at the client side in some way. I'd read the whole attribute value list, tweak it and replace it. BTW: That's why ldap.modlist.modifyModlist() was implemented. Ciao, Michael. |
From: Zhang H. <zhb...@gm...> - 2009-09-09 14:00:47
|
On Sep 9, 2009, at 9:48 PM, Michael Ströder wrote: > BTW: That's why > ldap.modlist.modifyModlist() was implemented. Any example? There is no example in official python-ldap document: http://www.python-ldap.org/doc/html/ldap-modlist.html?highlight=modifymodlist#ldap.modlist.modifyModlist Thanks very much. :) -- Best Regards. Zhang Huangbin - Open Source Mail Server Solution for Red Hat(R) Enterprise Linux, CentOS, Debian, Ubuntu: http://www.iredmail.org/ |
From: Michael S. <mi...@st...> - 2009-09-09 13:58:52
|
Zhang Huangbin wrote: > > On Sep 9, 2009, at 9:48 PM, Michael Ströder wrote: > >> BTW: That's why >> ldap.modlist.modifyModlist() was implemented. > > Any example? > > There is no example in official python-ldap document: > http://www.python-ldap.org/doc/html/ldap-modlist.html?highlight=modifymodlist#ldap.modlist.modifyModlist >>> import ldap.modlist >>> ldap.modlist.modifyModlist({'cn':'Mike'},{'cn':'Michael Stroeder','mail':'mi...@st...'}) [(0, 'mail', 'mi...@st...'), (1, 'cn', None), (0, 'cn', 'Michael Stroeder')] So basically you read the old_entry dict with an search operation, derive a new_entry dict from it, tweak that and pass old_entry and new_entry to this function. Ciao, Michael. |