Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/perl
- #
- # We use /usr/local/bin/perl because cygwin installs in /usr/bin/perl and we want to
- # use ActiveState Perl on Windows. As a result, we have to symlink all others
- # links:
- # !compiled_on_cygwin::
- # /usr/local/bin/perl -> /usr/bin/perl type=symbolic
- #
- use strict;
- # This is the LDAP module that makes all the dynamic stuff in cfengine work
- # determine this host's fqdn
- # determine this host's domain name
- # do a srv record lookup for ldap tcp 636 on this domain name
- #
- # if this host's fqdn is one of the returned records:
- # try to connect to self's fqdn for LDAP,
- # then try to connect to other records until one connects
- # if one is reached:
- # look up cn=hostname, ou=Hosts, dc=domain, dc=domain, dc=domain
- # and activate all classes in record and exit.
- # if record is not found, back-off and retry on next pass.
- # if none of the ldap servers can be reached, including oneself then assume localhost
- # is the first of it's kind and:
- # activate core_server, which will:
- # activate cfengine_server
- # (if debian) update /etc/apt/sources.list to use backports
- # (if debian) create /etc/apt/preferences to mask backports for !git
- # install git
- # install git2masterfiles
- # activate certificate_authority
- # using "secret" create caroot tree
- # using "secret" create gpg identity
- # activate ldap_server, which will:
- # add slapd.conf for self's domain name (determined earlier) if not exists
- # start slapd,
- # create self's host record if it doesn't exist,
- # define classes for self
- # setup and run all core services
- #
- # if no ldap servers are reachable and the fqdn is not in the _ldap._tcp srv list,
- # then take no action; Assume the host is disconnected from the core completely.
- #
- package Superstring;
- use Data::Dumper;
- sub new{
- use Sys::Hostname;
- use Sys::Hostname::Long;
- use FileHandle;
- my $class = shift;
- my $construct = shift if @_;
- my $self = { };
- bless ($self, $class);
- $self->{'cfg'}->{'fqdn'} = hostname_long();
- $self->{'cfg'}->{'hostname'} = hostname();
- $self->{'cfg'}->{'hostname'}=~s/\..*//g;
- $self->{'cfg'}->{'domain'} = $self->{'cfg'}->{'fqdn'};
- $self->{'cfg'}->{'domain'} =~ s/^$self->{'cfg'}->{'hostname'}\.//;
- $self->{'cfg'}->{'base_dn'} = $self->{'cfg'}->{'domain'};
- $self->{'cfg'}->{'base_dn'} =~ s/^/dc=/;
- $self->{'cfg'}->{'base_dn'} =~ s/\./,dc=/;
- if(-f "/usr/local/sbin/secret"){
- my $sech = new FileHandle;
- if($sech->open("/usr/local/sbin/secret|")){
- $self->{'cfg'}->{'secret'}=<$sech>;
- $sech->close;
- }
- }
- if($self->{'cfg'}->{'domain'} ne ""){
- return $self;
- }
- return undef;
- }
- ###################################################
- # Get all the DNS records that could determine
- # what this host is supposed to be
- ###################################################
- sub get_dns_records(){
- use Net::DNS;
- my $self = shift;
- my $res = Net::DNS::Resolver->new;
- my $query = $res->query("_ldap._tcp.".$self->{'cfg'}->{'domain'}, "SRV");
- if ($query){
- foreach my $rr (grep { $_->type eq 'SRV' } $query->answer) {
- push(@{ $self->{'cfg'}->{'ldap_servers'} },$rr->target);
- if($rr->target eq $self->{'cfg'}->{'fqdn'}){
- push(@{ $self->{'cfclasses'} },"ldap_server");
- }
- }
- }else{
- push(@{ $self->{'cfclasses'} },'dns_errors');
- warn "query failed: ", $res->errorstring, "\n";
- }
- my $query = $res->query($self->{'cfg'}->{'domain'}, "NS");
- if ($query){
- foreach my $rr (grep { $_->type eq 'NS' } $query->answer) {
- my $nameserver=$rr->nsdname;
- my $res2 = Net::DNS::Resolver->new;
- my $subquery = $res2->query($nameserver, "A");
- if ($subquery){
- foreach my $rra (grep { $_->type eq 'A' } $subquery->answer) {
- push(@{ $self->{'cfg'}->{'dns'}->{'a'}->{$nameserver} },$rra->address);
- my $res3 = Net::DNS::Resolver->new;
- my $ptrquery = $res2->query($rra->address, "PTR");
- if ($ptrquery){
- foreach my $rrp (grep { $_->type eq 'PTR' } $ptrquery->answer) {
- push(@{ $self->{'cfg'}->{'dns'}->{'ptr'}->{$rra->address} },$rrp->ptrdname);
- if($rrp->ptrdname eq $self->{'cfg'}->{'fqdn'}){
- push(@{ $self->{'cfclasses'} },"bind9_server");
- }
- }
- }else{
- push(@{ $self->{'cfclasses'} },'dns_errors');
- warn "query failed: ", $res3->errorstring, "\n";
- }
- }
- }else{
- push(@{ $self->{'cfclasses'} },'dns_errors');
- warn "query failed: ", $res2->errorstring, "\n";
- }
- push(@{ $self->{'cfg'}->{'dns'}->{'ns'} },$rr->nsdname);
- if($rr->nsdname eq $self->{'cfg'}->{'fqdn'}){
- push(@{ $self->{'cfclasses'} },"bind9_server");
- }
- }
- }else{
- warn "query failed: ", $res->errorstring, "\n";
- }
- return $self;
- }
- sub add_classes(){
- my $self=shift;
- foreach my $c (@_){
- push(@{ $self->{'cfclasses'} }, $c);
- }
- return $self;
- }
- sub dumpclasses(){
- my $self=shift;
- foreach my $c (@{ $self->{'cfclasses'} }){
- print "+",$c,"\n";
- }
- return $self;
- }
- sub dumpvariables(){
- my $self=shift;
- foreach my $k (keys(%{ $self->{'variables'} })){
- print "=",$k,"=",$self->{'variables'}->{$k},"\n";
- }
- return $self;
- }
- sub ldap_servers{
- my $self=shift;
- return $self->{'cfg'}->{'ldap_servers'} if defined $self->{'cfg'}->{'ldap_servers'};
- return undef;
- }
- sub domain{
- my $self=shift;
- return $self->{'cfg'}->{'domain'} if defined $self->{'cfg'}->{'domain'};
- return undef;
- }
- sub base_hostname{
- my $self=shift;
- return $self->{'cfg'}->{'hostname'} if defined $self->{'cfg'}->{'hostname'};
- return undef;
- }
- sub fqdomain{
- my $self=shift;
- return $self->{'cfg'}->{'fqdn'} if defined $self->{'cfg'}->{'fqdn'};
- return undef;
- }
- ###################################################
- # Attempt to contact all the LDAP Servers
- # and get this hosts LDAP record
- ###################################################
- sub ldapsearch{
- use Net::LDAP;
- my $self=shift;
- my $setup=shift;
- my $returnlist;
- my $ldap = Net::LDAP->new( $setup->{'host'}, timeout => 10) or warn "$@";
- my $mesg;
- if($ldap){
- if(defined($self->{'cfg'}->{'secret'})){
- $mesg = $ldap->bind(
- "cn=$self->{'cfg'}->{'hostname'},ou=Hosts,$self->{'cfg'}->{'base_dn'}",
- password=> $self->{'cfg'}->{'secret'}
- );
- }else{
- $mesg = $ldap->bind; # an anonymous bind
- }
- $mesg = $ldap->search( base => $setup->{'basedn'},scope=>'base',filter => "($setup->{'search'})");
- $mesg->code && warn $mesg->error;
- foreach my $entry ($mesg->entries) { push(@{$returnlist},$entry); }
- $mesg = $ldap->unbind; # take down session
- }
- return $returnlist;
- }
- sub host_ldap_record(){
- my $self=shift;
- my $host=shift;
- my $basedn="cn=".$self->base_hostname().",ou=Hosts,dc=".join(",dc=",split(/\./,$self->domain()));
- my $searchdn="cn=".$self->base_hostname();
- # loop through ldap_records and see if we are one of them...
- my $iamone=0;
- foreach my $ldap_server (@{$self->ldap_servers}){
- if($self->{'cfg'}->{'fqdn'} eq $ldap_server){ $iamone=1; }
- }
- # first try to fetch the record from oneself
- if($iamone){
- # get host record from our self
- print STDERR "Searching for $searchdn via ldap://".$self->fqdomain().":636\n";
- $self->{'cfg'}->{'ldap'}->{'hostrecord'}=$self->ldapsearch({'host'=>$self->fqdomain(),'basedn'=>$basedn,'search'=>$searchdn});
- }
- if(!defined( $self->{'cfg'}->{'ldap'}->{'hostrecord'} )){
- foreach my $ldap_server (@{$self->ldap_servers}){
- # We already tried self...
- next if(($self->{'cfg'}->{'fqdn'} eq $ldap_server)||(defined($self->{'cfg'}->{'ldap'}->{'hostrecord'})));
- print STDERR "Searching for $searchdn via ldap://".$ldap_server.":636\n";
- $self->{'cfg'}->{'ldap'}->{'hostrecord'}=$self->ldapsearch({'host'=>$ldap_server,'basedn'=>$basedn,'search'=>$searchdn});
- if(defined($self->{'cfg'}->{'ldap'}->{'hostrecord'})){ print STDERR "$searchdn found.\n"; }
- }
- }
- if(($iamone eq 1)&&(!defined( $self->{'cfg'}->{'ldap'}->{'hostrecord'} ))){
- $self->add_classes("core_server");
- }
- return $self;
- }
- 1;
- my $ss = Superstring->new();
- if($ss){
- $ss->get_dns_records();
- if(defined($ss->ldap_servers())){
- $ss->host_ldap_record($ss->fqdomain());
- foreach my $entry ( @{ $ss->{'cfg'}->{'ldap'}->{'hostrecord'} }){
- foreach my $attr ( $entry->attributes ){
- if($attr =~ /^configSet$/i){
- $ss->add_classes($entry->get_value( $attr ));
- }
- if($attr =~ /^configBase$/i){
- $ss->add_classes($entry->get_value( $attr ));
- }
- }
- }
- }else{
- print "No ldap server SRV records found in DNS\n";
- }
- binmode STDOUT;
- $ss->dumpclasses();
- $ss->dumpvariables();
- }
- #print Data::Dumper->Dump([$ss]);
Add Comment
Please, Sign In to add comment