svn commit: samba r18697 - in branches: SAMBA_3_0/examples/misc SAMBA_3_0_23/examples/misc

gd at samba.org gd at samba.org
Tue Sep 19 22:57:14 GMT 2006


Author: gd
Date: 2006-09-19 22:57:13 +0000 (Tue, 19 Sep 2006)
New Revision: 18697

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=18697

Log:
Make sure that adssearch.pl does not

* chase referrals 
* use paged search control

when using the LDAP change notify control for monitoring changes.

Guenther

Modified:
   branches/SAMBA_3_0/examples/misc/adssearch.pl
   branches/SAMBA_3_0_23/examples/misc/adssearch.pl


Changeset:
Modified: branches/SAMBA_3_0/examples/misc/adssearch.pl
===================================================================
--- branches/SAMBA_3_0/examples/misc/adssearch.pl	2006-09-19 22:48:08 UTC (rev 18696)
+++ branches/SAMBA_3_0/examples/misc/adssearch.pl	2006-09-19 22:57:13 UTC (rev 18697)
@@ -130,7 +130,7 @@
 }
 
 if ($opt_notify) {
-	$opt_paging = 0;
+	$opt_paging = undef;
 }
 
 # get the query
@@ -1562,7 +1562,7 @@
 
 	my ($res,$obj) = @_;
 
-	if ($res->code == LDAP_REFERRAL) {
+	if (!$opt_notify && $res->code == LDAP_REFERRAL) {
 		return;
 	}
 
@@ -1753,7 +1753,7 @@
 			scope => $scope,
 				) || die "cannot search";
 
-		if ($async_search->code == LDAP_REFERRAL) {
+		if (!$opt_notify && ($async_search->code == LDAP_REFERRAL)) {
 			foreach my $ref ($async_search->referrals) {
 				print "\ngot Referral: [$ref]\n";
 				$async_ldap_hd->unbind();

Modified: branches/SAMBA_3_0_23/examples/misc/adssearch.pl
===================================================================
--- branches/SAMBA_3_0_23/examples/misc/adssearch.pl	2006-09-19 22:48:08 UTC (rev 18696)
+++ branches/SAMBA_3_0_23/examples/misc/adssearch.pl	2006-09-19 22:57:13 UTC (rev 18697)
@@ -14,6 +14,7 @@
 
 use Net::LDAP;
 use Net::LDAP::Control;
+use Net::LDAP::Constant qw(LDAP_REFERRAL);
 use Convert::ASN1;
 use Time::Local;
 use POSIX qw(strftime);
@@ -38,7 +39,9 @@
 my $binddn 	= "";
 my $password 	= "";
 my $server 	= "";
+my $rebind_url;
 
+
 my $tdbdump	= "/usr/bin/tdbdump";
 my $testparm	= "/usr/bin/testparm";
 my $net		= "/usr/bin/net";
@@ -48,7 +51,6 @@
 my $klist	= "/usr/bin/klist";
 my $kinit	= "/usr/bin/kinit";
 my $ads_h 	= "/home/gd/ads.h";
-my $page_size	= "1000";
 my $workgroup	= "";
 my $machine	= "";
 my $realm	= "";
@@ -62,14 +64,17 @@
 	$opt_display_extendeddn,
 	$opt_display_metadata,
 	$opt_display_raw,
+	$opt_domain_scope,
 	$opt_dump_rootdse,
 	$opt_dump_schema,
 	$opt_dump_wknguid,
+	$opt_fastbind,
 	$opt_help, 
 	$opt_host, 
 	$opt_machine,
 	$opt_notify, 
-	$opt_notify_nodiffs, 
+	$opt_notify_nodiffs,
+	$opt_paging,
 	$opt_password,
 	$opt_port,
 	$opt_realm,
@@ -87,13 +92,16 @@
 	'base|b=s'	=> \$opt_base,
 	'D|DN=s'	=> \$opt_binddn,
 	'debug=i'	=> \$opt_debug,
-	'extendeddn|e=i'	=> \$opt_display_extendeddn,
+	'domain_scope'	=> \$opt_domain_scope,
+	'extendeddn|e:i'	=> \$opt_display_extendeddn,
+	'fastbind'	=> \$opt_fastbind,
 	'help'		=> \$opt_help,
 	'host|h=s'	=> \$opt_host,
 	'machine|P'	=> \$opt_machine,
 	'metadata|m'	=> \$opt_display_metadata,
 	'nodiffs'	=> \$opt_notify_nodiffs,
 	'notify|n'	=> \$opt_notify,
+	'paging:i'	=> \$opt_paging,
 	'password|w=s'	=> \$opt_password,
 	'port=i'	=> \$opt_port,
 	'rawdisplay'	=> \$opt_display_raw,
@@ -111,20 +119,27 @@
 	);
 
 
-# activate controls
-my $paging	= 1 if !$opt_notify;
-
 if (!@ARGV && !$opt_dump_schema && !$opt_dump_rootdse && !$opt_notify || $opt_help) {
 	usage();
 	exit 1;
 }
 
+if ($opt_fastbind && !$opt_simpleauth) {
+	printf("LDAP fast bind can only be performed with simple binds\n");
+	exit 1;
+}
+
+if ($opt_notify) {
+	$opt_paging = undef;
+}
+
 # get the query
 my $query 	= shift;
 my @attrs	= @ARGV;
 
 # some global vars
-my ($filter, $dse, $uri);
+my $filter = "";
+my ($dse, $uri);
 my ($attr, $value);
 my (@ctrls, @ctrls_s);
 my ($ctl_paged, $cookie);
@@ -483,14 +498,17 @@
 	print "\t--asq [attribute]\n\t\tAttribute to use for a attribute scoped query (LDAP_SERVER_ASQ_OID)\n";
 	print "\t--base|-b [base]\n\t\tUse base [base]\n";
 	print "\t--debug [level]\n\t\tUse debuglevel (for Net::LDAP)\n";
+	print "\t--domain_scope\n\t\tLimit LDAP search to local domain (LDAP_SERVER_DOMAIN_SCOPE_OID)\n";
 	print "\t--DN|-D [binddn]\n\t\tUse binddn or principal\n";
-	print "\t--extendeddn|-e\n\t\tDisplay extended dn (LDAP_SERVER_EXTENDED_DN_OID)\n";
+	print "\t--extendeddn|-e [value]\n\t\tDisplay extended dn (LDAP_SERVER_EXTENDED_DN_OID)\n";
+	print "\t--fastbind\n\t\tDo LDAP fast bind using LDAP_SERVER_FAST_BIND_OID extension\n";
 	print "\t--help\n\t\tDisplay help page\n";
 	print "\t--host|-h [host]\n\t\tQuery Host [host] (either a hostname or an LDAP uri)\n";
 	print "\t--machine|-P\n\t\tUse samba3 machine account stored in $secrets_tdb (needs root access)\n";
 	print "\t--metdata|-m\n\t\tDisplay replication metadata\n";
 	print "\t--nodiffs\n\t\tDisplay no diffs but full entry dump when running in notify mode\n";
 	print "\t--notify|-n\n\t\tActivate asynchronous change notification (LDAP_SERVER_NOTIFICATION_OID)\n";
+	print "\t--paging [pagesize]\n\t\tUse paged results when searching\n";
 	print "\t--password|-w [password]\n\t\tUse [password] for binddn\n";
 	print "\t--port [port]\n\t\tUse [port] when connecting ADS\n";
 	print "\t--rawdisplay\n\t\tDo not interpret values\n";
@@ -710,28 +728,43 @@
 	return $acct;
 }
 
-sub check_ctrls ($$@) {
+sub check_root_dse($$$@) {
 
 	# bogus function??
 	my $server = shift || "";
 	$dse = shift || get_dse($server) || return -1;
-	my @ctrls = @_;
+	my $attr = shift || die "unknown query";
+	my @array = @_;
 
-	my $dse_controls = $dse->get_value('supportedControl', asref => '1');
-	my @dse_controls = @$dse_controls;
+	my $dse_list = $dse->get_value($attr, asref => '1');
+	my @dse_array = @$dse_list;
 
-	foreach my $i (@ctrls) {
+	foreach my $i (@array) {
 		# we could use -> supported_control but this 
 		# is only available in newer versions of perl-ldap
 #		if ( ! $dse->supported_control( $i ) ) {
-		if ( grep(/$i->type()/, @dse_controls) ) { 
-			printf("required control: %s is not supported by ADS-server.\n", $i->type());
+		if ( grep(/$i->type()/, @dse_array) ) { 
+			printf("required \"$attr\": %s is not supported by ADS-server.\n", $i->type());
 			return -1;
 		}
 	}
 	return 0;
 }
 
+sub check_ctrls ($$@) {
+	my $server = shift;
+	my $dse = shift;
+	my @array = @_;
+	return check_root_dse($server, $dse, "supportedControl", @array);
+}
+
+sub check_exts ($$@) {
+	my $server = shift;
+	my $dse = shift;
+	my @array = @_;
+	return check_root_dse($server, $dse, "supportedExtension", @array);
+}
+
 sub get_base_from_rootdse {
 
 	my $server = shift || "";
@@ -1365,7 +1398,7 @@
 	printf "%10s: %s\n", "scope", $scope;
 	printf "%10s: %s\n", "attrs", join(", ", @attrs);
 	printf "%10s: %s\n", "controls", join(", ", @ctrls_s);
-	printf "%10s: %s\n", "page_size", $page_size if ($paging);
+	printf "%10s: %s\n", "page_size", $opt_paging if ($opt_paging);
 	printf "%10s: %s\n", "start_tls", $opt_starttls ? "yes" : "no";
 	printf "\n";
 }
@@ -1413,10 +1446,15 @@
 	$ctl_paged = Net::LDAP::Control->new( 
 		type => $ads_controls{'LDAP_PAGED_RESULT_OID_STRING'},
 		critical => 'true',
-		size => $page_size);
+		size => $opt_paging ? $opt_paging : 1000);
 
+	# setup domscope control
+	my $ctl_domscope = Net::LDAP::Control->new( 
+		type => $ads_controls{'LDAP_SERVER_DOMAIN_SCOPE_OID'},
+		critical => 'true',
+		value => "");
 
-	if ($paging) {
+	if (defined($opt_paging)) {
 		push(@ctrls, $ctl_paged);
 		push(@ctrls_s, "LDAP_PAGED_RESULT_OID_STRING" );
 	}
@@ -1434,7 +1472,12 @@
 		push(@ctrls, $ctl_asq);
 		push(@ctrls_s, "LDAP_SERVER_ASQ_OID");
 	}
-	
+
+	if ($opt_domain_scope) {
+		push(@ctrls, $ctl_domscope);
+		push(@ctrls_s, "LDAP_SERVER_DOMAIN_SCOPE_OID");
+	}
+
 	return @ctrls;
 }
 
@@ -1519,6 +1562,10 @@
 
 	my ($res,$obj) = @_;
 
+	if (!$opt_notify && $res->code == LDAP_REFERRAL) {
+		return;
+	}
+
 	if (!$opt_notify) {
 		return process_result($res,$obj);
 	} 
@@ -1566,6 +1613,9 @@
 		printf("\ngot changenotify for dn: [%s]\n%s\n", $async_entry->dn, ("-" x 80));
 
 		my $new_usn = $async_entry->get_value('uSNChanged');
+		if (!$new_usn) {
+			die "odd, no usnChanged attribute???";
+		}
 		if (!$usn || $new_usn > $usn) {
 			$usn = $new_usn;
 			if ($opt_notify_nodiffs) {
@@ -1602,16 +1652,39 @@
 		$mesg = $async_ldap_hd->bind( 
 			$binddn, 
 			password => $password, 
-			callback => \&error_callback
+			callback => $opt_fastbind ? undef : \&error_callback
 		) || die "doesnt work";
 	};
 	if ($mesg->code) { 
-		display_ldap_err($mesg);
+		display_ldap_err($mesg) if (!$opt_fastbind);
 		return -1;
 	}
 	return 0;
 }
 
+sub do_fast_bind() {
+
+	do_unbind();
+
+	my $hd = get_ldap_hd($server,1);
+
+	my $mesg = $hd->extension(
+		name => $ads_extensions{'LDAP_SERVER_FAST_BIND_OID'});
+	
+	if ($mesg->code) { 
+		display_ldap_err($mesg);
+		return -1;
+	}
+
+	my $ret = do_bind($hd, undef);
+	$hd->unbind;
+
+	printf("bind using 'LDAP_SERVER_FAST_BIND_OID' %s\n", 
+		$ret == 0 ? "succeeded" : "failed");
+
+	return $ret;
+}
+
 sub do_unbind() {
 	if ($async_ldap_hd) {
 		$async_ldap_hd->unbind;
@@ -1625,9 +1698,21 @@
 
 sub main () {
 
+	if ($opt_fastbind) {
+
+		if (check_exts($server,$dse,"LDAP_SERVER_FAST_BIND_OID") == -1) {
+			print "LDAP_SERVER_FAST_BIND_OID not supported by this server\n";
+			exit 1;
+		}
+
+		# fast bind can only bind, not search
+		exit do_fast_bind();
+	}
+
 	$filter = construct_filter($query);
 	@attrs  = construct_attrs(@attrs);
 	@ctrls  = gen_controls();
+
 	if (check_ctrls($server,$dse, at ctrls) == -1) {
 		print "not all required LDAP Controls are supported by this server\n";
 		exit 1;
@@ -1668,6 +1753,21 @@
 			scope => $scope,
 				) || die "cannot search";
 
+		if (!$opt_notify && ($async_search->code == LDAP_REFERRAL)) {
+			foreach my $ref ($async_search->referrals) {
+				print "\ngot Referral: [$ref]\n";
+				$async_ldap_hd->unbind();
+				$async_ldap_hd = get_ldap_hd($ref, 1);
+				if (do_bind($async_ldap_hd, $sasl_bind) == -1) {
+					$async_ldap_hd->unbind();
+					next;
+				}
+				print "\nsuccessful rebind to: [$ref]\n";
+				last;
+			}
+			next; # repeat the query
+		}
+
 		if ($opt_notify) {
 
 			print "Base [$base] is registered now for change-notify\n";
@@ -1701,7 +1801,7 @@
 	if ($async_search->entries == 0) {
 		print "No entries found with filter $filter\n";
 	} else {
-		print "Got $total_entry_count Entries in $page_count Pages\n" if ($paging);
+		print "Got $total_entry_count Entries in $page_count Pages\n" if ($opt_paging);
 	}
 
 	do_unbind()



More information about the samba-cvs mailing list