本文介绍了鉴定到Active Directory中的python-LDAP总是返回(97,[])的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类似于this问题,我想进行简单的身份验证到2003活动目录使用Python LDAP(CentOS的6.2 x86_64的,Python的2.6.6,蟒蛇,LDAP 2.3.10)。

尽管下面的步骤如常在init,包括

  conn.set_option(ldap.OPT_REFERRALS,0)
 

如果我通过正确的凭据我的总是的获得(97,[])返回:

 >>>导入LDAP
>>>康恩= ldap.initialize('LDAP://ad.server.domain.com)
>>> conn.protocol_version = 3
>>> conn.set_option(ldap.OPT_REFERRALS,0)
>>> conn.simple_bind_s('[email protected]','WrongPassword')
ldap.INVALID_CREDENTIALS:{'信息':'80090308:LdapErr:DSID-0C090334,注释:AcceptSecurityContext错误,数据52E,vece,说明:凭据无效}
>>> conn.simple_bind_s('[email protected]','CorrectPassword')
(97,[])
 

错误code 97并不成功;这是 LDAP_REFERRAL_LIMIT_EXCEEDED 错误从公元返回。我也可以把它作为一个的实际上的成功指标,因为:

 >>> conn.simple_bind_s('','CorrectPassword')
(97,[])
>>> conn.simple_bind_s('','')
(97,[])
 

更令人沮丧的是,这个剧本是从一个古老的Perl脚本使用网:: LDAP的迁移,其中的确实的返回0为成功认证绑定到相同的AD和服务器。

所有的信息,我可以找到有关python-LDAP表示我做的应该只是工作;我会倾向于认为有一些错误的AD服务器,但Perl脚本不会返回正确的LDAP code上的成功绑定。

我已经测试的python-LDAP 2.2.0和2.4.4的Python在一个旧的CentOS 5.5中我已经躺在周围,在完全相同的方式为失败。

有谁知道我缺少的是什么?

编辑:每个请求,这里是Perl脚本的作品。 的Net :: LDAP 返回从LDAP服务器返回的code,和AD服务器返回0x00时,请求成功,AFAICT。

 #!的/ usr / bin中/ perl的-w
使用严格的;
使用网:: LDAP;

##公司的子域
我@domains =(美洲,亚洲,欧洲);

#AD连接超时
我的$超时= 10;
#设置AD服务器信息。
我的$端口=389;
我的$主机=server.domain.com;

我的$ USER =转移@ARGV;
格格$用户;

我的$密码=< STDIN取代;
$密码=〜S / \ r \ñ//;
格格$密码;

我的$ LDAP =网:: LDAP的>新建($主机,端口=> $端口,超时=> $超时)||
        死无法连接到LDAP服务器;

我的$ bind_return = 1;
的foreach(@domains){
        我的$结果= $ LDAP->绑定($ USER \ @ $ _ domain.com,密码=> $密码);
        如果($ result-> code == 0){
                $ bind_return = 0;
                持续;
        }
}

##取消绑定和返回
$ LDAP->解除;

如果($ bind_return){打印验证失败。拒绝访问\ N}
退出$ bind_return;
 

解决方案

迈克尔Ströder,蟒蛇,LDAP库的作者,开导我是这样的:

 相关搜索:
  conn.simple_bind_s('[email protected]','WrongPassword')
除了ldap.INVALID_CREDENTIALS:
  user_error_msg('提供了错误的密码)
 

之所以这些结果:

 >>> conn.simple_bind_s('','CorrectPassword')
(97,[])
>>> conn.simple_bind_s('','')
(97,[])
 

是开箱即用2003的Active Directory 允许匿名绑定。因此,不提供用户ID都仍然会通过一个简单的绑定检查,如果被测试的唯一的事情是,是否 simple_bind_s()抛出一个错误。

2003 Active Directory中的确实的要求对不属于RootDSE的属性,所以我们内部的目的,我们增加了一个简单的搜索,以搜索任何认证尝试:块:

 相关搜索:
  conn.simple_bind_s('[email protected]','SubmittedPassword')
  conn.search_st(DC =域,DC = COM,ldap.SCOPE_SUBTREE,'(对象类=容器)','名',0,30)
除了ldap.INVALID_CREDENTIALS:
  user_error_msg('提供了错误的密码)
 

Similar to this question, I am trying to perform simple authentication to a 2003 Active Directory using python ldap (CentOS 6.2 x86_64, Python 2.6.6, python-ldap 2.3.10).

Despite following all the usual steps in the init, including

conn.set_option(ldap.OPT_REFERRALS, 0)

if I pass the correct credentials I always get a (97, []) returned:

>>> import ldap
>>> conn = ldap.initialize('ldap://ad.server.domain.com')
>>> conn.protocol_version = 3
>>> conn.set_option(ldap.OPT_REFERRALS, 0)
>>> conn.simple_bind_s('[email protected]', 'WrongPassword')
ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece', 'desc': 'Invalid credentials'}
>>> conn.simple_bind_s('[email protected]', 'CorrectPassword')
(97, [])

Error code 97 is not a success; it's the LDAP_REFERRAL_LIMIT_EXCEEDED error being returned from AD. Nor can I use it as a de facto success indicator, because:

>>> conn.simple_bind_s('', 'CorrectPassword')
(97, [])
>>> conn.simple_bind_s('', '')
(97, [])

Even more frustrating is that this script is a migration from an old Perl script using Net::LDAP, which does return 0 for a successful authenticated bind to the same AD and server.

All the information I can find on python-ldap indicates that what I am doing should Just Work; I would be inclined to think there's something wrong with the AD servers, but the Perl script does return the correct LDAP code on a successful bind.

I have tested python-ldap 2.2.0 and python 2.4.4 on an old CentOS 5.5 box I had lying around and it "fails" in exactly the same way.

Does anyone know what I am missing?

EDIT: Per request, here is the Perl script that works. Net::LDAP returns the return code from the LDAP server, and the AD server is returning 0x00, "Successful request", AFAICT.

#!/usr/bin/perl -w
use strict;
use Net::LDAP;

## Corporate subdomains
my @domains = ("americas", "asia", "europe");

# AD connect timeout
my $timeout = 10;
# Set AD server info.
my $port = "389";
my $host = "server.domain.com";

my $user = shift @ARGV;
chomp $user;

my $password = <STDIN>;
$password =~ s/\r\n//;
chomp $password;

my $ldap = Net::LDAP->new($host, port => $port, timeout => $timeout ) ||
        die "Unable to connect to LDAP server";

my $bind_return = 1;
foreach (@domains) {
        my $result = $ldap->bind( "$user\@$_.domain.com", password => $password );
        if( $result->code == 0) {
                $bind_return = 0;
                last;
        }
}

## Unbind and return
$ldap->unbind;

if ($bind_return) { print "Authentication Failed.  Access Denied\n" }
exit $bind_return;
解决方案

Michael Ströder, the author of the python-ldap library, enlightened me thus:

try:
  conn.simple_bind_s('[email protected]', 'WrongPassword')
except ldap.INVALID_CREDENTIALS:
  user_error_msg('wrong password provided')

The reason for these results:

>>> conn.simple_bind_s('', 'CorrectPassword')
(97, [])
>>> conn.simple_bind_s('', '')
(97, [])

is that out of the box 2003 Active Directory allows anonymous binds. So not providing a user id at all will still pass a simple bind check, if the only thing being tested is whether simple_bind_s() throws an error.

2003 Active Directory does require authentication for any searches that aren't attributes of the rootDSE, so for our internal purposes we added a trivial search to the try: block:

try:
  conn.simple_bind_s('[email protected]', 'SubmittedPassword')
  conn.search_st('DC=domain,DC=com', ldap.SCOPE_SUBTREE, '(objectClass=container)', 'name', 0, 30)
except ldap.INVALID_CREDENTIALS:
  user_error_msg('wrong password provided')

这篇关于鉴定到Active Directory中的python-LDAP总是返回(97,[])的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 11:31