2012-05-23 16 views
12

this questionと同様に、私は2003 Active Directoryに対して簡単な認証を実行しようとしています(CentOS 6.2 x86_64、Python 2.6.6、 LDAP 2.3.10)。python-ldapでActive Directoryを認証すると常に(97、[])が返されます

私は正しい資格情報を渡すと

conn.set_option(ldap.OPT_REFERRALS, 0) 

含めて初期化中にすべての通常の手順を、以下にもかかわらず、私はいつも(97, [])返さ取得

>>> 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, []) 

をエラーコード97ではありません成功; ADから返されるエラーはLDAP_REFERRAL_LIMIT_EXCEEDEDです。

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

さらにイライラは、このスクリプトは、ネット:: LDAP、リターン0を行い使用して、古いPerlスクリプトからの移行であるということです:ので、また私は、デファクト成功の指標として使用することができます同じADおよびサーバーへの認証されたバインドに成功したことを示します。

私がpython-ldapで見つけることができるすべての情報は、私がやっていることはちょうど仕事でなければならないことを示しています。私はADサーバーに何か問題があると思う傾向がありますが、Perlスクリプトはバインドが成功した場合に正しいLDAPコードを返します。

私はPython-ldap 2.2.0とPython 2.4.4を、古いCentOS 5.5のボックスにテストしました。私は横たわっていましたが、まったく同じ方法で「失敗」します。

誰かが迷っていることを知っていますか?

EDIT:リクエストごとに、ここで動作するPerlスクリプトがあります。 Net::LDAPはLDAPサーバーから戻りコードを返し、ADサーバーは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; 
+0

あなたは関連を投稿することができます:

2003のActive Directory がでrootDSEの属性ではありません任意の検索のための認証が必要です、私たちの内部目的のために私たちはtry:ブロックに些細な検索を追加しましたPerlコード? – stark

+0

私はserver.domain.comのために、あなたはpythonに合うようにad.server.domain.comを意味すると思いますか?また、デフォルトのポートは389ですが、URLに明示的に ":389"を追加するとよいでしょう。 – stark

答えて

14

マイケルStröder、のpython-LDAPライブラリの作者は、このように私を啓発:

を97 LDAP結果コードではありません。結果のタイプは ldap.RES_BINDです。通常は、 によって返された結果をLDAPObject.simple_bind_s()で調べる必要はありません(バインド レスポンスコントロールを抽出する場合を除きます)。

LDAP結果コードが0ではない場合、例ではldap.INVALID_CREDENTIALSのような という例外が発生します。

だからあなたのコードは次のようになります。

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

これらの結果の理由:

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

があることがボックス2003のActive Directory allows anonymous binds外です。したがって、ユーザーIDを提供しないと、単純なバインドチェックが渡されます。テストされるのは、simple_bind_s()がエラーをスローするかどうかだけです。

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') 
0

このエラーは、あなたのconn.set_option(ldap.OPT_REFERRALS, 0)が影響を受けていないことを意味します。

したがって、これを試してみてください。

import ldap 

ldap.set_option(ldap.OPT_REFERRALS,0) 
ldap.protocol_version = 3 
conn = ldap.initialize('ldap://....') 
conn.simple_bind_s('[email protected]', 'RightPassword') 
+0

喜びはありません、私は恐れています。それでも '(97、[])'を返します。これらのオプションがconn SimpleLDAPObjectインスタンスに対して正しく設定されていることをconn.get_option()で確認しました。 –

+0

私は間違っているかもしれませんが、Perlスクリプトでは 'user @ europe.domain.com'を使用していると思いますか? –

関連する問題