~ubuntu-branches/ubuntu/vivid/gosa/vivid

« back to all changes in this revision

Viewing changes to dns/admin/systems/services/dns/class_servDNS.inc

Tags: 2.7.1-1
* New upstream release
* Updated packaging to not include smarty (Closes: #620489)
* Fixed case of POSIX (Closes: #620486)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
class servdns extends goService
 
4
{
 
5
    /* attribute list for save action */
 
6
    var $ignore_account   = FALSE;
 
7
    var $attributes       = array(); 
 
8
    var $objectclasses    = array("whatever");
 
9
 
 
10
    var $RecordTypes      = array();
 
11
    var $Zones            = array();
 
12
 
 
13
    var $orig_dn          = "";
 
14
 
 
15
    var $initially_was_account;
 
16
 
 
17
    /* ServerService tab vars */
 
18
    var $conflicts        = array("servdns");
 
19
    var $DisplayName      = "";
 
20
    var $StatusFlag       = "";
 
21
    var $view_logged      = FALSE;
 
22
 
 
23
    var $dns_server_list   = array("ENTRIES"=> array(),"FOR_LIST"=> array());
 
24
    var $take_over_id       = -1;
 
25
 
 
26
 
 
27
    function servdns (&$config, $dn= NULL, $parent= NULL)
 
28
    {
 
29
        plugin::plugin ($config, $dn, $parent);
 
30
 
 
31
        $this->DisplayName = _("DNS service");
 
32
 
 
33
        $this->orig_dn = $dn;
 
34
 
 
35
        /* Get record types for zones
 
36
         */
 
37
        $this->RecordTypes = DNS::getDnsRecordTypes(true);
 
38
 
 
39
        /* Get all zone Informations
 
40
         */
 
41
        $this->Zones = DNS::getDNSZoneEntries($config,$dn);
 
42
 
 
43
        /* If there is at least one entry in this -> types, we have DNS enabled 
 
44
         */
 
45
        if(count($this->Zones) == 0){
 
46
            $this->is_account = false;
 
47
            $this->dns_server_list = $this->get_list_of_dns_servers();
 
48
        }else{
 
49
            $this->is_account = true;
 
50
        }
 
51
        $this->initially_was_account = $this->is_account;
 
52
 
 
53
        // Prepare lists
 
54
        $this->zoneList = new sortableListing();
 
55
        $this->zoneList->setDeleteable(true);
 
56
        $this->zoneList->setEditable(true);
 
57
        $this->zoneList->setWidth("100%");
 
58
        $this->zoneList->setHeight("300px");
 
59
        $this->zoneList->setHeader(array(_("Zone"),_("Reverse zone"),_("TTL"),_("Class")));
 
60
        $this->zoneList->setColspecs(array('*','*','*','*','40px'));
 
61
        $this->zoneList->setDefaultSortColumn(0);
 
62
    }
 
63
 
 
64
 
 
65
    function get_list_of_dns_servers()
 
66
    {
 
67
        $ret = array("ENTRIES"=> array(),"FOR_LIST"=> array());
 
68
        $ldap = $this->config->get_ldap_link();
 
69
        $ldap->cd($this->config->current['BASE']);
 
70
        $ldap->search("(&(objectClass=dNSZone)(zoneName=*))",array("dn","zoneName"));
 
71
        $dns = array();
 
72
        while($attrs = $ldap->fetch()){
 
73
            /* Skip own config */
 
74
            if($this->dn != "new" && preg_match("/".preg_quote($this->dn, '/')."$/",$attrs['dn'])){
 
75
                continue;
 
76
            }
 
77
            $dn = preg_replace("/^zoneName=[^,]+,/","",$attrs['dn']);
 
78
            if(preg_match("/^cn=/",$dn) && !in_array($dn,$dns)){
 
79
                $dns[] = $dn;
 
80
            }
 
81
        }
 
82
        $i = 0;
 
83
        foreach($dns as $dn){
 
84
            $ldap->cat($dn,array('*'));
 
85
            if($ldap->count()){
 
86
                $i ++;
 
87
                $attrs = $ldap->fetch();
 
88
                $ret['ENTRIES'][$i]   = $attrs;
 
89
                $ret['FOR_LIST'][$i] = $attrs['cn'][0];
 
90
            }
 
91
        }
 
92
        return($ret);
 
93
    }  
 
94
 
 
95
 
 
96
    function get_dns_info_string($id)
 
97
    {
 
98
        $ret="";
 
99
        $ldap = $this->config->get_ldap_link();
 
100
        $ldap->cd($this->dns_server_list['ENTRIES'][$id]['dn']);
 
101
        $ldap->search("(|(zoneName=*)(relativeDomainName=*))",array("dn"));
 
102
        while($attrs = $ldap->fetch()){
 
103
            $ret .= $attrs['dn']."\n";
 
104
        }
 
105
        return($ret);
 
106
    }
 
107
 
 
108
 
 
109
    function execute()
 
110
    {
 
111
        /* Call parent execute 
 
112
         */
 
113
        plugin::execute();
 
114
 
 
115
        if($this->is_account && !$this->view_logged){
 
116
            $this->view_logged = TRUE;
 
117
            new log("view","server/".get_class($this),$this->dn);
 
118
        }
 
119
 
 
120
        /* Fill templating stuff 
 
121
         */
 
122
        $smarty= get_smarty();
 
123
        $smarty->assign("dns_take_over",FALSE);
 
124
        $smarty->assign("is_createable",$this->acl_is_createable());
 
125
        $display= "";
 
126
 
 
127
 
 
128
        $this->initially_was_account= $this->is_account;
 
129
        /*****************/
 
130
        /* Handle Take Over Actions
 
131
        /*****************/
 
132
 
 
133
        /* Give smarty the required informations */
 
134
        $smarty->assign("dns_server_list", $this->dns_server_list['FOR_LIST']);
 
135
        $smarty->assign("dns_server_list_cnt", count($this->dns_server_list['FOR_LIST']));
 
136
 
 
137
        /* Take over requested, save id */
 
138
        if(isset($_POST['take_over_src']) && isset($_POST['take_over'])){
 
139
            $id = get_post('take_over_src');
 
140
            if(isset($this->dns_server_list['ENTRIES'][$id])){
 
141
                $this->take_over_id = $id;
 
142
            }
 
143
        }
 
144
 
 
145
        /* Abort take over action */
 
146
        if(isset($_POST['cancel_take_over'])){
 
147
            $this->dialog =false;
 
148
            $this->take_over_id = -1;
 
149
            $this->dns_server_list = $this->get_list_of_dns_servers();
 
150
        }
 
151
 
 
152
        /* Display informartion about take over that will be started when saving this server
 
153
         *  and hide default dns output
 
154
         */
 
155
        if($this->take_over_id != -1){
 
156
            $this->dialog = FALSE;
 
157
            $id = $this->take_over_id;
 
158
            $info = $this->get_dns_info_string($id);
 
159
            $smarty->assign("dns_take_over",TRUE);
 
160
            $smarty->assign("info",$info);
 
161
            $warning = sprintf(_("You are going to migrate the DNS setup from server '%s'."),$this->dns_server_list['ENTRIES'][$id]['cn'][0]);
 
162
            $warning2 = _("The migration will be started when you save this system. To cancel this action, use the cancel button below.");
 
163
            $smarty->assign("warning",$warning);
 
164
            $smarty->assign("warning2",$warning2);
 
165
            return($smarty->fetch(get_template_path('servdns.tpl', TRUE, dirname(__FILE__))));
 
166
        }
 
167
 
 
168
 
 
169
        /* Do we need to flip is_account state? 
 
170
         */
 
171
        if (isset($_POST['modify_state'])){
 
172
            $this->is_account= !$this->is_account;
 
173
        }
 
174
 
 
175
        /* Edited or Added zone 
 
176
         */
 
177
        if(isset($_POST['SaveZoneChanges'])){
 
178
            $this->dialog->save_object();
 
179
 
 
180
            /* Check for errors  
 
181
             */
 
182
            if(count($this->dialog->check())){
 
183
                foreach($this->dialog->check() as $msgs){
 
184
                    msg_dialog::display(_("Error"), $msgs, ERROR_DIALOG);
 
185
                }
 
186
            }else{
 
187
                /* add new/edited zone 
 
188
                 */
 
189
                $ret = $this->dialog->save();
 
190
                if(!$this->dialog->isNew){
 
191
                    unset($this->Zones[$this->dialog->OldZoneName]);
 
192
                }
 
193
                $this->Zones[$ret['zoneName']] = $ret;
 
194
                $this->dialog = FALSE;
 
195
            }
 
196
        }
 
197
 
 
198
        /* Cancel zone edit / new 
 
199
         */
 
200
        if(isset($_POST['CancelZoneChanges'])){
 
201
            $this->dialog = FALSE;
 
202
        }
 
203
 
 
204
        /* Add empty new zone 
 
205
         */
 
206
        if(isset($_POST['AddZone'])){
 
207
            $this->dialog = new servdnseditZone($this->config,$this->dn);
 
208
            if($this->is_new){
 
209
                $this->dialog->acl_base = $this->acl_base;
 
210
                $this->dialog->acl_category = $this->acl_category;
 
211
            }
 
212
        }
 
213
 
 
214
        /* Check for edit zone request 
 
215
         */
 
216
        $this->zoneList->save_object();
 
217
        $action = $this->zoneList->getAction();
 
218
        if($action['action'] == 'delete'){
 
219
            $id = $this->zoneList->getKey($action['targets'][0]);
 
220
            $this->RemoveZone($id);
 
221
        }
 
222
        if($action['action'] == 'edit'){
 
223
            $id = $this->zoneList->getKey($action['targets'][0]);
 
224
            $this->dialog= new servdnseditZone($this->config,$this->dn,$this->Zones[$id]);
 
225
            $this->dialog->acl_base = $this->acl_base;
 
226
            $this->dialog->acl_category = $this->acl_category;
 
227
        }
 
228
 
 
229
 
 
230
        /* Show dialog 
 
231
         */
 
232
        if(is_object($this->dialog)){
 
233
            $this->dialog->save_object();
 
234
            $this->dialog->parent = $this;
 
235
            return($this->dialog->execute());
 
236
        }
 
237
 
 
238
        /* Create Listbox with existing Zones 
 
239
         */
 
240
        $this->zoneList->setAcl($this->getacl(""));
 
241
 
 
242
        $lData = array();
 
243
        foreach($this->Zones as $zone => $values ){
 
244
            $lData[$zone] = array('data' => array($zone,$values['ReverseZone'],$values['sOAttl'],$values['dNSClass']));
 
245
        }    
 
246
        $this->zoneList->setListData($this->Zones,$lData);
 
247
        $this->zoneList->update();
 
248
 
 
249
        /* Display tempalte 
 
250
         */
 
251
        $smarty->assign("ZoneList",$this->zoneList->render());
 
252
        $display.= $smarty->fetch(get_template_path('servdns.tpl', TRUE, dirname(__FILE__)));
 
253
        return($display);
 
254
    }
 
255
 
 
256
 
 
257
    /* Delete specified zone
 
258
     */
 
259
    function RemoveZone($id,$force = FALSE)
 
260
    {
 
261
        $zones =  $this->getUsedZoneNames();
 
262
 
 
263
        if(isset($this->Zones[$id]['InitialReverseZone'])){
 
264
            $rev = DNS::FlipIp($this->Zones[$id]['InitialReverseZone']);
 
265
        }else{
 
266
            $rev = DNS::FlipIp($this->Zones[$id]['ReverseZone']);
 
267
        }
 
268
 
 
269
        $zonename = "";
 
270
        if(isset($this->Zones[$id]['InitialzoneName'])){
 
271
            $zonename= $this->Zones[$id]['InitialzoneName'];
 
272
        }
 
273
 
 
274
        $used = array();
 
275
 
 
276
        /* Add Records which use this zoneName
 
277
         */
 
278
        if(isset($zones[$zonename])){
 
279
            $used = array_merge($used,$zones[$zonename]);
 
280
        }
 
281
 
 
282
        /* Add Records which uses this reverse zone
 
283
         */
 
284
        if(isset($zones[$rev.".in-addr.arpa."])){
 
285
            $used = array_merge($used,$zones[$rev.".in-addr.arpa."]);
 
286
        } 
 
287
 
 
288
        /* There are still entries using this configuration
 
289
         *  Abort deletion
 
290
         */
 
291
        if(count($used) && !$force){
 
292
            $i = 2;
 
293
            $str ="";
 
294
            foreach($used as $dn){
 
295
                if($i > 0 && !preg_match("/,relativeDomainName=/",$dn)){
 
296
                    $i --;
 
297
                    $name = preg_replace("/^[^=]+=([^,]*),.*$/","\\1",$dn);
 
298
                    $zone = preg_replace("/^.*zoneName=([^,]*),.*$/","\\1",$dn);
 
299
                    $str.= $name.".".$zone." ";
 
300
                }
 
301
            }
 
302
 
 
303
            /*  Only show 2 dns in the error message 
 
304
             */
 
305
            if(count($used)> 2) {
 
306
                $str .=" ... ";
 
307
            }
 
308
            msg_dialog::display(_("Error"), sprintf(_("Cannot delete the selected zone. It is still in use by '%s'"), trim($str)), ERROR_DIALOG);
 
309
            return(false);
 
310
        }else{
 
311
            unset($this->Zones[$id]);
 
312
            return(true);
 
313
        }
 
314
    } 
 
315
 
 
316
 
 
317
    /* This funtion returns all used Zonenames 
 
318
     */
 
319
    function getUsedZoneNames()
 
320
    {
 
321
        $ret = array();
 
322
        $ldap = $this->config->get_ldap_link();
 
323
        $ldap->cd($this->config->current['BASE']);
 
324
        $ldap->search("(&(objectClass=dNSZone)(!(relativeDomainName=@))(zoneName=*))",array("zoneName","relativeDomainName"));
 
325
        while($attr = $ldap->fetch()){
 
326
            $ret[$attr['zoneName'][0]][] = $attr['dn'];
 
327
        }
 
328
        return($ret);
 
329
    }
 
330
 
 
331
 
 
332
    /* Remove dns service 
 
333
     */
 
334
    function remove_from_parent()
 
335
    {
 
336
        if($this->initially_was_account){
 
337
            $bool = true;
 
338
            $this->is_account = FALSE;
 
339
            foreach($this->Zones as $key => $zone){
 
340
                $bool= $bool & $this->RemoveZone($key,TRUE);
 
341
            }
 
342
            if($bool){
 
343
                $this->save();
 
344
            }
 
345
            return($bool);
 
346
        }
 
347
    }
 
348
 
 
349
 
 
350
    /* Save to LDAP */
 
351
    function save()
 
352
    {
 
353
 
 
354
        /* Take over handling
 
355
         * - Create list of zones managed by source server 
 
356
         * - Copy ldap entries to destination server 
 
357
         * - Remove old zone entries from source
 
358
         */
 
359
        if($this->take_over_id != -1){
 
360
            $del = array();
 
361
            $id = $this->take_over_id;
 
362
            $src = $this->dns_server_list['ENTRIES'][$id]['dn'];
 
363
            $ldap = $this->config->get_ldap_link(); 
 
364
            $ldap->ls("(objectClass=dnsZone)",$src,array('cn'));
 
365
            while($attrs = $ldap->fetch()){
 
366
                $src_zone = $attrs['dn'];
 
367
                $dst_zone = preg_replace("/".preg_quote($src, '/')."$/",$this->dn,$src_zone);
 
368
                $res = plugin::recursive_move($src_zone, $dst_zone);
 
369
 
 
370
                if($res){
 
371
                    $del [] = $src_zone;
 
372
                }
 
373
            }
 
374
            foreach($del as $src_zone){
 
375
                $ldap->rmdir_recursive($src_zone);
 
376
            }
 
377
            return;
 
378
        }
 
379
 
 
380
        /* Save zone editor changes now */
 
381
        foreach($this->Zones as $name => $zone){
 
382
            if(isset($zone['zoneEditor'] ) && $zone['zoneEditor'] != NULL && is_object($zone['zoneEditor'])){
 
383
                $zone['zoneEditor']->save();
 
384
                unset($this->Zones[$name]['zoneEditor']);;
 
385
            }
 
386
        }
 
387
 
 
388
        $ldap = $this->config->get_ldap_link();
 
389
        $ldap->cd($this->config->current['BASE']);  
 
390
 
 
391
        /* Get differences 
 
392
         */
 
393
        $old_dn = $this->orig_dn;
 
394
        if($old_dn == "new"){
 
395
            $old_dn = $this->dn;
 
396
        }
 
397
 
 
398
        /* Update dns to current object dn */ 
 
399
        $tmp = DNS::getDNSZoneEntriesDiff($this->config,$this->Zones,$old_dn);
 
400
        $tmp2 = array();
 
401
        foreach($tmp as $key1 => $data1){
 
402
            $tmp2[$key1] = array();
 
403
            foreach($data1 as $key2 => $data2){
 
404
                $tmp2[$key1][preg_replace("/".preg_quote($old_dn, '/')."$/",$this->dn,$key2)] = $data2;
 
405
            }
 
406
        }
 
407
        $tmp = $tmp2;
 
408
 
 
409
        /* Updated zone entries if reverser or forward name has changed  
 
410
         * Must be done before moving entries, else the given dn is invalid
 
411
         */
 
412
        if(isset($tmp['zoneUpdates'])){
 
413
            foreach($tmp['zoneUpdates'] as $dn => $attrs){
 
414
                $ldap->cd($dn);
 
415
                $ldap->modify($attrs);
 
416
                new log("modify","unknown/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
 
417
                if (!$ldap->success()){
 
418
                    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
 
419
                }
 
420
            }
 
421
        }
 
422
 
 
423
        /* Delete dns 
 
424
         */
 
425
        foreach($tmp['del'] as $dn => $del){
 
426
 
 
427
            $for = $del['InitialzoneName'];
 
428
            $rev = DNS::FlipIp($del['InitialReverseZone']).".in-addr.arpa.";
 
429
 
 
430
            $ldap->cd($dn);
 
431
            $ldap->rmdir_recursive($dn);
 
432
            new log("remove","unknown/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
 
433
            if (!$ldap->success()){
 
434
                msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
 
435
            }
 
436
 
 
437
            /* Handle Post events */
 
438
            if(preg_match("/^zoneName=/",$dn)){
 
439
#        $this->handle_post_events("remove",array("dn" => $dn,"zoneName" => $for));
 
440
#        $this->handle_post_events("remove",array("dn" => $dn,"zoneName" => $rev));
 
441
            }
 
442
        }
 
443
 
 
444
        /* move follwoing entries
 
445
         */
 
446
        foreach($tmp['move'] as $src => $dst){
 
447
            $this->recursive_move($src,$dst);
 
448
        }
 
449
 
 
450
        /* Add || Update new DNS entries
 
451
         */
 
452
        foreach($tmp['add'] as $dn => $attrs){
 
453
            $ldap->cd($dn);
 
454
            $ldap->cat($dn, array('dn'));
 
455
            if($ldap->fetch()){
 
456
                $ldap->cd($dn);
 
457
                $ldap->modify ($attrs);
 
458
                if (!$ldap->success()){
 
459
                    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
 
460
                }
 
461
 
 
462
                /* Handle Post events */
 
463
                if(preg_match("/^zoneName=/",$dn)){
 
464
#          $this->handle_post_events("modify",array("dn" => $dn,"zoneName" => $attrs['zoneName']));
 
465
                }
 
466
            }else{
 
467
                $ldap->cd($dn);
 
468
                $ldap->add($attrs);
 
469
                if (!$ldap->success()){
 
470
                    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_ADD, get_class()));
 
471
                }
 
472
 
 
473
                /* Handle Post events */
 
474
                if(preg_match("/^zoneName=/",$dn)){
 
475
#          $this->handle_post_events("add",array("dn" => $dn,"zoneName" => $attrs['zoneName']));
 
476
                }
 
477
            }
 
478
        }
 
479
        $this->handle_post_events("modify");
 
480
    }
 
481
 
 
482
 
 
483
    /* Directly save new status flag */
 
484
    function setStatus($value)
 
485
    {
 
486
        if($value == "none") return;
 
487
        if(!$this->initially_was_account) return;
 
488
        if(empty($this->StatusFlag)) return;
 
489
        $ldap = $this->config->get_ldap_link();
 
490
        $ldap->cd($this->dn);
 
491
        $ldap->cat($this->dn,array("objectClass"));
 
492
        if($ldap->count()){
 
493
 
 
494
            $tmp = $ldap->fetch();
 
495
            for($i = 0; $i < $tmp['objectClass']['count']; $i ++){
 
496
                $attrs['objectClass'][] = $tmp['objectClass'][$i];
 
497
            }
 
498
            $flag = $this->StatusFlag;
 
499
            $attrs[$flag] = $value;
 
500
            $this->$flag = $value;
 
501
            $ldap->modify($attrs);
 
502
            if (!$ldap->success()){
 
503
                msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
 
504
            }
 
505
            $this->action_hook();
 
506
        }
 
507
    }
 
508
 
 
509
 
 
510
    function getListEntry()
 
511
    {
 
512
        $fields               = goService::getListEntry(); 
 
513
        $fields['Message']    = _("DNS service");
 
514
#$fields['AllowEdit']  = true;
 
515
        return($fields);
 
516
    }
 
517
 
 
518
 
 
519
    /* Get updates for status flag */
 
520
    function updateStatusState()
 
521
    {
 
522
        if(empty($this->StatusFlag)) return;
 
523
 
 
524
        $attrs = array();
 
525
        $flag = $this->StatusFlag;
 
526
        $ldap = $this->config->get_ldap_link();
 
527
        $ldap->cd($this->cn);
 
528
        $ldap->cat($this->dn,array($flag));
 
529
        if($ldap->count()){
 
530
            $attrs = $ldap->fetch();
 
531
        }
 
532
        if(isset($attrs[$flag][0])){
 
533
            $this->$flag = $attrs[$flag][0];
 
534
        }
 
535
    }
 
536
 
 
537
 
 
538
    /* Return plugin informations for acl handling */
 
539
    static function plInfo()
 
540
    {
 
541
        return (array(
 
542
                    "plShortName"   => _("DNS service"),
 
543
                    "plDescription" => _("DNS service")." ("._("Services").")",
 
544
                    "plSelfModify"  => FALSE,
 
545
                    "plDepends"     => array(),
 
546
                    "plPriority"    => 83,
 
547
                    "plSection"     => array("administration"),
 
548
                    "plCategory"    => array("server"),
 
549
 
 
550
                    "plProvidedAcls"=> array(
 
551
                        "start"         => _("Start service"),  // Remove this to hide the start button at all.
 
552
                        "stop"          => _("Stop service"),   // Remove this to hide the stop button at all.
 
553
                        "restart"       => _("Restart service"),// Remove this to hide the restart button at all.
 
554
 
 
555
                        "zoneName"      =>_("Zone name"),
 
556
                        "ReverseZone"   =>_("Reverse zone"),
 
557
                        "NetworkClass"  =>_("Network class"),
 
558
                        "zoneEditor"    =>_("Zone entry editor"),
 
559
                        "sOAprimary"    =>_("Primary DNS server"),
 
560
                        "sOAmail"       =>_("Mail address"),
 
561
                        "sOAserial"     =>_("Serial"),
 
562
                        "sOArefresh"    =>_("Refresh"),
 
563
                        "sOAretry"      =>_("Retry"),
 
564
                        "sOAexpire"     =>_("Expire"),
 
565
                        "sOAttl"        =>_("TTL"),
 
566
                        "mXRecord"      =>_("MX records"),
 
567
                        "zoneRecords"   =>_("Zone records"))
 
568
                        ));
 
569
    }
 
570
 
 
571
}
 
572
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 
573
?>