Kết nối, ràng buộc, tìm kiếm:

Một phần của tài liệu Đồ án tin học nghiên cứu về giao thức LDAP (Trang 166)

Để bắt đầu với modul Net::LDAP, ta sẽ việc một đoạn script LDAP cơ bản tên là search.pl. Đoạn script này mô tả các phương pháp được dùng để kết nối với server thư mục và lấy thông tin. Dùng praga use:

#!/usr/bin/perl use Net::LDAP;

Sau khi module được đưa vào, ta có thể tạo mới 1 ví dụ của đối tượng Net::LDAP. Để làm việc này, ta cần hostname của server LDAP mà đoạn script phải kết nối tới. Có một số tùy chọn phổ biến sau:

port

Là port TCP mà server thư mục đang kết nối tới. Nếu không định nghĩa port nào, thì port mặc định là 389

version

Phiên bản LDAP được dùng khi kết nối tới server. Phiên bản mặc định là Version 2 trong bản phát hành 0.26. Tuy nhiên, điều này có thể thay đổi.

timeout

Thời gian tính bằng giây mà các module phải chờ khi đang kết nối với server thư mục. Mặc định là 120 giây cho hầu hết các trường hợp, nếu việc tìm kiếm phực tạp hơn hoặc khi kết nối với một thư mục quá lớn, giá trị này sẽ được tăng lên.

Dòng tiếp theo của đoạn code thiết lập một kết nối tới host ldap.plainjoe.org trên port 389 dùng phiên bản 3 của giao thức. Giá trị trả về cho đối tượng Net::LDAP có thể dùng để lấy và sửa đổi dữ liệu trong thư mục.

version => 3 );

Các script có thể kết nối tới các thư mục sau khi được xử lý bởi các server LDAP. Mặc định, Net::LDAP dùng các kết nối ngầm ẩn danh, nhưng nó hỗ trợ tất cả các chuẩn kết nối được định nghĩa bởi LDAPv3 RFCs (ẩn danh, đơn giản, và SASL). Bây giờ, ta sẽ chỉ tìm hiểu xem làm thể nào để dùng một kết nối đơn giản.

Đầu tiên, trước khi kết nối với server, gọi lệnh start_tls( ) để mã hóa kết nối. Mã hóa password và DN của người dùng. Dạng đơn giản nhất:

$ldap->start_tls( );

Kiểm tra lỗi:

Hầu hết các phương thức của Net::LDAP trả về một đối tượng với 2 phương pháp để đạt được trạng thái trả về của hàm. Hàm code ( ) lấy giá trị số nguyên được trả về từ phương thức gọi là khởi tạo đối tượng, hàm error ( ) trả về một chuỗi ký tự mô tả kết hợp với mã. Các hằng số cho các lỗi LDAP khác nhau được liệt kê trong Net::LDAP::Constant. Các mã lỗi cụ thể được đưa vào trong mã của bạn bằng cách thêm một dòng như sau:

use Net::LDAP::Constant qw(LDAP_SUCCESS);

Đoạn code sau kiểm tra một điều kiện lỗi sau lệnh gọi LDAP tùy ý:

if ($result->code( ) != LDAP_SUCCESS) { die $result->error( );

}

Vì hầu hết các phương thức đều trả về 0 nếu thành công, nên việc kiểm ta lỗi có thể được rút ngắn như sau:

die $result->error( ) if $result->code( );

Nên kiểm tra lỗi sau khi thiết lập một kênh giao tiếp an toàn. Nếu lệnh start_tls( ) bị fail, và đoạn script vẫn tiếp tục, thì có thể nó sẽ vô tình truyền tải thông tin tài khoản một cách rõ ràng. Để kiểm tra lỗi thì ta nên lưu lại các kết quả được trả về bởi start_tls ( ) và dùng lệnh code ( ) để tìm hiểu liệu start_tls ( ) đã thành công hay chưa.

$result = $ldap->start_tls( );

die $result->error( ) if $result->code( );

Nếu script cố gắng thiết lập bảo mật tầng vận chuyển với một server không được hỗ trợ các hoạt động mở rộng, thì sẽ xuất hiện thông báo lỗi:

Operations error at ./search.pl line XXX.

Bây giờ ta có thể gởi các dữ liệu đến server một cách an toàn. Thường thì yêu cầu kết nối chỉ gồm DN và password. Đoạn code sau tìm cách kết nối khách hàng tới thư mục có nội dung cn=Gerald Carter,ou=people,dc=plainjoe,dc=orgsử dụng password là hello. Một lần nữa, ta dùng error ( )code ( ) để kiểm tra trạng thái trả về:

password => "hello");

die $result->error( ) if $result->code( );

Nếu không có lỗi, đoạn script được tìm kiếm trong thư mục. Hàm search ( ) chấp nhận các thông số chuẩn trong công cụ truy vấn LDAP. Ví dụ:

$msg = $ldap->search(

base => "ou=people,dc=plainjoe,dc=org", scope => "sub",

filter => "(cn=$ARGV[0])" );

Giá trị trả về của việc tìm kiếm là một đối tượng cố định của Net::LDAP::Search. Ta có thể thao tác với đối tượng này để truy xuất bất cứ mục nào phù hợp với việc tìm kiếm. Đối tượng này có hàm count ( ) để đếm số mục, và hàm

all_entries ( ) trả về một mảng các đối tượng Net::LDAP::Entry, mỗi đối tượng đại diện cho thông tin liên quan tới một nút thư mục duy nhất. Dùng hàm dump ( ) để xem các kết quả truy vấn.

if ( $msg->count( ) > 0 ) {

print $msg->count( ), " entries returned.\n";

foreach $entry ( $msg->all_entries( ) ) { $entry->dump( ); } } Đầu ra của một mục: dn:cn=Gerald Carter,ou=people,dc=plainjoe,dc=org objectClass: inetOrgPerson cn: Gerald Carter sn: Carter givenName: Gerald o: Hewlett-Packard mobile: 256.555.5309 mail: jerry@plainjoe.org postalAddress: 103 Somewhere Street l: Some Town

st: AL

postalCode: 55555-5555

Nếu bạn chỉ quan tâm tới địa chỉ email của một ai đó thì sao? Ta dùng hàm search ( ) để xuất ra các phần ta mong muốn (ở đây là địa chỉ email). Việc tìm kiếm sẽ trả ra giá trị phù hợp với thuộc tính ta nêu ra.

$msg = $ldap->search( base => "ou=people,dc=plainjoe,dc=org", scope => "sub", filter => "(cn=$ARGV[0])", attrs => [ "cn", "mail" ] ); Và đây là kết quả: dn:cn=Gerald Carter,ou=people,dc=plainjoe,dc=org

mail: jerry@plainjoe.org

Dòng cuối cùng của đoạn mã là unbind( ) dùng để ngắt kết nối tới thư mục:

$ldap->unbind( );

Khi có lệnh này, kết nối tới máy chủ sẽ bị ngắt. Muốn kết nối lại ta phải dung lệnh bind ( ) một lần nữa, và vẫn phải cung cấp DN và password lần nữa.

Đoạn mã search.pl toàn vẹn

#!/usr/bin/perl ##

## Usage: ./search.pl name

##

## Author: Gerald Carter <jerry@plainjoe.org> ##

use Net::LDAP;

## Connect and bind to the server.

$ldap = Net::LDAP->new ("ldap.plainjoe.org", port =>389, version => 3 )

or die $!;

$result = $ldap->start_tls( );

die $result->error( ) if $result->code( );

$result = $ldap->bind(

"cn=Gerald Carter,ou=people,dc=plainjoe,dc=org", password => "hello");

die $result->error( ) if $result->code( );

## Query for the cn and mail attributes. $msg = $ldap->search( base => "ou=people,dc=plainjoe,dc=org", scope => "sub", filter => "(cn=$ARGV[0])", attrs => [ "cn", "mail" ] );

## Print resulting entries to standard output. if ( $msg->count( ) > 0 ) {

print $msg->count( ), " entries returned.\n";

foreach $entry ( $msg->all_entries( ) ) { $entry->dump( );

}} }

## Unbind and exit.

Đầu tiên, ta phải thêm pragma use thứ hai để import module LDIF:

use Net::LDAP::LDIF;

Sau đó, script phải tạo một ví dụ của đối tượng Net::LDAP::LDIF. Đầu ra từ đối tượng này có thể được link tới các file có sẵn chẳng hạn như STDOUT

$ldif = Net::LDAP::LDIF->new (STDOUT, "w") or die $!;

Có thể điền tên file trong ngoặc của new(), hoặc ta có thể cho biết cách file đó được dùng (r là đọc, w là viết và cắt ngắn, a là viết và nối thêm).

$ldif = Net::LDAP::LDIF->new ("./result.ldif", "w") or die $!;

Ta mở file sau khi script đã kiểm tra rằng $msg->count( ) > 0:

if ( $msg->count( ) > 0 ) {

print $msg->count( ), " entries returned.\n";

$ldif = Net::LDAP::LDIF->new (scalar<STDOUT>, "w") or die $!;

Cuối cùng, thay vòng lặp foreach trên mỗi mục bởi 1 lệnh gọi write_entry( )

$ldif->write_entry($msg->all_entries( ));

write_entry( ) chấp nhận một Net::LDAP::Entry hoặc mảng 1 chiều của các đối tượng này. Vòng lặp mới là:

if ( $msg->count( ) > 0 ) {

print $msg->count( ), " entries returned.\n";

$ldif = Net::LDAP::LDIF->new (scalar<STDOUT>, "w") or die $!;

$ldif->write_entry($msg->all_entries( )); }

Bây giờ, đầu ra của script sẽ như sau:

dn: cn=Gerald Carter,ou=contacts,dc=plainjoe,dc=org cn: Gerald Carter

mail: jerry@samba.org

Trông có vẻ không có gì thay đổi, nhưng nó rất quan trọng. Vì dữ liệu bây giờ là LDIF, các công cụ khác như là ldapdmodify có thể phân tích cú pháp (parse) đầu ra của script.

Khi script tạo file LDIF, ta có thể đóng file bằng done ()

Việc tìm kiếm đối tượng trong thư mục chỉ là khởi đầu. Sức mạnh thật sự của viết code là ta có thể chỉnh sửa thư mục, ta có thể thêm nội dung, xóa nội dung, và tùy chỉnh các nội dung đã có sẵn.

Một phần của tài liệu Đồ án tin học nghiên cứu về giao thức LDAP (Trang 166)

Tải bản đầy đủ (DOCX)

(188 trang)
w