File Coverage

blib/lib/Kolab/Conf.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Kolab::Conf;
2              
3             ##
4             ## Copyright (c) 2003 Code Fusion cc
5             ##
6             ## Writen by Stuart Bingė
7             ## Portions based on work by the following people:
8             ##
9             ## (c) 2003 Tassilo Erlewein
10             ## (c) 2003 Martin Konold
11             ## (c) 2003 Achim Frank
12             ##
13             ##
14             ## This program is free software; you can redistribute it and/or
15             ## modify it under the terms of the GNU General Public License as
16             ## published by the Free Software Foundation; either version 2, or
17             ## (at your option) any later version.
18             ##
19             ## This program is distributed in the hope that it will be useful,
20             ## but WITHOUT ANY WARRANTY; without even the implied warranty of
21             ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22             ## General Public License for more details.
23             ##
24             ## You can view the GNU General Public License, online, at the GNU
25             ## Project's homepage; see .
26             ##
27              
28 1     1   24434 use 5.008;
  1         4  
  1         51  
29 1     1   6 use strict;
  1         2  
  1         36  
30 1     1   5 use warnings;
  1         6  
  1         31  
31 1     1   952 use IO::File;
  1         14711  
  1         158  
32 1     1   962 use File::Copy;
  1         5258  
  1         67  
33 1     1   363 use Kolab;
  0            
  0            
34             use Kolab::Util;
35             use Kolab::LDAP;
36              
37             require Exporter;
38              
39             our @ISA = qw(Exporter);
40              
41             our %EXPORT_TAGS = (
42             'all' => [ qw(
43             &buildPostfixTransportMap
44             &buildCyrusConfig
45             &buildCyrusGroups
46             &rebuildTemplates
47             %haschanged
48             ) ]
49             );
50              
51             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
52              
53             our @EXPORT = qw(
54              
55             );
56              
57             our $VERSION = sprintf('%d.%02d', q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/);
58              
59             sub build {
60             my $tmpl = shift;
61             my $cfg = shift;
62             my $prefix = $Kolab::config{'prefix'};
63              
64             my $TEMPLATE;
65             if (!($TEMPLATE = IO::File->new($tmpl, 'r'))) {
66             Kolab::log('T', "Unable to open template file `$tmpl'", KOLAB_ERROR);
67             exit(1);
68             }
69             my @tempfile = ();
70              
71             while (<$TEMPLATE>) {
72             if (/\@{3}(\S+)\@{3}/) {
73             if ($Kolab::config{$1}) {
74             s/\@{3}(\S+)\@{3}/$Kolab::config{$1}/g;
75             } else {
76             Kolab::log('T', "No configuration variable corresponding to `$1' exists", KOLAB_WARN);
77             s/\@{3}(\S+)\@{3}//g;
78             }
79             }
80             push (@tempfile, $_);
81             }
82             $TEMPLATE->close;
83              
84             my $configchanged = 0;
85             my $CONFIGFILE;
86             if (!($CONFIGFILE = IO::File->new($cfg, 'r'))) {
87             Kolab::log('T', "Unable to open config file `$cfg'", KOLAB_ERROR);
88             $configchanged = 1;
89             } else {
90            
91             my @configfile = <$CONFIGFILE>;
92             $CONFIGFILE->close;
93             undef $CONFIGFILE;
94              
95             if ($#configfile == $#tempfile) {
96             foreach my $line (@tempfile) {
97             my $configline = shift(@configfile);
98             $configchanged = 1 if ($configline ne $line)
99             }
100             } else {
101             $configchanged = 1;
102             }
103             }
104              
105             return 0 if ($configchanged ne 1);
106              
107             if ($configchanged) {
108             Kolab::log('T', "`$cfg' change detected.", KOLAB_DEBUG);
109              
110             if ($cfg =~ /postfix/) {
111             $Kolab::haschanged{'postfix'} = 1;
112             } elsif ($cfg =~ /saslauthd/) {
113             $Kolab::haschanged{'saslauthd'} = 1;
114             } elsif ($cfg =~ /apache/) {
115             $Kolab::haschanged{'apache'} = 1;
116             } elsif ($cfg =~ /proftpd/) {
117             $Kolab::haschanged{'proftpd'} = 1;
118             } elsif ($cfg =~ /openldap/) {
119             $Kolab::haschanged{'slapd'} = 1;
120             } elsif ($cfg =~ /imapd/) {
121             $Kolab::haschanged{'imapd'} = 1;
122             }
123             }
124             Kolab::log('T', "Creating new configuration file `$cfg' from template `$tmpl'");
125              
126             my $tmpfile = $prefix . '/etc/kolab/.tmp';
127             unlink($tmpfile);
128             my $NEWFILE;
129             if ($cfg =~ /openldap/) {
130             if (!($NEWFILE = IO::File->new($tmpfile, O_RDWR|O_CREAT|O_EXCL, 0600))) {
131             Kolab::log('T', "Unable to open configuration file `$tmpfile'", KOLAB_ERROR);
132             exit(1);
133             }
134             } else {
135             if (!($NEWFILE = IO::File->new($tmpfile, O_RDWR|O_CREAT|O_EXCL, 0644))) {
136             Kolab::log('T', "Unable to open configuration file `$tmpfile'", KOLAB_ERROR);
137             exit(1);
138             }
139             }
140              
141             foreach my $line (@tempfile) {
142             print $NEWFILE $line;
143             }
144             $NEWFILE->close;
145             unlink($cfg);
146             link($tmpfile,$cfg);
147             unlink($tmpfile);
148             chown($Kolab::config{'kolab_uid'}, $Kolab::config{'kolab_gid'}, $cfg);
149              
150              
151             Kolab::log('T', "Finished creating configuration file `$cfg'");
152             }
153              
154             sub buildPostfixTransportMap
155             {
156             Kolab::log('T', 'Building Postfix transport map');
157              
158             my $prefix = $Kolab::config{'prefix'};
159             my $cfg = "$prefix/etc/postfix/transport";
160             my $oldcfg = $cfg . '.old';
161             copy($cfg, $oldcfg);
162             chown($Kolab::config{'kolab_uid'}, $Kolab::config{'kolab_gid'}, $oldcfg);
163             copy("$prefix/etc/kolab/transport.template", $cfg);
164              
165             my $transport;
166             if (!($transport = IO::File->new($cfg, 'a'))) {
167             Kolab::log('T', 'Unable to create Postfix transport map', KOLAB_ERROR);
168             exit(1);
169             }
170              
171             my $ldap = Kolab::LDAP::create(
172             $Kolab::config{'ldap_ip'},
173             $Kolab::config{'ldap_port'},
174             $Kolab::config{'bind_dn'},
175             $Kolab::config{'bind_pw'}
176             );
177              
178             my $mesg = $ldap->search(
179             base => $Kolab::config{'base_dn'},
180             scope => 'sub',
181             filter => '(objectclass=*)'
182             );
183             if ($mesg->code) {
184             Kolab::log('T', 'Unable to locate Postfix transport map entries in LDAP', KOLAB_ERROR);
185             exit(1);
186             }
187              
188             my $ldapobject;
189             if ($mesg->code <= 0) {
190             foreach $ldapobject ($mesg->entries) {
191             my $routes = $ldapobject->get_value('postfix-transport', asref => 1);
192             foreach (@$routes) {
193             $_ = trim($_);
194             Kolab::log('T', "Adding SMTP route `$_'");
195             print $transport $_ . "\n";
196             }
197             }
198             } else {
199             Kolab::log('T', 'No Postfix transport map entries found');
200             }
201              
202             Kolab::LDAP::destroy($ldap);
203             $transport->close;
204              
205             # FIXME: bad way of doing things...
206             system("chown root.root $prefix/etc/postfix/*");
207             system("$prefix/sbin/postmap $prefix/etc/postfix/transport");
208              
209             if (-f $oldcfg) {
210             my $rc = `diff -q $cfg $oldcfg`;
211             chomp($rc);
212             if ($rc) {
213             Kolab::log('T', "`$cfg' change detected: $rc", KOLAB_DEBUG);
214             $Kolab::haschanged{'postfix'} = 1;
215             }
216             } else {
217             $Kolab::haschanged{'postfix'} = 1;
218             }
219              
220             Kolab::log('T', 'Finished building Postfix transport map');
221             }
222              
223             sub buildCyrusConfig
224             {
225             Kolab::log('T', 'Building Cyrus config');
226              
227             my $prefix = $Kolab::config{'prefix'};
228             my $cyrustemplate;
229             if (!($cyrustemplate = IO::File->new("$prefix/etc/kolab/cyrus.conf.template", 'r'))) {
230             Kolab::log('T', "Unable to open template file `cyrus.conf.template'", KOLAB_ERROR);
231             exit(1);
232             }
233              
234             my $cfg = "$prefix/etc/imapd/cyrus.conf";
235             my $oldcfg = $cfg . '.old';
236             copy($cfg, $oldcfg);
237             chown($Kolab::config{'kolab_uid'}, $Kolab::config{'kolab_gid'}, $oldcfg);
238              
239             my $cyrusconf;
240             if (!($cyrusconf = IO::File->new($cfg, 'w'))) {
241             Kolab::log('T', "Unable to open configuration file `$cfg'", KOLAB_ERROR);
242             exit(1);
243             }
244              
245             while (<$cyrustemplate>) {
246             if (/\@{3}cyrus-imap\@{3}/ && ($Kolab::config{"cyrus-imap"} =~ /true/i)) {
247             $_ = "imap cmd=\"imapd -C $prefix/etc/imapd/imapd.conf\" listen=\"143\" prefork=0\n";
248             }
249             elsif (/\@{3}cyrus-pop3\@{3}/ && ($Kolab::config{"cyrus-pop3"} =~ /true/i)) {
250             $_ = "pop3 cmd=\"pop3d -C $prefix/etc/imapd/imapd.conf\" listen=\"110\" prefork=0\n";
251             }
252             elsif (/\@{3}cyrus-imaps\@{3}/ && ($Kolab::config{"cyrus-imaps"} =~ /true/i)) {
253             $_ = "imaps cmd=\"imapd -s -C $prefix/etc/imapd/imapd.conf\" listen=\"993\" prefork=0\n";
254             }
255             elsif (/\@{3}cyrus-pop3s\@{3}/ && ($Kolab::config{"cyrus-pop3s"} =~ /true/i)) {
256             $_ = "pop3s cmd=\"pop3d -s -C $prefix/etc/imapd/imapd.conf\" listen=\"995\" prefork=0\n";
257             }
258             elsif (/\@{3}cyrus-sieve\@{3}/ && ($Kolab::config{"cyrus-sieve"} =~ /true/i)) {
259             $_ = "sieve cmd=\"timsieved -C $prefix/etc/imapd/imapd.conf\" listen=\"2000\" prefork=0\n";
260             }
261             $_ =~ s/\@{3}.*\@{3}//;
262             print $cyrusconf $_;
263             }
264              
265             $cyrustemplate->close;
266             $cyrusconf->close;
267              
268             chown($Kolab::config{'kolab_uid'}, $Kolab::config{'kolab_gid'}, $cfg);
269              
270             if (-f $oldcfg) {
271             my $rc = `diff -q $cfg $oldcfg`;
272             chomp($rc);
273             if ($rc) {
274             Kolab::log('T', "`$cfg' change detected: $rc", KOLAB_DEBUG);
275             $Kolab::haschanged{'imapd'} = 1;
276             }
277             } else {
278             $Kolab::haschanged{'imapd'} = 1;
279             }
280              
281             Kolab::log('T', 'Finished building Cyrus config');
282             }
283              
284             sub buildCyrusGroups
285             {
286             Kolab::log('T', 'Building Cyrus groups');
287              
288             my $prefix = $Kolab::config{'prefix'};
289             my $cfg = "$prefix/etc/imapd/imapd.group";
290             my $oldcfg = $cfg . '.old';
291             copy($cfg, $oldcfg);
292             chown($Kolab::config{'kolab_uid'}, $Kolab::config{'kolab_gid'}, $oldcfg);
293             copy("$prefix/etc/kolab/imapd.group.template", $cfg);
294             my $groupconf;
295             if (!($groupconf = IO::File->new($cfg, 'a'))) {
296             Kolab::log('T', "Unable to open configuration file `$cfg'", KOLAB_ERROR);
297             exit(1);
298             }
299              
300             my $ldap = Kolab::LDAP::create(
301             $Kolab::config{'ldap_ip'},
302             $Kolab::config{'ldap_port'},
303             $Kolab::config{'bind_dn'},
304             $Kolab::config{'bind_pw'}
305             );
306              
307             my $mesg = $ldap->search(
308             base => $Kolab::config{'base_dn'},
309             scope => 'sub',
310             filter => '(objectclass=groupofnames)'
311             );
312             if ($mesg->code) {
313             Kolab::log('T', 'Unable to locate Cyrus groups in LDAP', KOLAB_ERROR);
314             exit(1);
315             }
316              
317             my $ldapobject;
318             my $count = 60000;
319             if ($mesg->code <= 0) {
320             foreach $ldapobject ($mesg->entries) {
321             my $group = $ldapobject->get_value('cn') . ":*:$count:";
322             my $userlist = $ldapobject->get_value('uid', asref => 1);
323             foreach (@$userlist) { $group .= "$_,"; }
324             $group =~ s/,$//;
325             print $groupconf $group . "\n";
326             Kolab::log('T', "Adding cyrus group `$group'");
327             $count++;
328             }
329             } else {
330             Kolab::log('T', 'No Cyrus groups found');
331             }
332              
333             $groupconf->close;
334             Kolab::LDAP::destroy($ldap);
335              
336             chown($Kolab::config{'kolab_uid'}, $Kolab::config{'kolab_gid'}, $cfg);
337              
338             if (-f $oldcfg) {
339             my $rc = `diff -q $cfg $oldcfg`;
340             chomp($rc);
341             if ($rc) {
342             Kolab::log('T', "`$cfg' change detected: $rc", KOLAB_DEBUG);
343             $Kolab::haschanged{'imapd'} = 1;
344             }
345             } else {
346             $Kolab::haschanged{'imapd'} = 1;
347             }
348              
349             Kolab::log('T', 'Finished building Cyrus groups');
350             }
351              
352             sub rebuildTemplates
353             {
354             my $key;
355             my $value;
356             my $section="";
357              
358             my $prefix = $Kolab::config{'prefix'};
359              
360             my %templates = (
361             "$prefix/etc/kolab/session_vars.php.template" => "$prefix/var/kolab/www/admin/include/session_vars.php",
362             "$prefix/etc/kolab/main.cf.template" => "$prefix/etc/postfix/main.cf",
363             "$prefix/etc/kolab/master.cf.template" => "$prefix/etc/postfix/master.cf",
364             "$prefix/etc/kolab/saslauthd.conf.template" => "$prefix/etc/sasl/saslauthd.conf",
365             "$prefix/etc/kolab/imapd.conf.template" => "$prefix/etc/imapd/imapd.conf",
366             "$prefix/etc/kolab/httpd.conf.template" => "$prefix/etc/apache/apache.conf",
367             "$prefix/etc/kolab/legacy.conf.template" => "$prefix/etc/apache/legacy.conf",
368             "$prefix/etc/kolab/php.ini.template" => "$prefix/etc/apache/php.ini",
369             "$prefix/etc/kolab/proftpd.conf.template" => "$prefix/etc/proftpd/proftpd.conf",
370             "$prefix/etc/kolab/slapd.conf.template" => "$prefix/etc/openldap/slapd.conf"
371             );
372              
373             Kolab::log('T', 'Regenerating configuration files');
374              
375             foreach $key (keys %templates) {
376             build($key, $templates{$key});
377             }
378              
379             buildPostfixTransportMap;
380             buildCyrusConfig;
381             buildCyrusGroups;
382              
383             Kolab::log('T', 'Finished regenerating configuration files');
384             }
385              
386             1;
387             __END__