14

この質問と同様に、python ldap(CentOS 6.2 x86_64、Python 2.6.6、python-ldap 2.3.10)を使用して2003ActiveDirectoryに対して単純な認証を実行しようとしています。

initの通常の手順をすべて実行したにもかかわらず、

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('user@domain.com', 'WrongPassword')
ldap.INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece', 'desc': 'Invalid credentials'}
>>> conn.simple_bind_s('user@domain.com', 'CorrectPassword')
(97, [])

エラーコード97は成功しません。LDAP_REFERRAL_LIMIT_EXCEEDEDADから返されるエラーです。また、それを事実上の成功の指標として使用することもできません。理由は次のとおりです。

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

さらに苛立たしいのは、このスクリプトがNet :: LDAPを使用した古いPerlスクリプトからの移行であり、同じADとサーバーへの認証済みバインド成功すると0を返すことです。

私がpython-ldapで見つけることができるすべての情報は、私がしていることがうまくいくはずであることを示しています。ADサーバーに何か問題があると思う傾向がありますが、Perlスクリプトはバインドが成功すると正しいLDAPコードを返します。

横になっていた古いCentOS5.5ボックスでpython-ldap2.2.0とpython2.4.4をテストしましたが、まったく同じように「失敗」します。

誰かが私が欠けているものを知っていますか?

編集:リクエストごとに、これが機能するPerlスクリプトです。 Net::LDAPLDAPサーバーからの戻りコードを返し、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;
4

2 に答える 2

15

python-ldapライブラリの作者であるMichaelStröderは、次のように私に教えてくれました。

97はLDAP結果コードではありません。これは、結果タイプldap.RES_BINDです。通常、LDAPObject.simple_bind_s()によって返される結果を確認する必要はありません(バインド応答コントロールを抽出する場合を除く)。

LDAP結果コードが0でない場合、付随する例外が発生します(例のldap.INVALID_CREDENTIALSのように)。

したがって、コードは次のようになります。

try:
  conn.simple_bind_s('user@domain.com', 'WrongPassword')
except ldap.INVALID_CREDENTIALS:
  user_error_msg('wrong password provided')

これらの結果の理由:

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

箱から出してすぐに使える2003ActiveDirectoryでは、匿名バインドが許可されています。simple_bind_s()したがって、テストされているのがエラーをスローするかどうかだけである場合、ユーザーIDをまったく提供しない場合でも、単純なバインドチェックに合格します。

2003 Active Directory、rootDSEの属性ではない検索に対して認証を必要とするため、内部目的のために、try:ブロックに簡単な検索を追加しました。

try:
  conn.simple_bind_s('user@domain.com', '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')
于 2012-05-24T19:06:00.010 に答える
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('user@domain.com', 'RightPassword')
于 2012-05-24T16:50:35.380 に答える