From: <Mik...@op...> - 2009-08-04 16:25:00
|
Hi, I'm not sure if this is the right place for this query, but I couldn't find a python-LDAP-Users list. I'm trying to modify a user's password on an Windows 2003 Active directory using passwd_s, however the server is returning the following error: {'info': '0000203D: LdapErr: DSID-0C090C7D, comment: Unknown extended request OID, data 0, vece', 'desc': 'Protocol error'} I realise this is a server configuration thing as opposed to a python-ldap issue, but google hasn't been any help so far. Does anyone here know what it is I need to enable/change in order to get it to work? The connection is using ldaps:// on port 636 and I can search the AD and modify other values eg givenName etc, just not passwords, and I'm binding as domain administrator. Thanks Mike Peters "This message is intended for the named recipient only and may be privileged and/or confidential. If you are not the intended or named recipient or have received this email in error then you should not copy forward or disclose it to any other persons. If you have received this email in error you should destroy it and contact the sender so that we may take appropriate action. The views and opinions expressed in this email may not represent the views and opinions of Open International Limited or any of its subsidiaries and are made without prejudice and subject to contract. The Company Reserves the right to intercept and review all email communications." Open International Limited. Registered Office: Buckholt Drive, Warndon, Worcester, WR4 9SR. Registered in England. Registered No: 05716519 |
From: Michael S. <mi...@st...> - 2009-08-04 16:29:16
|
Mik...@op... wrote: > > I'm not sure if this is the right place for this query, but I couldn't > find a python-LDAP-Users list. > > I'm trying to modify a user's password on an Windows 2003 Active > directory using passwd_s, however the server is returning the following > error: > > {'info': '0000203D: LdapErr: DSID-0C090C7D, comment: Unknown extended > request OID, data 0, vece', 'desc': 'Protocol error'} > > I realise this is a server configuration thing as opposed to a > python-ldap issue, but google hasn't been any help so far. Does anyone > here know what it is I need to enable/change in order to get it to work? This is because Windows 2003 AD does not support the LDAP Password Modify Extended Operation (see RFC 3062). > The connection is using ldaps:// on port 636 and I can search the AD and > modify other values eg givenName etc, just not passwords, and I'm > binding as domain administrator. There's a MSDN article about how to set attribute unicodePwd via LDAP in AD. Ciao, Michael. |
From: <Mik...@op...> - 2009-08-04 16:48:08
|
Michael, Thanks for the quick response, much appreciated. I guess I've been barking up the wrong tree then :) If I try the alternative method however: mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', 'password' )] dn = 'CN=Barney Rubble,OU=Users,DC=mydomain,dc=local' r = l.modify_s(dn, mod_attrs) I get: {'info': '0000001F: SvcErr: DSID-031A0FC0, problem 5003 (WILL_NOT_PERFORM), data 0\n', 'desc': 'Server is unwilling to perform'} I guess I'm still missing something :( One thing which may be relevant is if I use l.start_tls_s() before simple_bind_s, the login fails although without start_tls_s Wireshark shows the connection to be encrypted. Thanks again Mike Peters > -----Original Message----- > From: Michael Ströder [mailto:mi...@st...] > Sent: 04 August 2009 17:29 > To: Mike Peters > Cc: pyt...@li... > Subject: Re: ldap.passwd_s with Active Direcory > > Mik...@op... wrote: > > > > I'm not sure if this is the right place for this query, but I > couldn't > > find a python-LDAP-Users list. > > > > I'm trying to modify a user's password on an Windows 2003 Active > > directory using passwd_s, however the server is returning the > following > > error: > > > > {'info': '0000203D: LdapErr: DSID-0C090C7D, comment: Unknown extended > > request OID, data 0, vece', 'desc': 'Protocol error'} > > > > I realise this is a server configuration thing as opposed to a > > python-ldap issue, but google hasn't been any help so far. Does > anyone > > here know what it is I need to enable/change in order to get it to > work? > > This is because Windows 2003 AD does not support the LDAP Password > Modify > Extended Operation (see RFC 3062). > > > The connection is using ldaps:// on port 636 and I can search the AD > and > > modify other values eg givenName etc, just not passwords, and I'm > > binding as domain administrator. > > There's a MSDN article about how to set attribute unicodePwd via LDAP > in AD. > > Ciao, Michael. |
From: Michael S. <mi...@st...> - 2009-08-04 17:23:46
|
Mik...@op... wrote: > >> There's a MSDN article about how to set attribute unicodePwd via LDAP >> in AD. > > If I try the alternative method however: > > mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', 'password' )] > dn = 'CN=Barney Rubble,OU=Users,DC=mydomain,dc=local' > r = l.modify_s(dn, mod_attrs) > > I get: > > {'info': '0000001F: SvcErr: DSID-031A0FC0, problem 5003 (WILL_NOT_PERFORM), data 0\n', 'desc': 'Server is unwilling to perform'} > > I guess I'm still missing something :( Did you search for the MSDN article? The value has to be in your case above: '"password"'.encode('utf-16-le') Note the quotes and the UTF-16 low-endian encoding. > One thing which may be relevant is if I use l.start_tls_s() before > simple_bind_s, the login fails although without start_tls_s Wireshark shows > the connection to be encrypted. With AD the connection has to be encrypted for write access to unicodePwd but that can also be done with ldaps:// on port 636. Ciao, Michael. |
From: <Mik...@op...> - 2009-08-05 14:55:58
|
> -----Original Message----- > From: Michael Ströder [mailto:mi...@st...] > Sent: 04 August 2009 18:23 > To: Mike Peters > Cc: pyt...@li... > Subject: Re: ldap.passwd_s with Active Direcory > > Mik...@op... wrote: > > > >> There's a MSDN article about how to set attribute unicodePwd via > LDAP > >> in AD. > > > > If I try the alternative method however: > > > > mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', 'password' )] > > dn = 'CN=Barney Rubble,OU=Users,DC=mydomain,dc=local' > > r = l.modify_s(dn, mod_attrs) > > > > I get: > > > > {'info': '0000001F: SvcErr: DSID-031A0FC0, problem 5003 > (WILL_NOT_PERFORM), data 0\n', 'desc': 'Server is unwilling to > perform'} > > > > I guess I'm still missing something :( > > Did you search for the MSDN article? The value has to be in your case > above: > > '"password"'.encode('utf-16-le') > > Note the quotes and the UTF-16 low-endian encoding. > Thanks again for your help. I tried that but to no avail. I still get the same error. Do you know if the fact I'm accessing the server over a VPN would make any difference? Mike Peters |
From: Russell J. <ra...@cs...> - 2009-08-05 15:33:16
Attachments:
signature.asc
|
Mik...@op... wrote: >> -----Original Message----- >> From: Michael Ströder [mailto:mi...@st...] >> Sent: 04 August 2009 18:23 >> To: Mike Peters >> Cc: pyt...@li... >> Subject: Re: ldap.passwd_s with Active Direcory >> >> Mik...@op... wrote: >>>> There's a MSDN article about how to set attribute unicodePwd via >> LDAP >>>> in AD. >>> If I try the alternative method however: >>> >>> mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', 'password' )] >>> dn = 'CN=Barney Rubble,OU=Users,DC=mydomain,dc=local' >>> r = l.modify_s(dn, mod_attrs) >>> >>> I get: >>> >>> {'info': '0000001F: SvcErr: DSID-031A0FC0, problem 5003 >> (WILL_NOT_PERFORM), data 0\n', 'desc': 'Server is unwilling to >> perform'} >>> I guess I'm still missing something :( >> Did you search for the MSDN article? The value has to be in your case >> above: >> >> '"password"'.encode('utf-16-le') >> >> Note the quotes and the UTF-16 low-endian encoding. >> > > Thanks again for your help. I tried that but to no avail. I still get the same error. Do you know if the fact I'm accessing the server over a VPN would make any difference? > For what it's worth, this is the working code I use to set the password. I didn't realize you could use the -le suffix to get an encoding without the byte order mark which I've just been stripping off. The example posted above should be equivalent. ldap_conn.modify_s(dn, [ ( ldap.MOD_REPLACE, 'unicodePwd', ''.join(('"', pwd, '"')).encode('utf-16').lstrip('\377\376'), ) ]) Another thing to note is that the connection must be under a TLS layer. -- Russell A. Jackson <ra...@cs...> Network Analyst California State University, Bakersfield Excellent day to have a rotten day. |
From: Michael S. <mi...@st...> - 2009-08-05 15:11:41
|
Mik...@op... wrote: > Michael Ströder wrote: >> Did you search for the MSDN article? The value has to be in your case >> above: >> >> '"password"'.encode('utf-16-le') >> >> Note the quotes and the UTF-16 low-endian encoding. > > Thanks again for your help. I tried that but to no avail. I still get the > same error. It should work. It's the way I've implemented it in web2ldap. You must use either LDAPS or StartTLS ext.op. You might wanna look what's going on by setting trace_level=2 when calling ldap.initialize(). > Do you know if the fact I'm accessing the server over a VPN > would make any difference? AD enforces that to work solely over an encrypted connection. A VPN is outside the connection handling of AD so this won't work. Ciao, Michael. |
From: <Mik...@op...> - 2009-08-05 16:09:37
|
> -----Original Message----- > From: Michael Ströder [mailto:mi...@st...] > Sent: 05 August 2009 16:11 > To: Mike Peters > Cc: pyt...@li... > Subject: Re: ldap.passwd_s with Active Direcory > > Mik...@op... wrote: > > Michael Ströder wrote: > >> Did you search for the MSDN article? The value has to be in your > case > >> above: > >> > >> '"password"'.encode('utf-16-le') > >> > >> Note the quotes and the UTF-16 low-endian encoding. > > > > Thanks again for your help. I tried that but to no avail. I still get > the > > same error. > > It should work. It's the way I've implemented it in web2ldap. You must > use > either LDAPS or StartTLS ext.op. > > You might wanna look what's going on by setting trace_level=2 when > calling > ldap.initialize(). > With trace_level=2 I get the following: In [1]: import ldap In [2]: l = ldap.initialize("ldaps://ad01.demo.local:636", trace_level=2) *** ldaps://ad01.demo.local:636 - SimpleLDAPObject.set_option ((17, 3),{}) In [3]: l.simple_bind_s(u'user@ADDEMO', u'secret') *** ldaps://ad01.demo.local:636 - SimpleLDAPObject.simple_bind ((u'user@ADDEMO', u'secret', None, None),{}) => result: 1 *** ldaps://ad01.demo.local:636 - SimpleLDAPObject.result3 ((1, 1, -1),{}) => result: (97, [], 1, []) Out[3]: (97, []) In [4]: mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', '"password"'.encode('utf-16-le') )] In [5]: dn = 'CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local' In [6]: r = l.modify_s(dn, mod_attrs)*** ldaps://ad01.demo.local:636 - SimpleLDAPObject.modify_ext (('CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local', [(2, 'unicodePwd', '"\x00p\x00a\x00s\x00s\x00w\x00o\x00r\x00d\x00"\x00')], None, None),{}) => result: 2 *** ldaps://ad01.demo.local:636 - SimpleLDAPObject.result3 ((2, 1, -1),{}) => LDAPError - UNWILLING_TO_PERFORM: {'info': '0000052D: SvcErr: DSID-031A0FC0, problem 5003 (WILL_NOT_PERFORM), data 0\n', 'desc': 'Server is unwilling to perform'} ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (134, 0)) --------------------------------------------------------------------------- UNWILLING_TO_PERFORM Traceback (most recent call last) /home/django/pplace/<ipython console> in <module>() /usr/lib/python2.5/site-packages/ldap/ldapobject.pyc in modify_s(self, dn, modlist) 326 def modify_s(self,dn,modlist): 327 msgid = self.modify(dn,modlist) --> 328 return self.result(msgid,all=1,timeout=self.timeout) 329 330 def modrdn(self,dn,newrdn,delold=1): /usr/lib/python2.5/site-packages/ldap/ldapobject.pyc in result(self, msgid, all, timeout) 426 polling (timeout = 0), in which case (None, None) is returned. 427 """ --> 428 res_type,res_data,res_msgid = self.result2(msgid,all,timeout) 429 return res_type,res_data 430 /usr/lib/python2.5/site-packages/ldap/ldapobject.pyc in result2(self, msgid, all, timeout) 430 431 def result2(self,msgid=_ldap.RES_ANY,all=1,timeout=None): --> 432 res_type, res_data, res_msgid, srv_ctrls = self.result3(msgid,all,timeout) 433 return res_type, res_data, res_msgid 434 /usr/lib/python2.5/site-packages/ldap/ldapobject.pyc in result3(self, msgid, all, timeout) 436 if timeout is None: 437 timeout = self.timeout --> 438 ldap_result = self._ldap_call(self._l.result3,msgid,all,timeout) 439 if ldap_result is None: 440 rtype, rdata, rmsgid, decoded_serverctrls = (None,None,None,None) /usr/lib/python2.5/site-packages/ldap/ldapobject.pyc in _ldap_call(self, func, *args, **kwargs) 94 try: 95 try: ---> 96 result = func(*args,**kwargs) 97 finally: 98 self._ldap_object_lock.release() UNWILLING_TO_PERFORM: {'info': '0000052D: SvcErr: DSID-031A0FC0, problem 5003 (WILL_NOT_PERFORM), data 0\n', 'desc': 'Server is unwilling to perform'} Does the encoded password look right? Thanks Mike Peters |
From: Michael S. <mi...@st...> - 2009-08-06 02:18:40
|
Mik...@op... wrote: > *** ldaps://ad01.demo.local:636 - SimpleLDAPObject.simple_bind ((u'user@ADDEMO', u'secret', None, None),{}) First of all you should not pass Unicode strings to python-ldap. That's not a problem for the actual values you used though in this example but in general up to now python-ldap only receives raw strings as arguments. > In [4]: mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', '"password"'.encode('utf-16-le') )] > In [5]: dn = 'CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local' > > In [6]: r = l.modify_s(dn, mod_attrs)*** ldaps://ad01.demo.local:636 - SimpleLDAPObject.modify_ext (('CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local', [(2, 'unicodePwd', '"\x00p\x00a\x00s\x00s\x00w\x00o\x00r\x00d\x00"\x00')], None, None),{}) Unfortunately I can't tell whether user@ADDEMO and CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local are the same AD user entry. I vaguely remember that when setting your own password you have to explicitly delete the old one and add the new one. Dig for the MSDN article. Ciao, Michael. |
From: <Mik...@op...> - 2009-08-06 15:14:42
|
> -----Original Message----- > From: Michael Ströder [mailto:mi...@st...] > Sent: 06 August 2009 00:49 > To: Mike Peters > Cc: pyt...@li... > Subject: Re: ldap.passwd_s with Active Direcory > > Mik...@op... wrote: > > *** ldaps://ad01.demo.local:636 - SimpleLDAPObject.simple_bind > ((u'user@ADDEMO', u'secret', None, None),{}) > > First of all you should not pass Unicode strings to python-ldap. That's > not a > problem for the actual values you used though in this example but in > general > up to now python-ldap only receives raw strings as arguments. OK, thanks. I'll bear that in mind. > > > In [4]: mod_attrs = [( ldap.MOD_REPLACE, 'unicodePwd', > '"password"'.encode('utf-16-le') )] > > In [5]: dn = 'CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local' > > > > In [6]: r = l.modify_s(dn, mod_attrs)*** ldaps://ad01.demo.local:636 > - SimpleLDAPObject.modify_ext (('CN=Barney > Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local', [(2, 'unicodePwd', > '"\x00p\x00a\x00s\x00s\x00w\x00o\x00r\x00d\x00"\x00')], None, None),{}) > > Unfortunately I can't tell whether > user@ADDEMO and CN=Barney Rubble,OU=Users,OU=ADDEMO,DC=demo,DC=local > are the same AD user entry. > > I vaguely remember that when setting your own password you have to > explicitly > delete the old one and add the new one. Dig for the MSDN article. > No, I'm using a different user. I've tried a couple of different users including Administrator in case it is user permissions. I've looked at the MSDN article and can't see anything in there different. Thanks Mike Peters |
From: Michael S. <mi...@st...> - 2009-08-06 15:20:34
|
Mik...@op... wrote: > No, I'm using a different user. I've tried a couple of different users > including Administrator in case it is user permissions. I've looked at the > MSDN article and can't see anything in there different. Strange enough exactly this works just fine with my web2ldap which uses python-ldap. Ciao, Michael. |