Imported Upstream version 0.66.1
[hcoop/debian/courier-authlib.git] / userdb / makeuserdb.in
CommitLineData
d9898ee8 1#! @PERL@
2#
3# Create userdb database
4#
5# Usage: makeuserdb
6#
d9898ee8 7#
8# Copyright 1998 - 2006 Double Precision, Inc. See COPYING for
9# distribution information.
10
11use Fcntl ':flock';
12
13$prefix="@prefix@";
14$exec_prefix="@exec_prefix@";
15$bindir="@bindir@";
16
17$ENV{'PATH'}="@bindir@:/usr/bin:/usr/local/bin:/bin";
18
19$dbfile="@userdb@";
20
21$makedat="@makedat@";
22
23$name=shift @ARGV;
24if ($name eq "-f") {
25 $dbfile=shift @ARGV;
26 $dbfile=~s/\/$//;
27}
28
29$datfile=$dbfile.".dat";
30# XXX the lock file here is etc/userdb.lock but the userdb command uses etc/.lock.userdb
31$lockfile=$dbfile.".lock";
32$shadowfile=$dbfile."shadow.dat";
33$tmpdatfile=$dbfile.".tmp";
34$tmpshadowfile=$dbfile."shadow.tmp";
35
36$mode=(stat($dbfile))[2];
37die "$dbfile: not found.\n" unless defined $mode;
38
39die "$dbfile: MAY NOT HAVE GROUP OR WORLD PERMISSIONS!!\n"
40 if ( $mode & 077);
41
42eval {
43 die "SYMLINK\n" if -l $dbfile;
44};
45
46die "ERROR: Wrong makeuserdb command.\n ($dbfile is a symbolic link)\n"
47 if $@ eq "SYMLINK\n";
48
49eval {
50 die "SYMLINK\n" if -l $datfile;
51};
52
53die "ERROR: Wrong makeuserdb command.\n ($datfile is a symbolic link)\n"
54 if $@ eq "SYMLINK\n";
55
56eval {
57 die "SYMLINK\n" if -l $shadowfile;
58};
59
60die "ERROR: Wrong makeuserdb command.\n ($shadowfile is a symbolic link)\n"
61 if $@ eq "SYMLINK\n";
62
63umask (022);
64open(LOCK, ">$lockfile") or die "Can't open $lockfile: $!";
65flock(LOCK,LOCK_EX) || die "Can't lock $lockfile: $!";
66
67open (DBPIPE, "| ${makedat} - $tmpdatfile $datfile") || die "$!\n";
68umask (066);
69open (SHADOWPIPE, "| ${makedat} - $tmpshadowfile $shadowfile")
70 || die "$!\n";
71
72eval {
73
74 if ( -d $dbfile )
75 {
76 my (@dirs);
77 my (@files);
78
79 push @dirs, $dbfile;
80 while ( $#dirs >= 0 )
81 {
82 $dir=shift @dirs;
83 opendir(DIR, $dir) || die "$!\n";
84 while ( defined($filename=readdir(DIR)))
85 {
86 next if $filename =~ /^\./;
87 if ( -d "$dir/$filename" )
88 {
89 push @dirs, "$dir/$filename";
90 }
91 else
92 {
93 push @files, "$dir/$filename";
94 }
95 }
96 closedir(DIR);
97 }
98
99 while (defined ($filename=shift @files))
100 {
101 &do_file( $filename );
102 }
103 }
104 else
105 {
106 &do_file( $dbfile );
107 }
108
109 print DBPIPE ".\n" || die "$!\n";
110 print SHADOWPIPE ".\n" || die "$!\n";
111} ;
112
113$err=$@;
114if ($err)
115{
116 print "$err";
117 exit (1);
118}
119
120close(DBPIPE) || die "$!\n";
121exit (1) if $?;
122close(SHADOWPIPE) || die "$!\n";
123exit (1) if $?;
124
125exit (0);
126
127sub do_file {
128my ($filename)=@_;
129my ($addr, $fields);
130my (@nonshadow, @shadow);
131
132my $location=substr($filename, length("@userdb@"));
133
134 $location =~ s/^\///;
135 $location =~ s/\/$//;
136 $location .= "/" if $location ne "";
137
138 open (F, $filename) || die "$filename: $!\n";
139 while (<F>)
140 {
141 if ( /^[\n#]/ || ! /^([^\t]*)\t(.*)/ )
142 {
143 print DBPIPE;
144 print SHADOWPIPE;
145 next;
146 }
147 ($addr,$fields)=($1,$2);
148 undef @nonshadow;
149 undef @shadow;
150
151 foreach ( split (/\|/, $fields ) )
152 {
153 if ( /^[^=]*pw=/ )
154 {
155 push @shadow, $_;
156 }
157 else
158 {
159 push @nonshadow, $_;
160 }
161 }
162
163 push @nonshadow, "_=$location";
164 ( print DBPIPE "$addr\t" . join("|", @nonshadow) . "\n"
165 || die "$!\n" ) if $#nonshadow >= 0;
166 ( print SHADOWPIPE "$addr\t" . join("|", @shadow) . "\n"
167 || die "$!\n" ) if $#shadow >= 0;
168 }
169 print DBPIPE "\n";
170 print SHADOWPIPE "\n";
171}