• Lấy giá trị khả dụng kế tiếp uidNumber từ mục uidPool.
• Ban hành một yêu cầu sửa đổi LDAP để xĩa giá trị uidNumber ban đầu, và lưu giá trị cũ +1 vào giá trị mới
• Nếu việc update fail, làm lại cho đến khi việc sửa đổi thành cơng.
Việt tìm kiếm và cập nhật được chuyển thành vịng lặp do…while để chắc chắn rằng bạn cĩ một UID cĩ giá trị khi bạn thốt. Nếu việc tìm kiếm thất bại, do trả lại bị lỗi hoặc danh sách bị rỗng, hàm get_next_uid ( ) fail và trả lại một UID vơ giá trị (-1):
do { $msg = $ldap->search( base => "dc=plainjoe,dc=org", scope => "one", filter => "(objectclass=uidPool)" ); if ($msg->code ) { warn $msg->error; return -1; } if ( ! $msg->count ) {
warn "Unable to locate uidPool entry!"; return -1;
}
Để cĩ được số ID khả dụng tiếp theo, hàm lấy thuộc tính uidNumber từ mục đầu tiên được trả về của hàm search ( ). Thuộc tính uidNumber được định nghĩa bởi giản đồ RFC 2307 là giá trị đơn, do vậy get_value( ) luơn trả về một hằng số:
$entry = $msg->entry(0);
$uid = $entry->get_value( 'uidNumber' );
Hàm modify( ) địi hỏi DN của mục phải được thay đổi thành tham số đầu tiên
modify( DN, options );
options xác định loại update nào cần thực hiện: add, delete, replace, or changes. Ba loại đầu tiên nhận
một tham chiếu đến một bảng hash của các thuộc tính và các giá trị. Ví dụ, đoạn code này xĩa thuộc tính email jerry@plainjoe.org:
$ldap->modify( $entry->dn( ),
delete => [ 'mail' => 'jerry@plainjoe.org' ] );
modify( ) cĩ thể thay đổi nhiều loại khác nhau. Ở đây bạn xĩa một địa chỉ email và số điện thoại: $ldap->modify( $entry->dn( ),
delete => { 'mail' => 'jerry@plainjoe.org' }, add => { 'telephoneNumber' => '555-1234' } );
Việc dùng riêng rẽ hàm add và hàm delete khơng đảm bảo LDAP sẽ thực hiện cái nào trước. Thứ tự thực hiện phụ thuộc vào hàm get_next_uid ( ) vì hàm xĩa nên thực hiện trước hàm thêm vào. Vì lý do đĩ, hàm get_next_uid ( ) dùng changes trước, vì nĩ cho phép lập trình viên xác định việc sửa đổi được thực hiện ra sao.
Tùy chọn changes xác định cụ thể các mảng cập nhật. Một cặp nội dung được xác định là: loại sửa đổi (add, delete hay replace), và giá trị thao chiếm đến một mảng được xác định bởi cặp
chọn changes:
$ldap->modify( $entry->dn( ), changes => [ 'delete, [ 'mail', 'jerry@plainjoe.org' ], 'add', ['telephoneNumber', '555-1234' ] ] );
Thơng thường ta sẽ dễ hiểu các update này hơn nếu chúng nằm ở các mảng khác nhau, hơn là dùng một tham chiếu. Đoạn code sau dùng ba mảng để lưu trữ các thay đổi. Mảng đầu tiên lưu trữ yêu cầu delete, mảng thứ hai lưu trữ yêu cầu add, và mảng thứ ba lưu trữ các tham chiếu đến đến 2 mảng trước đĩ, sau khi đã xác định loại thay đổi.
push ( @Delete, 'uidNumber', $uid ); push ( @Add, 'uidNumber', $uid+1 ); push ( @Changes, 'delete', \@Delete ); push ( @Changes, 'add', \@Add );
$result = $ldap->modify( $entry->dn( ), 'changes' => [ @Changes ] );
Nếu việc gọi hàm modify( ) thất bại, đoạn mã giả sử rằng việc xĩa bị thất bại vì giá trị uidNumber khơng khớp. Do đĩ, biến $uid được đặt là -1 và vịng lặp sẽ lặp lại:
if ( $result->code ) { $uid = -1 }
} while ( $uid = = -1 );
Cuối cùng, hàm trả ra một UID cĩ giá trị:
return $uid; }
Đây là hàm get_next_uid( )tồn bộ:
########################################################## Get the next available UID from the idPool. Spin until you get one. ## Get the next available UID from the idPool. Spin until you get one. ##
sub get_next_uid { my ( $ldap ) = @_; my ( $uid, $msg, $entry );
my ( @Add, @Delete, @Changes );
do {
## Get the uidPool entry and perform error checking. $msg = $ldap->search( base => "dc=plainjoe,dc=org", scope => "one", filter => "(objectclass=uidPool)" ); if ($msg->code ) { warn $msg->error; return -1; } if ( ! $msg->count ) {
warn "Unable to locate uidPool entry!"; return -1;
}
$uid = $entry->get_value( 'uidNumber' );
## Put the changes together to update the next UID in the directory. push ( @Delete, 'uidNumber', $uid );
push ( @Add, 'uidNumber', $uid+1 ); push ( @Changes, 'delete', \@Delete ); push ( @Changes, 'add', \@Add );
## Update the directory.
$result = $ldap->modify( $entry->dn( ), 'changes' => [ @Changes ] ); if ( $result->code ) { $uid = -1 }
## Do you need another round? } while ( $uid = = -1 );
## All done return $uid; }
Hàm này sẽ được áp dụng một cách tương tự như:
if ( ($nextuid=get_next_uid( $ldap )) = = -1) { print "Unable to generate new uid!\n"; print "Unable to generate new uid!\n"; exit 1;
}
##############################################################################