source: trunk/third/sendmail/contrib/buildvirtuser @ 19204

Revision 19204, 5.9 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
  • Property svn:executable set to *
Line 
1#!/usr/bin/perl -w
2
3# Copyright (c) 1999-2003 Gregory Neil Shapiro.  All Rights Reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14# 3. Neither the name of the author nor the names of its contributors
15#    may be used to endorse or promote products derived from this software
16#    without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28# SUCH DAMAGE.
29
30# $Id: buildvirtuser,v 1.1.1.1 2003-04-08 15:09:08 zacheiss Exp $
31
32=head1 NAME
33
34buildvirtuser - Build virtusertable support from a directory of files
35
36=head1 SYNOPSIS
37
38    buildvirtuser [-f] [-t]
39
40=head1 DESCRIPTION
41
42buildvirtuser will build /etc/mail/virtusertable.db and /etc/mail/virthosts
43based on the contents of the directory /etc/mail/virtusers/.  That
44directory should contain one file per virtual domain with the filename
45matching the virtual domain name and the contents containing a list of
46usernames on the left and the actual address for that username on the
47right.  An empty left column translates to the default for that domain.
48Blank lines and lines beginning with '#' are ignored.  Occurrences of
49$DOMAIN in the file are replaced by the current domain being processed.
50Occurrences of $LHS in the right hand side are replaced by the address on
51the left hand side.
52
53The -f option forces the database to be rebuilt regardless of whether
54any file changes were detected.
55
56The -t option instructs the program to build a text file instead of a
57database.  The text file can then be used with makemap.
58
59=head1 CONFIGURATION
60
61In order to function properly, sendmail must be configured to use these
62files with:
63
64        FEATURE(`virtusertable')dnl
65        VIRTUSER_DOMAIN_FILE(`/etc/mail/virthosts')dnl
66
67If a new domain is added (i.e., by adding a new file to
68/etc/mail/virtusers/), the sendmail daemon must be restarted for the change
69to take affect.
70
71=head1 EXAMPLES
72
73Here are some example files from the /etc/mail/virtusers/ directory:
74
75=head2 /etc/mail/virtusers/bsdunix.org:
76
77 # Services
78 MAILER-DAEMON  gshapiro+bounce.$DOMAIN@gshapiro.net
79 postmaster     gshapiro+$LHS.$DOMAIN@gshapiro.net
80 webmaster      gshapiro+$LHS.$DOMAIN@gshapiro.net
81 
82 # Defaults
83                error:nouser No such user
84 
85 # Users
86 gshapiro       gshapiro+$DOMAIN@gshapiro.net
87 bob            robert@smtp.org
88
89=head2 /etc/mail/virtusers/smtp.org:
90
91 # Defaults
92                gshapiro+$DOMAIN@gshapiro.net
93 
94 # Users
95 john           john@wookie.org
96 nancy          n@milter.com
97
98=head1 AUTHOR
99
100Gregory Neil Shapiro E<lt>F<gshapiro@gshapiro.net>E<gt>
101
102=cut
103
104use strict;
105use Getopt::Std;
106
107my $makemap = "/usr/sbin/makemap";
108my $dbtype = "hash";
109my $maildir = "/etc/mail";
110my $virthosts = "$maildir/virthosts";
111my $newvirthosts = "$maildir/virthosts.new";
112my $virts = "$maildir/virtusers";
113my $newvirt = "$maildir/virtusertable.new.db";
114my $virt = "$maildir/virtusertable.db";
115my %virt = ();
116my $newest = 0;
117my ($lhs, $domain, $key, $value);
118my $opts = {};
119
120getopts('ft', $opts) || die "Usage: $0 [-f] [-t]\n";
121
122if ($opts->{t})
123{
124        $newvirt = "$maildir/virtusertable.new";
125        $virt = "$maildir/virtusertable";
126}
127
128opendir(VIRTS, $virts) || die "Could not open directory $virts: $!\n";
129my @virts = grep { -f "$virts/$_" } readdir(VIRTS);
130closedir(VIRTS) || die "Could not close directory $virts: $!\n";
131
132foreach $domain (@virts)
133{
134        open(DOMAIN, "$virts/$domain") || die "Could not open file $virts/$domain: $!\n";
135        my $line = 0;
136        my $mtime = (stat(DOMAIN))[9] || 0;
137        if ($mtime > $newest)
138        {
139                $newest = $mtime;
140        }
141LINE:   while (<DOMAIN>)
142        {
143                chomp;
144                $line++;
145                next LINE if /^#/;
146                next LINE if /^$/;
147                if (m/^([^\t ]*)[\t ]+(.*)$/)
148                {
149                        if (defined($1))
150                        {
151                                $lhs = "$1";
152                                $key = "$1\@$domain";
153                        }
154                        else
155                        {
156                                $lhs = "";
157                                $key = "\@$domain";
158                        }
159                        $value = $2;
160                }
161                else
162                {
163                        die "Bogus line $line in $virts/$domain\n";
164                }
165
166                # Variable subsitution
167                $key =~ s/\$DOMAIN/$domain/g;
168                $value =~ s/\$DOMAIN/$domain/g;
169                $value =~ s/\$LHS/$lhs/g;
170                $virt{$key} = $value;
171        }
172        close(DOMAIN) || die "Could not close $virts/$domain: $!\n";
173}
174
175my $virtmtime = (stat($virt))[9] || 0;
176if ($opts->{f} || $virtmtime < $newest)
177{
178        print STDOUT "Rebuilding $virt\n";
179# logger -s -t ${prog} -p mail.info "Rebuilding ${basedir}/virtusertable"
180        if ($opts->{t})
181        {
182                open(MAKEMAP, ">$newvirt") || die "Could not open $newvirt: $!\n";
183        }
184        else
185        {
186                open(MAKEMAP, "|$makemap $dbtype $newvirt") || die "Could not start makemap: $!\n";
187        }
188
189        foreach $key (keys %virt)
190        {
191                print MAKEMAP "$key\t\t$virt{$key}\n";
192        }
193        close(MAKEMAP) || die "Could not close makemap ($?): $!\n";
194        rename($newvirt, $virt) || die "Could not rename $newvirt to $virt: $!\n";
195
196        open(VIRTHOST, ">$newvirthosts") || die "Could not open file $newvirthosts: $!\n";
197        foreach $domain (sort @virts)
198        {
199                print VIRTHOST "$domain\n";
200        }
201        close(VIRTHOST) || die "Could not close $newvirthosts: $!\n";
202        rename($newvirthosts, $virthosts) || die "Could not rename $newvirthosts to $virthosts: $!\n";
203}
204exit 0;
Note: See TracBrowser for help on using the repository browser.