~ubuntu-branches/ubuntu/lucid/ebox-dns/lucid

« back to all changes in this revision

Viewing changes to src/EBox/DNS.pm.in

  • Committer: Bazaar Package Importer
  • Author(s): Javier Uruen Val, Javier Uruen Val
  • Date: 2010-02-07 18:51:11 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100207185111-qfo58di723initiu
Tags: 1.5-0ubuntu1
 [Javier Uruen Val]
 * New upstream release (LP: #521806)
 * debian/control
   - Bump eBox dependency
   - Add dependency on libcrypt-openssl-random-perl
   - Update description
   - Bump Standards-version to 3.8.4. No changes required.
 * debian/copyright: updated emails and dates.
 * debian/watch: fixed by adding /latest in the url

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
use constant BIND9INIT     => "@BIND9_INIT@";
43
43
use constant PIDFILE       => "/var/run/bind/run/named.pid";
44
44
use constant NAMESERVER_HOST => 'ns';
 
45
use constant KEYSFILE => BIND9CONFDIR . '/keys';
45
46
 
46
47
sub _create
47
48
{
48
49
    my $class = shift;
49
50
    my $self = $class->SUPER::_create(name => 'dns',
50
51
            domain => 'ebox-dns',
51
 
            printableName => __('DNS'),
 
52
            printableName => 'DNS',
52
53
            @_);
53
54
 
54
55
    bless($self, $class);
82
83
                            directory => 'aliasTable',
83
84
                           ],
84
85
            },
85
 
            {
86
 
             class => 'EBox::DNS::Model::EnableFormDNS',
87
 
             parameters => [
88
 
                            enableTitle => __('DNS Server'),
89
 
                            modelDomain => 'DNS',
90
 
                            domain      => 'ebox-dns',
91
 
                            directory   => 'enableForm',
92
 
                           ],
93
 
            },
94
86
            'EBox::DNS::Model::MailExchanger',
 
87
            'EBox::DNS::Model::NameServer',
95
88
           ];
96
89
}
97
90
 
162
155
                                 path    => [ 'DomainTable', 'mailExchangers' ],
163
156
                                 indexes => [ 'domain' ],
164
157
                               },
165
 
         # Both last two methods are only working with custom MX records
 
158
         # Both following two methods are only working with custom MX records
166
159
         'changeMXPreference' => { action  => 'set',
167
160
                                   path    => [ 'DomainTable', 'mailExchangers' ],
168
161
                                   indexes => [ 'domain', 'hostName' ],
201
194
#
202
195
sub addDomain
203
196
{
204
 
 my ($self, $domainData) = @_;
205
 
 
206
 
 my $domainModel = EBox::Model::ModelManager->instance()->model('DomainTable');
207
 
 
208
 
 $domainModel->addDomain($domainData);
 
197
    my ($self, $domainData) = @_;
 
198
 
 
199
    my $domainModel = EBox::Model::ModelManager->instance()->model('DomainTable');
 
200
 
 
201
    $domainModel->addDomain($domainData);
209
202
}
210
203
 
211
204
# Method: domains
215
208
#
216
209
#  Array ref - containing hash refs with the following elements:
217
210
#
218
 
#           name - String the domain's name
219
 
#           ipaddr - String the domain's ip address
 
211
#    name    - String the domain's name
 
212
#    ipaddr  - String the domain's ip address
 
213
#    dynamic - Boolean indicating if the domain is dynamically updated
220
214
#
221
215
sub domains
222
216
{
232
226
 
233
227
        $domaindata->{'name'} = $row->valueByName('domain');
234
228
        $domaindata->{'ipaddr'} = $row->valueByName('ipaddr');
 
229
        $domaindata->{'dynamic'} = $row->valueByName('dynamic');
235
230
 
236
231
        push(@array, $domaindata);
237
232
    }
239
234
    return \@array;
240
235
}
241
236
 
242
 
# Method: _hostnames
243
 
#  returns an array with all hostname structure
244
 
#
245
 
# Parameters:
246
 
#   model to iterate over
247
 
#
248
 
# Returns:
249
 
#  array ref with this structure data:
250
 
#  
251
 
#  'name': hostname
252
 
#  'ip': ip address of hostname
253
 
#  'aliases': an array ref returned by <EBox::DNS::aliases> method.
254
 
#  
255
 
sub _hostnames
256
 
{
257
 
    my ($self, $model) = @_;
258
 
    my @array;
259
 
 
260
 
    foreach my $id (@{$model->ids()})
261
 
    {
262
 
        my $hostname = $model->row($id);
263
 
        my $hostdata;
264
 
 
265
 
        $hostdata->{'name'} = $hostname->valueByName('hostname');
266
 
        $hostdata->{'ip'} = $hostname->valueByName('ipaddr');
267
 
        $hostdata->{'aliases'} = 
268
 
            $self->aliases($hostname->subModel('alias'));
269
 
 
270
 
        push(@array, $hostdata);
271
 
    }
272
 
 
273
 
    return \@array;
274
 
}
275
 
 
276
 
# Method: _formatMailExchangers
277
 
#
278
 
#       Format the mail exchangers to write configuration settings
279
 
#       properly. That is, custom MX records appends a full stop after
280
 
#       the type value.
281
 
#
282
 
# Parameters:
283
 
#
284
 
#       mailExchangers - model to iterate over 
285
 
#
286
 
#            hostName - String the host's name
287
 
#            id - String the row identifier
288
 
#            preference - Int the preference attribute
289
 
#            ownerDomain - if the hostname owns to the same domain.
290
 
#            custom - if the hostname is a foreign one
291
 
#
292
 
# Returns:
293
 
#
294
 
#   Array ref of hashes containing the following keys:
295
 
#
296
 
#      hostName   
297
 
#       preference
298
 
sub _formatMailExchangers
299
 
{
300
 
    my ($self, $mailExchangers) = @_;
301
 
 
302
 
    my @mailExchangers;
303
 
    foreach my $id (@{$mailExchangers->ids()}) {
304
 
        my $mx = $mailExchangers->row($id);
305
 
        my $hostName = $mx->valueByName('hostName');
306
 
        if ($mx->elementByName('hostName')->selectedType() eq 'custom') {
307
 
            unless ( $hostName =~ m:\.$: ) {
308
 
                $hostName .= '.';
309
 
            }
310
 
        } else {
311
 
            $hostName = $mx->parentRow()
312
 
               ->subModel('hostnames')
313
 
               ->row($hostName)
314
 
               ->valueByName('hostname');
315
 
        }
316
 
        push (@mailExchangers, { 
317
 
                hostName => $hostName, 
318
 
                preference => $mx->valueByName('preference')
319
 
                });
320
 
    }
321
 
    return \@mailExchangers;
322
 
}
323
237
 
324
238
# Method: getHostnames
325
239
#
445
359
    return NAMESERVER_HOST;
446
360
}
447
361
 
448
 
# Method: _completeDomain
449
 
#
450
 
#  Return a structure with all required data to build bind db config files
451
 
#
452
 
# Parameters:
453
 
#
454
 
#  domain - String the domain's name
455
 
#
456
 
# Returns:
457
 
#
458
 
# hash ref - structure data with:
459
 
#
460
 
#  'name': domain name
461
 
#  'ipaddr': domain ip address
462
 
#  'hosts': an array ref returned by <EBox::DNS::_hostnames> method.
463
 
#
464
 
sub _completeDomain # (domain)
465
 
{
466
 
    my ($self, $domain) = @_;
467
 
    my $model = $self->model('DomainTable');
468
 
    my $domdata;
469
 
 
470
 
    my $row = $model->find(domain => $domain->{'name'});
471
 
    $domdata->{'name'} = $domain->{'name'};
472
 
    $domdata->{'ipaddr'} = $domain->{'ipaddr'};
473
 
    $domdata->{'hosts'} = $self->_hostnames(
474
 
            $row->subModel('hostnames'));
475
 
 
476
 
    my $subModel = $row->subModel('mailExchangers');
477
 
    $domdata->{'mailExchangers'} = $self->_formatMailExchangers($subModel);
478
 
 
479
 
    return $domdata;
480
 
}
481
362
 
482
363
# Method: createHostDataArray
483
364
#  returns host and their alias info in a single hosts array ref.
628
509
    my $files = [{
629
510
            'file' => BIND9CONFFILE,
630
511
            'module' => 'dns',
631
 
            'reason' => 'main bind9 configuration file'
 
512
            'reason' => __('main bind9 configuration file'),
632
513
        },
633
514
       {
634
515
           'file' => BIND9CONFOPTIONSFILE,
635
516
           'module' => 'dns',
636
 
           'reason' => 'bind9 options configuration file'
 
517
           'reason' => __('bind9 options configuration file'),
637
518
       },
638
519
       {
639
520
           'file' => BIND9CONFLOCALFILE ,
640
521
           'module' => 'dns',
641
 
           'reason' => 'local bind9 configuration file'
642
 
       }
 
522
           'reason' => __('local bind9 configuration file'),
 
523
       },
 
524
       {
 
525
           'file'   => KEYSFILE,
 
526
           'module' => 'dns',
 
527
           'reason' => __('Keys configuration file'),
 
528
       },
643
529
    ];
644
530
 
645
531
 
646
 
    my @domains = @{$self->domains()};
 
532
    my @domainIds = @{$self->_domainIds()};
647
533
 
648
534
    my @domainData;
649
 
    foreach my $domain (@domains)
 
535
    foreach my $domainId (@domainIds)
650
536
    {
651
 
        my $domdata = $self->_completeDomain($domain);
 
537
        my $domdata = $self->_completeDomain($domainId);
652
538
        push(@domainData, $domdata);
653
539
        my $file = BIND9CONFDIR . "/db." . $domdata->{'name'};
654
540
        push (@{$files},
655
541
                {
656
542
                'file' => $file,
657
543
                'module' => 'dns',
658
 
                'reason' => __x('configuration file for zone {zone}', 
 
544
                'reason' => __x('configuration file for zone {zone}',
659
545
                    zone => $file )
660
546
                });
661
547
 
680
566
    return $files;
681
567
}
682
568
 
 
569
# Method: actions
 
570
#
 
571
# Overrides:
 
572
#
 
573
#    <EBox::Module::Service::actions>
 
574
#
 
575
sub actions
 
576
{
 
577
    return [
 
578
        { 'action' => __x('Change the permissions for {dir} to allow writing to bind group',
 
579
                          dir => BIND9CONFDIR),
 
580
          'reason' => __('Let the bind daemon to be dynamically updated'),
 
581
          'module' => 'dns' },
 
582
        ];
 
583
 
 
584
}
 
585
 
683
586
# Method: enableActions 
684
587
#
685
588
#  Override EBox::Module::Service::enableActions
713
616
    my ($self, $status) = @_;
714
617
 
715
618
    $self->SUPER::enableService($status);
716
 
    $self->configureFirewall();    
 
619
    $self->configureFirewall();
717
620
}
718
621
 
719
622
# Method: _setConf
724
627
#
725
628
sub _setConf
726
629
{
727
 
    my $self = shift;
 
630
    my ($self) = @_;
728
631
    my @array = ();
729
632
 
730
 
    $self->writeConfFile(BIND9CONFFILE, 
731
 
            "dns/named.conf.mas", 
 
633
    $self->writeConfFile(BIND9CONFFILE,
 
634
            "dns/named.conf.mas",
732
635
            \@array);
733
636
    $self->writeConfFile(BIND9CONFOPTIONSFILE, 
734
 
            "dns/named.conf.options.mas", 
 
637
            "dns/named.conf.options.mas",
735
638
            \@array);
736
639
 
737
 
    my @domains = @{$self->domains()};
738
 
 
739
 
# push(@array, 'domains' => \@domains);
740
 
# $self->writeConfFile(BIND9CONFLOCALFILE, 
741
 
#    "dns/named.conf.local.mas", 
742
 
#    \@array);
743
 
 
744
 
# root("/bin/rm -rf " . BIND9CONFDIR . "/zones/");
745
 
# root("/bin/mkdir " . BIND9CONFDIR . "/zones/");
 
640
    my @domainIds = @{$self->_domainIds()};
 
641
    # Hash to store the keys indexed by name, storing the secret
 
642
    my %keys = ();
746
643
 
747
644
    my @domainData;
748
 
    foreach my $domain (@domains)
749
 
    {
750
 
        my $domdata = $self->_completeDomain($domain);
 
645
    foreach my $domainId (@domainIds) {
 
646
        my $domdata = $self->_completeDomain($domainId);
751
647
        push(@domainData, $domdata);
752
648
 
753
649
        my $file = BIND9CONFDIR . "/db." . $domdata->{'name'};
754
650
        @array = ();
755
651
        push(@array, 'domain' => $domdata);
756
652
        push(@array, 'nameserverHostname' => __PACKAGE__->NameserverHost());
757
 
        $self->writeConfFile($file,"dns/db.mas",\@array);
 
653
        # Prevent to write the file again if this is dynamic and the
 
654
        # journal file has been already created
 
655
        unless ( $domdata->{'dynamic'} and -e "${file}.jnl" ) {
 
656
            $self->writeConfFile($file,"dns/db.mas",\@array);
 
657
        }
 
658
 
 
659
        # Add the updater key if the zone is dynamic
 
660
        if ( $domdata->{'dynamic'} ) {
 
661
            $keys{$domdata->{'name'}} = $domdata->{'tsigKey'};
 
662
        }
758
663
    }
759
664
 
760
665
    my $reversedData = $self->switchToReverseInfoData(\@domainData);
767
672
        @array = ();
768
673
        push(@array, 'rdata' => $reversedDataItem);
769
674
        $self->writeConfFile($file, "dns/dbrev.mas", \@array);
 
675
 
 
676
        # TODO: reversed zone
770
677
    }
771
678
 
 
679
    my @domains = @{$self->domains()};
 
680
 
772
681
    push(@array, 'domains' => \@domains);
773
682
    push(@array, 'inaddrs' => \@inaddrs);
774
683
    $self->writeConfFile(BIND9CONFLOCALFILE,
775
684
            "dns/named.conf.local.mas",
776
685
            \@array);
 
686
 
 
687
    @array = ( 'keys' => \%keys );
 
688
    $self->writeConfFile(KEYSFILE, 'dns/keys.mas', \@array);
 
689
 
777
690
}
778
691
 
779
692
sub configureFirewall
798
711
sub menu
799
712
{
800
713
    my ($self, $root) = @_;
801
 
    $root->add(new EBox::Menu::Item('url' => 'DNS/Composite/DNSComposite',
 
714
    $root->add(new EBox::Menu::Item('url' => 'DNS/View/DomainTable',
802
715
                                    'text' => $self->printableName(),
803
 
                                    'separator' => __('Infrastructure'),
 
716
                                    'separator' => 'Infrastructure',
804
717
                                    'order' => 420));
805
718
}
806
719
 
 
720
sub logReportInfo
 
721
{
 
722
    my ($self) = @_;
 
723
 
 
724
    my $domains = @{$self->domains()};
 
725
    my $data = [
 
726
        {
 
727
            'table'  => 'dns_domains',
 
728
            'values' => {
 
729
                'domains' => $domains
 
730
            }
 
731
        }
 
732
    ];
 
733
    return $data;
 
734
}
 
735
 
 
736
sub consolidateReportInfoQueries
 
737
{
 
738
    return [
 
739
        {
 
740
            'target_table' => 'dns_domains_report',
 
741
            'query' => {
 
742
                'select' => 'domains',
 
743
                'from' => 'dns_domains'
 
744
            }
 
745
        }
 
746
    ];
 
747
}
 
748
 
 
749
# Method: report
 
750
#
 
751
# Overrides:
 
752
#   <EBox::Module::Base::report>
 
753
sub report
 
754
{
 
755
    my ($self, $beg, $end, $options) = @_;
 
756
 
 
757
    my $report = {};
 
758
 
 
759
    $report->{'domains'} = $self->runMonthlyQuery($beg, $end, {
 
760
        'select' => 'domains',
 
761
        'from' => 'dns_domains_report',
 
762
    }, { 'name' => 'domains' });
 
763
 
 
764
    return $report;
 
765
}
 
766
 
 
767
# Method: keysFile
 
768
#
 
769
#     Get the keys file path
 
770
#
 
771
# Returns:
 
772
#
 
773
#     String - the keys file path
 
774
#
 
775
sub keysFile
 
776
{
 
777
    return KEYSFILE;
 
778
}
 
779
 
 
780
# Group: Private methods
 
781
 
 
782
# Method: _hostnames
 
783
#  returns an array with all hostname structure
 
784
#
 
785
# Parameters:
 
786
#   model to iterate over
 
787
#
 
788
# Returns:
 
789
#  array ref with this structure data:
 
790
#  
 
791
#  'name': hostname
 
792
#  'ip': ip address of hostname
 
793
#  'aliases': an array ref returned by <EBox::DNS::aliases> method.
 
794
#  
 
795
sub _hostnames
 
796
{
 
797
    my ($self, $model) = @_;
 
798
    my @array;
 
799
 
 
800
    foreach my $id (@{$model->ids()})
 
801
    {
 
802
        my $hostname = $model->row($id);
 
803
        my $hostdata;
 
804
 
 
805
        $hostdata->{'name'} = $hostname->valueByName('hostname');
 
806
        $hostdata->{'ip'} = $hostname->valueByName('ipaddr');
 
807
        $hostdata->{'aliases'} = 
 
808
            $self->aliases($hostname->subModel('alias'));
 
809
 
 
810
        push(@array, $hostdata);
 
811
    }
 
812
 
 
813
    return \@array;
 
814
}
 
815
 
 
816
# Method: _formatMailExchangers
 
817
#
 
818
#       Format the mail exchangers to write configuration settings
 
819
#       properly. That is, custom MX records appends a full stop after
 
820
#       the type value.
 
821
#
 
822
# Parameters:
 
823
#
 
824
#       mailExchangers - model to iterate over 
 
825
#
 
826
#            hostName - String the host's name
 
827
#            id - String the row identifier
 
828
#            preference - Int the preference attribute
 
829
#            ownerDomain - if the hostname owns to the same domain.
 
830
#            custom - if the hostname is a foreign one
 
831
#
 
832
# Returns:
 
833
#
 
834
#   Array ref of hashes containing the following keys:
 
835
#
 
836
#      hostName
 
837
#       preference
 
838
sub _formatMailExchangers
 
839
{
 
840
    my ($self, $mailExchangers) = @_;
 
841
 
 
842
    my @mailExchangers;
 
843
    foreach my $id (@{$mailExchangers->ids()}) {
 
844
        my $mx = $mailExchangers->row($id);
 
845
        my $hostName = $mx->valueByName('hostName');
 
846
        if ($mx->elementByName('hostName')->selectedType() eq 'custom') {
 
847
            unless ( $hostName =~ m:\.$: ) {
 
848
                $hostName .= '.';
 
849
            }
 
850
        } else {
 
851
            $hostName = $mx->parentRow()
 
852
               ->subModel('hostnames')
 
853
               ->row($hostName)
 
854
               ->valueByName('hostname');
 
855
        }
 
856
        push (@mailExchangers, { 
 
857
                hostName => $hostName, 
 
858
                preference => $mx->valueByName('preference')
 
859
                });
 
860
    }
 
861
    return \@mailExchangers;
 
862
}
 
863
 
 
864
# Method: _formatNameServers
 
865
#
 
866
#       Format the name servers to write configuration settings
 
867
#       properly. That is, custom NS records appends a full stop after
 
868
#       the type value.
 
869
#
 
870
#       If it has none configured, it will configure the following:
 
871
#
 
872
#       @ NS 127.0.0.1 # If there is no hostname named NS
 
873
#       @ NS ns        # If there is a hostname whose name is 'ns'
 
874
#
 
875
# Parameters:
 
876
#
 
877
#       nameServers - model to iterate over
 
878
#
 
879
#            hostName - String the host's name
 
880
#            id - String the row identifier
 
881
#            ownerDomain - if the hostname owns to the same domain.
 
882
#            custom - if the hostname is a foreign one
 
883
#
 
884
#       hostnames   - model with hostnames for that domain
 
885
#
 
886
# Returns:
 
887
#
 
888
#   Array ref of the name servers to set on
 
889
#
 
890
sub _formatNameServers
 
891
{
 
892
    my ($self, $nameServers, $hostnames) = @_;
 
893
 
 
894
    my @nameservers;
 
895
    foreach my $id (@{$nameServers->ids()}) {
 
896
        my $ns = $nameServers->row($id);
 
897
        my $hostName = $ns->valueByName('hostName');
 
898
        if ($ns->elementByName('hostName')->selectedType() eq 'custom') {
 
899
            unless ( $hostName =~ m:\.$: ) {
 
900
                $hostName .= '.';
 
901
            }
 
902
        } else {
 
903
            $hostName = $ns->parentRow()
 
904
               ->subModel('hostnames')
 
905
               ->row($hostName)
 
906
               ->valueByName('hostname');
 
907
        }
 
908
        push (@nameservers, $hostName);
 
909
    }
 
910
    if ( @nameservers == 0 ) {
 
911
        # Look for any hostname whose name is 'ns'
 
912
        my $matchedId = $hostnames->findId(hostname => __PACKAGE__->NameserverHost());
 
913
        if ( defined($matchedId) ) {
 
914
            push(@nameservers, __PACKAGE__->NameserverHost());
 
915
        }
 
916
    }
 
917
 
 
918
    return \@nameservers;
 
919
}
 
920
 
 
921
# Method: _completeDomain
 
922
#
 
923
#  Return a structure with all required data to build bind db config files
 
924
#
 
925
# Parameters:
 
926
#
 
927
#  domain - String the domain's identifier
 
928
#
 
929
# Returns:
 
930
#
 
931
# hash ref - structure data with:
 
932
#
 
933
#  'name': domain name
 
934
#  'ipaddr': domain ip address
 
935
#  'dynamic' : the domain is dynamically updated
 
936
#  'tsigKey' : the TSIG key is the domain is dynamic
 
937
#  'hosts': an array ref returned by <EBox::DNS::_hostnames> method.
 
938
#  'mailExchangers' : an array ref returned by <EBox::DNS::_formatMailExchangers>
 
939
#  'nameServers' : an array ref returned by <EBox::DNS::_formatNameServers>
 
940
#
 
941
sub _completeDomain # (domainId)
 
942
{
 
943
    my ($self, $domainId) = @_;
 
944
 
 
945
    my $model = $self->model('DomainTable');
 
946
    my $row = $model->row($domainId);
 
947
 
 
948
    my $domdata;
 
949
    $domdata->{'name'} = $row->valueByName('domain');
 
950
    foreach my $key (qw(ipaddr dynamic tsigKey)) {
 
951
        $domdata->{$key} = $row->valueByName($key);
 
952
    }
 
953
    $domdata->{'hosts'} = $self->_hostnames(
 
954
            $row->subModel('hostnames'));
 
955
 
 
956
    my $subModel = $row->subModel('mailExchangers');
 
957
    $domdata->{'mailExchangers'} = $self->_formatMailExchangers($subModel);
 
958
    $domdata->{'nameServers'} = $self->_formatNameServers($row->subModel('nameServers'),
 
959
                                                          $row->subModel('hostnames'));
 
960
 
 
961
    return $domdata;
 
962
}
 
963
 
 
964
# Return the domain row ids in an array ref
 
965
sub _domainIds
 
966
{
 
967
    my ($self) = @_;
 
968
 
 
969
    my $model = $self->model('DomainTable');
 
970
    return $model->ids();
 
971
}
807
972
 
808
973
1;