1#! @PERL@ 2# 3# Create userdb database 4# 5# Usage: makeuserdb 6# 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} 172