• 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 thoá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( )toà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;
}
##############################################################################