shelldap
changeset 92 a1aa55019077
parent 91 80ec00959fbd
child 93 4c7843b9a047
equal deleted inserted replaced
91:80ec00959fbd 92:a1aa55019077
   136 
   136 
   137 =back
   137 =back
   138 
   138 
   139 =over 4
   139 =over 4
   140 
   140 
       
   141 =item B<paginate>
       
   142 
       
   143 Integer.  If enabled, shelldap will attempt to use server side
       
   144 pagination to build listings.  Note: if you're using this to avoid
       
   145 sizelimit errors, you'll likely need server configuration to raise the
       
   146 limits for paginated results.
       
   147 
       
   148 	--paginate 100
       
   149 
       
   150 =back
       
   151 
       
   152 =over 4
       
   153 
   141 =item B<promptpass>
   154 =item B<promptpass>
   142 
   155 
   143 Force password prompting.  Useful to temporarily override cached
   156 Force password prompting.  Useful to temporarily override cached
   144 credentials.
   157 credentials.
   145 
   158 
   446 	LDAP_BUSY
   459 	LDAP_BUSY
   447 	LDAP_UNAVAILABLE
   460 	LDAP_UNAVAILABLE
   448 	LDAP_OTHER
   461 	LDAP_OTHER
   449 	LDAP_TIMEOUT
   462 	LDAP_TIMEOUT
   450 	LDAP_NO_MEMORY
   463 	LDAP_NO_MEMORY
   451 	LDAP_CONNECT_ERROR /;
   464 	LDAP_CONNECT_ERROR
       
   465 	LDAP_CONTROL_PAGED /;
   452 use Net::LDAP::Util qw/ canonical_dn ldap_explode_dn /;
   466 use Net::LDAP::Util qw/ canonical_dn ldap_explode_dn /;
   453 use Net::LDAP::LDIF;
   467 use Net::LDAP::LDIF;
       
   468 use Net::LDAP::Extension::SetPassword;
       
   469 use Net::LDAP::Control::Paged;
   454 use Data::Dumper;
   470 use Data::Dumper;
   455 use File::Temp;
   471 use File::Temp;
   456 use Algorithm::Diff;
   472 use Algorithm::Diff;
   457 use Carp 'confess';
   473 use Carp 'confess';
   458 use base 'Term::Shell';
   474 use base 'Term::Shell';
   459 require Net::LDAP::Extension::SetPassword;
       
   460 
   475 
   461 my $conf = $main::conf;
   476 my $conf = $main::conf;
   462 
   477 
   463 # make 'die' backtrace in debug mode
   478 # make 'die' backtrace in debug mode
   464 $SIG{'__DIE__'} = \&Carp::confess if $conf->{'debug'};
   479 $SIG{'__DIE__'} = \&Carp::confess if $conf->{'debug'};
   504 	if ( $conf->{'debug'} ) {
   519 	if ( $conf->{'debug'} ) {
   505 		my @versions = $self->{'root_dse'}->get_value('supportedLDAPVersion');
   520 		my @versions = $self->{'root_dse'}->get_value('supportedLDAPVersion');
   506 		print "Connected to $conf->{'server'}\n";
   521 		print "Connected to $conf->{'server'}\n";
   507 		print "Supported LDAP version: ", ( join ', ', @versions ), "\n";
   522 		print "Supported LDAP version: ", ( join ', ', @versions ), "\n";
   508 		print "Cipher in use: ", $self->ldap()->cipher(), "\n";
   523 		print "Cipher in use: ", $self->ldap()->cipher(), "\n";
       
   524 	}
       
   525 
       
   526 	# check for the pagination extension on the server early, and bail
       
   527 	# if necessary.
       
   528 	if ( $conf->{'paginate'} && $conf->{'paginate'} =~ /^\d+$/ && $conf->{'paginate'} > 0 ) {
       
   529 		my $has_pagination = ( grep $_ eq LDAP_CONTROL_PAGED, $self->{'root_dse'}->get_value('supportedControl') );
       
   530 		die "Server pagination is enabled, but the server doesn't seem to support it.\n" unless $has_pagination;
       
   531 	}
       
   532 	else {
       
   533 		$conf->{'paginate'} = undef;
   509 	}
   534 	}
   510 
   535 
   511 	# try an initial search and bail early if it doesn't work. (bad baseDN?)
   536 	# try an initial search and bail early if it doesn't work. (bad baseDN?)
   512 	my $s = $self->search();
   537 	my $s = $self->search();
   513 	die "LDAP baseDN error: ", $s->{'message'}, "\n" if $s->{'code'};
   538 	die "LDAP baseDN error: ", $s->{'message'}, "\n" if $s->{'code'};
   871 	}	
   896 	}	
   872 	return;
   897 	return;
   873 }
   898 }
   874 
   899 
   875 
   900 
   876 ### Perform an LDAP search.
   901 ### Perform an LDAP search, optionally with the server side pager
       
   902 ### control.
   877 ###
   903 ###
   878 ### Returns a hashref containing the return code and
   904 ### Returns a hashref containing the return code and
   879 ### an arrayref of Net::LDAP::Entry objects.
   905 ### an arrayref of Net::LDAP::Entry objects.
   880 ###
   906 ###
   881 sub search 
   907 sub search 
   882 {
   908 {
   883 	my $self = shift;
   909 	my $self = shift;
   884 	my $opts = shift || {};
   910 	my $opts = shift || {};
       
   911 	my $controls = [];
   885 
   912 
   886 	$opts->{'base'}   ||= $self->base(),
   913 	$opts->{'base'}   ||= $self->base(),
   887 	$opts->{'filter'} ||= '(objectClass=*)';
   914 	$opts->{'filter'} ||= '(objectClass=*)';
   888 	$opts->{'scope'}  ||= 'base';
   915 	$opts->{'scope'}  ||= 'base';
       
   916 
       
   917 	my $pager;
       
   918 	if ( $conf->{'paginate'} ) {
       
   919 		$pager = Net::LDAP::Control::Paged->new( size => $conf->{'paginate'} );
       
   920 		push( @$controls, $pager );
       
   921 	}
   889 
   922 
   890 	my $search = sub { 
   923 	my $search = sub { 
   891 		return $self->ldap->search(
   924 		return $self->ldap->search(
   892 			base	  => $opts->{'base'},
   925 			base	  => $opts->{'base'},
   893 			filter	  => $opts->{'filter'},
   926 			filter	  => $opts->{'filter'},
   894 			scope	  => $opts->{'scope'},
   927 			scope	  => $opts->{'scope'},
   895 			timelimit => $conf->{'timeout'},
   928 			timelimit => $conf->{'timeout'},
   896 			typesonly => ! $opts->{'vals'},
   929 			typesonly => ! $opts->{'vals'},
   897 			attrs	  => $opts->{'attrs'} || ['*']
   930 			attrs	  => $opts->{'attrs'} || ['*'],
       
   931 			control   => $controls
   898 		);
   932 		);
   899 	};
   933 	};
   900 
   934 
   901 	my $s = $self->with_retry( $search );
   935 	my $s;
       
   936 	my $entries = [];
       
   937    	my $token  = '-';
       
   938 
       
   939 	if ( $conf->{'paginate'} ) {
       
   940 		while( $token ) {
       
   941 			$s = $self->with_retry( $search );
       
   942 			push( @$entries, $s->entries() );
       
   943 
       
   944 			my $page_response = $s->control( LDAP_CONTROL_PAGED ) or last;
       
   945 			$token = $page_response->cookie;
       
   946 			$pager->cookie( $token );
       
   947 		}
       
   948 	}
       
   949 	else {
       
   950 		$s = $self->with_retry( $search );
       
   951 		$entries = [ $s->entries() ];
       
   952 	}
       
   953 
   902 	my $rv = {
   954 	my $rv = {
   903 		code	=> $s->code(),
   955 		code	=> $s->code(),
   904 		message => $s->error(),
   956 		message => $s->error()
   905 		entries => []
       
   906 	};
   957 	};
   907 
   958 
   908 	$rv->{'entries'} =
   959 	if ( $opts->{'scope'} eq 'base' ) {
   909 	  $opts->{'scope'} eq 'base' ? [ $s->shift_entry() ] : [ $s->entries() ];
   960 		$rv->{'entries'} = [ $s->shift_entry() ]
       
   961 	}
       
   962 	else {
       
   963 		$rv->{'entries'} = $entries;
       
   964 	}
   910 
   965 
   911 	return $rv;
   966 	return $rv;
   912 }
   967 }
   913 
   968 
   914 
   969 
  2320 	'server|H=s',
  2375 	'server|H=s',
  2321 	'configfile|f=s',
  2376 	'configfile|f=s',
  2322 	'binddn|D=s',
  2377 	'binddn|D=s',
  2323 	'basedn|b=s',
  2378 	'basedn|b=s',
  2324 	'cacheage=i',
  2379 	'cacheage=i',
       
  2380 	'paginate=i',
  2325 	'promptpass|W',
  2381 	'promptpass|W',
  2326 	'timeout=i',
  2382 	'timeout=i',
  2327 	'sasl|Y=s',
  2383 	'sasl|Y=s',
  2328 	'tls_cacert=s',
  2384 	'tls_cacert=s',
  2329 	'tls_cert=s',
  2385 	'tls_cert=s',
  2348 if ( $conf->{'configfile'} ) {
  2404 if ( $conf->{'configfile'} ) {
  2349 	my $more_conf = load_config( $conf->{'configfile'} );
  2405 	my $more_conf = load_config( $conf->{'configfile'} );
  2350 	while ( my ($k, $v) = each %{$conf} ) { $conf->{ $k } = $v }
  2406 	while ( my ($k, $v) = each %{$conf} ) { $conf->{ $k } = $v }
  2351 }
  2407 }
  2352 
  2408 
  2353 
       
  2354 # defaults
  2409 # defaults
  2355 $conf->{'configfile'} ||= "$ENV{'HOME'}/.shelldap.rc";
  2410 $conf->{'configfile'} ||= "$ENV{'HOME'}/.shelldap.rc";
  2356 $conf->{'cacheage'} ||= 300;
  2411 $conf->{'cacheage'} ||= 300;
  2357 $conf->{'timeout'}  ||= 10;
  2412 $conf->{'timeout'}  ||= 10;
  2358 
  2413