#! /usr/bin/perl5 eval 'exec perl5 -S $0 "$@"' if 0; push(@INC, "/usr/share/lib/perl5/sgi_lib"); use MDBM_File; use Fcntl; use Socket; $YPPUSH=$ENV{'YPPUSH'}?$ENV{'YPPUSH'}:"/usr/sbin/yppush"; # # This routine sets up default values for variables using historic environment # variables after parsing the command line. # sub set_defaults { $ns_dir = $ENV{"NSDIR"} ? $ENV{"NSDIR"} : "/var/ns/domains" unless $ns_dir; $source_dir = $ENV{"DIR"} ? $ENV{"DIR"} : "/etc" unless $source_dir; $force = $ENV{"UPDATE"} ? 1 : 0 unless $force; $aliases_file = $ENV{"ALIASES"} ? $ENV{"ALIASES"} : "aliases" unless $aliases_file; $bootparams_file = "bootparams" unless $bootparams_file; $ethers_file = "ethers" unless $ethers_file; $group_file = "group" unless $group_file; $hosts_file = "hosts" unless $hosts_file; $netgroup_file = "netgroup" unless $netgroup_file; $networks_file = "networks" unless $networks_file; $passwd_file = $ENV{"PWFILE"} ? $ENV{"PWFILE"} : "passwd" unless $passwd_file; $protocols_file = "protocols" unless $protocols_file; $rpc_file = "rpc" unless $rpc_file; $services_file = "services" unless $services_file; $capability_file = "capability" unless $capability_file; $clearance_file = "clearance" unless $clearance_file; $mac_file = "mac" unless $mac_file; $shadow_file = "shadow" unless $shadow_file; $ypservers_file = "ypservers" unless $ypservers_file; $no_netgroup_expand = 0 unless $no_netgroup_expand; if (! $domain) { if ($ENV{"DOM"}) { $domain = $ENV{"DOM"}; } else { chomp($domain = `domainname`); } } chomp($hostname = `hostname`); $nopush = $ENV{"NOPUSH"} unless $nopush; $dest_dir = "$ns_dir/$domain" unless $dest_dir; } $SIG{CHLD} = sub { wait }; # # This just adds the magic keys required for NIS to work. # sub yp_keys { local $db = $_[0]; local $source = $_[1]; local $dest = $_[2]; $time = time(); $$db{"YP_MASTER_NAME"} = $hostname; $$db{"YP_LAST_MODIFIED"} = "$time"; $$db{"YP_INPUT_FILE"} = $source; $$db{"YP_OUTPUT_NAME"} = $dest; $$db{"YP_DOMAIN_NAME"} = $domain; } # # This execs yppush on a map. # sub yp_push { local $db = $_[0]; do { $pid = fork; unless (defined $pid) { print STDERR "cannot fork: $!"; if ($count++ > 6) { print STDERR "giving up\n"; return 0; } } } until defined $pid; if ($pid) { return 1; } else { if (! exec($YPPUSH, "-d", $domain, $db)) { print STDERR "failed exec $YPPUSH -d $domain $db\n"; exit(1); } } } # # The aliases file is used to build two maps: aliases.byname and # aliases.bymember. Note that historically alias keys have included the # trailing null, so we do that here as well. # sub ns_aliases { if (-r "$ns_dir/$domain/$aliases_file") { $source = "$ns_dir/$domain/$aliases_file"; } elsif ( -r "$source_dir/$aliases_file") { $source = "$source_dir/$aliases_file"; } elsif ( -r $aliases_file) { $source = $aliases_file; } else { print STDERR "Unable to read source file: $?\n"; return; } $byname = "$dest_dir/mail.aliases.m"; $bymember = "$dest_dir/mail.byaddr.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $bymember) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $bymember\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%bymember, MDBM_File, "$bymember.$$", O_RDWR|O_CREAT, 0600) || (warn("Unable to open destination database files.\n") && return); open(IN, "<$source") || (warn("Unable to open source file.\n") && return); while () { next if /^\s*[+#\n]/; chomp; s/^\s+//; if (! /\s*:\s*/) { print STDERR "WARNING: no ':' in line: $_\n"; next; } $value = $'; $key = $`; $key =~ tr/A-Z/a-z/; while((! $value || /\s*,\s*$/) && ($_ = )) { chomp; if (! $_ || /^\s*#/) { print STDERR "WARNING: trailing ',' in $key: $value\n"; last; } elsif (! /^\s/) { print STDERR "WARNING: no whitespace at beginning of continuation line in $key: $_\n"; last; } s/^\s+//; $value .= $_; } @value = split(/\s*,\s*/, $value); # # Note: we take the last key instead of the first since this # is what sendmail does. # print STDERR "WARNING: duplicate key: $key\n" if ($byname{"$key\0"}); $byname{"$key\0"} = join(',', @value); foreach $member (@value) { next if ($member =~ /\|/); next if ($member =~ /:include:/); next unless ($member =~ /\@/ || $member =~ /\!/); next if ($member =~ /^\@/ || $member =~ /^YP_/); # note that this doesn't check for # duplicates. This is because a duplicate # is normall, but the old version only # used one key, and it was the last one # encountered. $bymember{"$member\0"} = "$key"; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%bymember, $source, $bymember); untie(%bymember); rename("$byname.$$", $byname); rename("$bymember.$$", $bymember); if (! $nopush) { yp_push("mail.aliases"); yp_push("mail.byaddr"); } } # # The bootparams file is used to build the bootparams.byname database. # sub ns_bootparams { if (-r "$ns_dir/$domain/$bootparams_file") { $source = "$ns_dir/$domain/$bootparams_file"; } elsif (-r "$source_dir/$bootparams_file") { $source = "$source_dir/$bootparams_file"; } elsif (-r $bootparams_file) { $source = $bootparams_file; } else { print STDERR "Unable to read source file: $?\n"; return; } $byname = "$dest_dir/bootparams.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _))) { return; } print "Parsing $bootparams_file\n\tinto $byname\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) || (warn("Unable to open destination database files.\n") && return); open(IN, "<$source") || (warn("Unable to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; $value = $_; while(($value =~ s/\s*\\$//) && ) { chomp; s/^\s+/ /; $value .= $_; } @value = split(/\s+/, $value); $key = shift(@value); $key =~ tr/A-Z/a-z/; if ($byname{$key}) { print STDERR "WARNING: duplicate key: $key\n"; } else { $byname{$key} = join(' ', @value); } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); rename("$byname.$$", $byname); if (! $nopush) { yp_push("bootparams"); } } # # The ethers file is used to build two maps: ethers.byname and ethers.byaddr. # sub ns_ethers { if (-r "$ns_dir/$domain/$ethers_file") { $source = "$ns_dir/$domain/$ethers_file"; } elsif (-r "$source_dir/$ethers_file") { $source = "$source_dir/$ethers_file"; } elsif (-r $ethers_file) { $source = $ethers_file; } else { print STDERR "Could not read source file: $ethers_file\n"; return; } $byname = "$dest_dir/ethers.byname.m"; $byaddr = "$dest_dir/ethers.byaddr.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byaddr) && ($mtime > (-M _))) { return; } print "Parsing $ethers_file\n\tinto $byname\n\tand $byaddr\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byaddr, MDBM_File, "$byaddr.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/#.*//; ($addr, $name) = split(/\s+/); $line = "$addr\t$name"; $addr = sprintf("%x:%x:%x:%x:%x:%x", map { hex($_) } split(':', $addr)); $name =~ tr/A-Z/a-z/; if ($byaddr{$addr}) { print STDERR "WARNING: duplicate address: $addr\n"; } else { $byaddr{$addr} = $line; } if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byaddr, $source, $byaddr); untie(%byaddr); rename("$byname.$$", $byname); rename("$byaddr.$$", $byaddr); if (! $nopush) { yp_push("ethers.byname"); yp_push("ethers.byaddr"); } } # # The group file is used to build three maps: group.byname, group.bygid, # and group.bymember. # sub ns_group { if (-r "$ns_dir/$domain/$group_file") { $source = "$ns_dir/$domain/$group_file"; } elsif (-r "$source_dir/$group_file") { $source = "$source_dir/$group_file"; } elsif (-r $group_file) { $source = $group_file; } else { print STDERR "Could not open source file: $group_file\n"; return; } $byname = "$dest_dir/group.byname.m"; $bygid = "$dest_dir/group.bygid.m"; $bymember = "$dest_dir/group.bymember.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $bygid) && ($mtime > (-M _)) && (-w $bymember) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname,\n\t$bygid\n\tand $bymember\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%bygid, MDBM_File, "$bygid.$$", O_RDWR|O_CREAT, 0600) && tie(%bymember, MDBM_File, "$bymember.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; next if /^\s*\+/; chomp; s/^\s+//; $line = $_; ($name, $gid, $members) = (split(/:/))[0,2,3]; next unless ($name); if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } next unless ($gid ne ""); if ($bygid{$gid}) { print STDERR "WARNING: duplicate gid: $gid\n"; } else { $bygid{$gid} = $line; } next unless ($members); foreach $member (split(/\s*,\s*/, $members)) { if ($bymember{$member}) { $bymember{$member} .= ",$gid"; } else { $bymember{$member} = "$member:$gid"; } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%bygid, $source, $bygid); untie(%bygid); yp_keys(\%bymember, $source, $bymember); untie(%bymember); rename("$byname.$$", $byname); rename("$bygid.$$", $bygid); rename("$bymember.$$", $bymember); if (! $nopush) { yp_push("group.byname"); yp_push("group.bygid"); yp_push("group.bymember"); } } # # The hosts file is used to build two maps: hosts.byname and hosts.byaddr. # sub ns_hosts { if (-r "$ns_dir/$domain/$hosts_file") { $source = "$ns_dir/$domain/$hosts_file"; } elsif (-r "$source_dir/$hosts_file") { $source = "$source_dir/$hosts_file"; } elsif (-r $hosts_file) { $source = $hosts_file; } else { print STDERR "Could not read source file: $hosts_file\n"; return; } $byname = "$dest_dir/hosts.byname.m"; $byaddr = "$dest_dir/hosts.byaddr.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byaddr) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $byaddr\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byaddr, MDBM_File, "$byaddr.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/#.*//; @line = split(/\s+/); $line = join("\t", @line); $a = Socket::inet_aton(shift(@line)); next unless($a); $address = join('.',unpack(C4, $a)); if ($byaddr{$address}) { print STDERR "WARNING: duplicate address: $address\n"; } else { $byaddr{$address} = $line; } foreach $name (@line) { $name =~ tr/A-Z/a-z/; if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byaddr, $source, $byaddr); untie(%byaddr); rename("$byname.$$", $byname); rename("$byaddr.$$", $byaddr); if (! $nopush) { yp_push("hosts.byname"); yp_push("hosts.byaddr"); } } # # This routine will be called recursively to unroll a netgroup. # All netgroups are stored in the %all array. # sub expand_netgroup { my $name = $_[0]; local @line; local $line = $all{$name} or return ""; while ($line) { while ($line =~ /^(\([^\)]+\))\s*/) { push(@line, $&); $line = $'; } next unless $line; if ($line =~ /\s+/) { $group = $`; $line = $'; } else { $group = $line; $line = ""; } if ($groups_visited{$group}) { print STDERR "WARNING duplicate group: $group\n"; next; } $groups_visited{$group} = 1; $add = expand_netgroup($group); $line = $add . $line; }; return join(' ', @line); } # # The netgroup file is used to build three maps: netgroup, netgroup.byuser, # and netgroup.byhost. # sub ns_netgroup { local %all, %groups_visited; local $MAX_NETGROUP = 1024; local %users, %hosts; local $lower; if (-r "$ns_dir/$domain/$netgroup_file") { $source = "$ns_dir/$domain/$netgroup_file"; } elsif (-r "$source_dir/$netgroup_file") { $source = "$source_dir/$netgroup_file"; } elsif (-r $netgroup_file) { $source = $netgroup_file; } else { print STDERR "Could not read source file: $netgroup_file\n"; return; } $byname = "$dest_dir/netgroup.m"; $byhost = "$dest_dir/netgroup.byhost.m"; $byuser = "$dest_dir/netgroup.byuser.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byhost) && ($mtime > (-M _)) && (-w $byuser) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname,\n\t$byhost\n\tand $byuser\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byhost, MDBM_File, "$byhost.$$", O_RDWR|O_CREAT, 0600) && tie(%byuser, MDBM_File, "$byuser.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { $ln = $_; next if $ln =~ /^\s*[#\n]/; $ln =~ s/^\s+//; $ln =~ s/\s*#.*//; while ($ln =~ /\\\n$/ && ($new = )) { $new =~ s/^\s+/ /; $new =~ s/\s*#.*//; substr($ln, -2, 2) = $new; } chomp $ln; $ln =~ s/^\s+//; $ln =~ s/\s*#.*//; $ln =~ /\s+/; $key = $`; $line = $'; next unless ($key && $line); $all{$key} = $line; } foreach $key (keys %all) { undef %groups_visited; $groups_visited{$key} = 1; next unless ($line = expand_netgroup($key)); @line = split(/\s*\(\s*/, $line); if ($byname{$key}) { print STDERR "WARNING: duplicate name: $key\n"; } else { if ($no_netgroup_expand || length($line) > $MAX_NETGROUP) { $byname{$key} = $all{$key}; } else { $byname{$key} = $line; } } foreach $name (@line) { next unless $name; $name =~ s/[\)\s]+$//; ($host, $user, $dom) = split(/\s*,\s*/, $name); $lower = $dom; $lower =~ tr/A-Z/a-z/; $host = '*' unless($host); $fullhost = ($dom) ? "$host.$dom" : "$host.*"; $fullhost =~ tr/A-Z/a-z/; if ($fullhost =~ /^[a-z0-9_*]/) { if ($byhost{$fullhost}) { if (! $hosts{$fullhost,$key}) { $byhost{$fullhost} .= ",$key"; $hosts{$fullhost,$key} = 1; } } else { $byhost{$fullhost} = "$key"; $hosts{$fullhost,$key} = 1; } if ($lower ne $dom) { $fullhost = "$host.$dom"; if ($byhost{$fullhost}) { if (! $hosts{$fullhost,$key}) { $byhost{$fullhost} .= ",$key"; $hosts{$fullhost,$key}= 1; } } else { $byhost{$fullhost} = "$key"; $hosts{$fullhost,$key} = 1; } } } $user = '*' unless($user); $fulluser = ($dom) ? "$user.$dom" : "$user.*"; if ($fulluser =~ /^[A-Za-z0-9_*]/) { if ($byuser{$fulluser}) { if (! $users{$fulluser,$key}) { $byuser{$fulluser} .= ",$key"; $users{$fulluser,$key} = 1; } } else { $byuser{$fulluser} = "$key"; $users{$fulluser,$key} = 1; } if ($lower ne $dom) { $fulluser = "$user.$lower"; if ($byuser{$fulluser}) { if (! $users{$fulluser,$key}) { $byuser{$fulluser} .= ",$key"; $users{$fulluser,$key}= 1; } } else { $byuser{$fulluser} = "$key"; $users{$fulluser,$key} = 1; } } } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byhost, $source, $byhost); untie(%byhost); yp_keys(\%byuser, $source, $byuser); untie(%byuser); rename("$byname.$$", $byname); rename("$byhost.$$", $byhost); rename("$byuser.$$", $byuser); if (! $nopush) { yp_push("netgroup"); yp_push("netgroup.byhost"); yp_push("netgroup.byuser"); } } # # The netid.byname map is built using the passwd and hosts files. # sub ns_netid { my %groups = (); if (-r "$ns_dir/$domain/$hosts_file") { $hosts = "$ns_dir/$domain/$hosts_file" } elsif (-r "$source_dir/$hosts_file") { $hosts = "$source_dir/$hosts_file"; } elsif (-r $hosts_file) { $hosts = $hosts_file; } else { print STDERR "Could not read hosts file: $hosts_file\n"; return; } if (-r "$ns_dir/$domain/$passwd_file") { $passwd = "$ns_dir/$domain/$passwd_file" } elsif (-r "$source_dir/$passwd_file") { $passwd = "$source_dir/$passwd_file"; } elsif (-r $passwd_file) { $passwd = $passwd_file; } else { print STDERR "Could not read passwd file: $passwd_file\n"; return; } if (-r "$ns_dir/$domain/$group_file") { $group = "$ns_dir/$domain/$group_file" } elsif (-r "$source_dir/$group_file") { $group = "$source_dir/$group_file"; } elsif (-r $group_file) { $group = $group_file; } else { print STDERR "Could not read group file: $group_file\n"; return; } $byname = "$dest_dir/netid.byname.m"; $mtime = -M $byname; if ((! $force) && (-w $byname) && ($mtime < (-M $hosts)) && ($mtime < (-M $passwd)) && ($mtime < (-M $group))) { return; } print "Parsing $hosts,\n\t$passwd\n\tand $group\n\tinto $byname\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database file.\n") && return); open(HOSTS, "<$hosts") && open(PASSWD, "<$passwd") && open(GROUP, "<$group") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; ($gid, $members) = (split(/:/))[2,3]; chomp($members); next unless ($members); @members = split(/\s*,\s*/, $members); foreach $member (@members) { if ($groups{$member}) { $groups{$member} .= ",$gid"; } else { $groups{$member} = $gid; } } } while () { next if /^\s*[#\n]/; next if (/^\s*[+-]/); ($login, $uid, $gid) = (split(/:/))[0,2,3]; next unless ($login && $gid && $uid); $fullname = "unix.$uid\@$domain"; if ($byname{$fullname}) { print STDERR "WARNING: duplicate user: $fullname\n"; } else { if ($groups{$login}) { $groups{$login} = "$gid," . $groups{$login}; } else { $groups{$login} = $gid; } $byname{$fullname} = $uid . ":" . $groups{$login}; } } while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/#.*//; $name = (split(/\s+/))[1]; $fullname = "unix.$name\@$domain"; if ($byname{$fullname}) { print STDERR "WARNING: duplicate host: $fullname\n"; } else { $byname{$fullname} = "0:$name"; } } close(HOSTS); close(PASSWD); close(GROUP); yp_keys(\%byname, $source, $byname); untie(%byname); rename("$byname.$$", $byname); if (! $nopush) { yp_push("netid.byname"); } } # # The networks file is used to build two maps: networks.byname and # networks.byaddr. # sub ns_networks { if (-r "$ns_dir/$domain/$networks_file") { $source = "$ns_dir/$domain/$networks_file"; } elsif (-r "$source_dir/$networks_file") { $source = "$source_dir/$networks_file"; } elsif (-r $networks_file) { $source = $networks_file; } else { print STDERR "Could not read source file: $networks_file\n"; return; } $byname = "$dest_dir/networks.byname.m"; $byaddr = "$dest_dir/networks.byaddr.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byaddr) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $byaddr\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byaddr, MDBM_File, "$byaddr.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/\s*#.*//; @line = split(/\s+/); $line = join("\t", @line); $network = splice(@line, 1, 1); next unless ($network); if ($byaddr{$network}) { print STDERR "WARNING: duplicate network: $network\n"; } else { $byaddr{$network} = $line; } foreach $name (@line) { if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byaddr, $source, $byaddr); untie(%byaddr); rename("$byname.$$", $byname); rename("$byaddr.$$", $byaddr); if (! $nopush) { yp_push("networks.byname"); yp_push("networks.byaddr"); } } # # The passwd file is used to build two maps: passwd.byname and passwd.byuid. # sub ns_passwd { if (-r "$ns_dir/$domain/$passwd_file") { $source = "$ns_dir/$domain/$passwd_file"; } elsif (-r "$source_dir/$passwd_file") { $source = "$source_dir/$passwd_file"; } elsif (-r $passwd_file) { $source = $passwd_file; } else { print STDERR "Could not read source file: $passwd_file\n"; return; } $byname = "$dest_dir/passwd.byname.m"; $byuid = "$dest_dir/passwd.byuid.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byuid) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $byuid\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byuid, MDBM_File, "$byuid.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; $line = $_; ($name, $uid) = (split(/:/))[0,2]; # skip root or passthru records if (($uid == 0) || ($name =~ /^\s*[+-]/)) { print STDERR "SKIPPING: $line\n"; next; } if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } if ($byuid{$uid}) { print STDERR "WARNING: duplicate uid: $uid\n"; } else { $byuid{$uid} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byuid, $source, $byuid); untie(%byuid); rename("$byname.$$", $byname); rename("$byuid.$$", $byuid); if (! $nopush) { yp_push("passwd.byname"); yp_push("passwd.byuid"); } } # # The protocols file is used to build two maps: protocols.byname and # protocols.bynumber. # sub ns_protocols { if (-r "$ns_dir/$domain/$protocols_file") { $source = "$ns_dir/$domain/$protocols_file"; } elsif (-r "$source_dir/$protocols_file") { $source = "$source_dir/$protocols_file"; } elsif (-r $protocols_file) { $source = $protocols_file; } else { print STDERR "Could not read source file: $protocols_file\n"; return; } $byname = "$dest_dir/protocols.byname.m"; $bynumber = "$dest_dir/protocols.bynumber.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $bynumber) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $bynumber\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%bynumber, MDBM_File, "$bynumber.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/\s*#.*//; @line = split(/\s+/); $line = join("\t", @line); $number = splice(@line, 1, 1); if ($bynumber{$number}) { print STDERR "WARNING: duplicate number: $number\n"; } else { $bynumber{$number} = $line; } foreach $name (@line) { if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%bynumber, $source, $bynumber); untie(%bynumber); rename("$byname.$$", $byname); rename("$bynumber.$$", $bynumber); if (! $nopush) { yp_push("protocols.byname"); yp_push("protocols.bynumber"); } } # # The rpc file is used to build two maps, rpc.byname and rpc.bynumber. # sub ns_rpc { if (-r "$ns_dir/$domain/$rpc_file") { $source = "$ns_dir/$domain/$rpc_file"; } elsif (-r "$source_dir/$rpc_file") { $source = "$source_dir/$rpc_file"; } elsif (-r $rpc_file) { $source = $rpc_file; } else { print STDERR "Could not read source file: $rpc_file\n"; return; } $byname = "$dest_dir/rpc.byname.m"; $bynumber = "$dest_dir/rpc.bynumber.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $bynumber) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $bynumber\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%bynumber, MDBM_File, "$bynumber.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/\s*#.*//; @line = split(/\s+/); $line = join("\t", @line); $number = splice(@line, 1, 1); if ($bynumber{$number}) { print STDERR "WARNING: duplicate number: $number\n"; } else { $bynumber{$number} = $line; } foreach $name (@line) { if ($byname{$name}) { print STDERR "WARNING: duplicate name: $name\n"; } else { $byname{$name} = $line; } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%bynumber, $source, $bynumber); untie(%bynumber); rename("$byname.$$", $byname); rename("$bynumber.$$", $bynumber); if (! $nopush) { yp_push("rpc.byname"); yp_push("rpc.bynumber"); } } # # The services file is used to build two maps: services.byname and # services.byport. These are really by-name-and-protocol and # by-port-and-protocol. # sub ns_services { if (-r "$ns_dir/$domain/$services_file") { $source = "$ns_dir/$domain/$services_file"; } elsif (-r "$source_dir/$services_file") { $source = "$source_dir/$services_file"; } elsif (-r $services_file) { $source = $services_file; } else { print STDERR "Could not read source file: $services_file\n"; return; } $byname = "$dest_dir/services.m"; $byport = "$dest_dir/services.byname.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byport) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $byport\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byport, MDBM_File, "$byport.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; s/\s*#.*//; @line = split(/\s+/); $line = join("\t", @line); $portnproto = splice(@line, 1, 1); next unless ($portnproto =~ m#/#); $proto = $'; if ($byport{$portnproto}) { print STDERR "WARNING: duplicate port: $portnproto\n"; } else { $byport{$portnproto} = $line; } foreach $name (@line) { $namenproto = "$name/$proto"; $byname{$name} = $line unless $byname{$name}; if ($byname{"$namenproto"}) { print STDERR "WARNING: duplicate name: $namenproto\n"; } else { $byname{"$namenproto"} = $line; } } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byport, $source, $byport); untie(%byport); rename("$byname.$$", $byname); rename("$byport.$$", $byport); if (! $nopush) { yp_push("services.byname"); yp_push("services"); } } # # The capability file is used to build one map, capability.byname # sub ns_capability { if (-r "$ns_dir/$domain/$capability_file") { $source = "$ns_dir/$domain/$capability_file"; } elsif (-r "$source_dir/$capability_file") { $source = "$source_dir/$capability_file"; } elsif (-r $capability_file) { $source = $capability_file; } else { print STDERR "Could not read source file: $capability_file\n"; return; } $byname = "$dest_dir/capability.byname.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { chomp; s/^\s+//; @line = split(/:/); $line = $_; if ($byname{$line[0]}) { print STDERR "WARNING: duplicate name: $line[0]\n"; } else { $byname{$line[0]} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); rename("$byname.$$", $byname); if (! $nopush) { yp_push("capability.byname"); } } # # The clearance file is used to build one map, clearance.byname # sub ns_clearance { if (-r "$ns_dir/$domain/$clearance_file") { $source = "$ns_dir/$domain/$clearance_file"; } elsif (-r "$source_dir/$clearance_file") { $source = "$source_dir/$clearance_file"; } elsif (-r $clearance_file) { $source = $clearance_file; } else { print STDERR "Could not read source file: $clearance_file\n"; return; } $byname = "$dest_dir/clearance.byname.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { chomp; s/^\s+//; @line = split(/:/); $line = $_; if ($byname{$line[0]}) { print STDERR "WARNING: duplicate name: $line[0]\n"; } else { $byname{$line[0]} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); rename("$byname.$$", $byname); if (! $nopush) { yp_push("clearance.byname"); } } # # The mac file is used to build two maps, mac.byname and mac.byvalue. # sub ns_mac { if (-r "$ns_dir/$domain/$mac_file") { $source = "$ns_dir/$domain/$mac_file"; } elsif (-r "$source_dir/$mac_file") { $source = "$source_dir/$mac_file"; } elsif (-r $mac_file) { $source = $mac_file; } else { print STDERR "Could not read source file: $mac_file\n"; return; } $byname = "$dest_dir/mac.byname.m"; $byvalue = "$dest_dir/mac.byvalue.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _)) && (-w $byvalue) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n\tand $byvalue\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) && tie(%byvalue, MDBM_File, "$byvalue.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; @line = split(/:/); $line = $_; $name = join(':', @line[0,1]); $value = join(':', @line[1,2]); if ($byname{$name}) { print STDERR "WARNING: duplicate key: $name\n"; } else { $byname{$name} = $line; } if ($byvalue{$value}) { print STDERR "WARNING: duplicate key: $value\n"; } else { $byvalue{$value} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); yp_keys(\%byvalue, $source, $byvalue); untie(%byvalue); rename("$byname.$$", $byname); rename("$byvalue.$$", $byvalue); if (! $nopush) { yp_push("mac.byname"); yp_push("mac.byvalue"); } } # # The shadow file is used to build one map, shadow.byname # sub ns_shadow { if (-r "$ns_dir/$domain/$shadow_file") { $source = "$ns_dir/$domain/$shadow_file"; } elsif (-r "$source_dir/$shadow_file") { $source = "$source_dir/$shadow_file"; } elsif (-r $shadow_file) { $source = $shadow_file; } else { print STDERR "Could not read source file: $shadow_file\n"; return; } $byname = "$dest_dir/shadow.byname.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { chomp; s/^\s+//; @line = split(/:/); $line = $_; if ($byname{$line[0]}) { print STDERR "WARNING: duplicate name: $line[0]\n"; } else { $byname{$line[0]} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); rename("$byname.$$", $byname); if (! $nopush) { yp_push("shadow.byname"); } } # # The ypservers file is used to build the map ypservers. # sub ns_ypservers { if (-r "$ns_dir/$domain/$ypservers_file") { $source = "$ns_dir/$domain/$ypservers_file"; } elsif (-r "$source_dir/$ypservers_file") { $source = "$source_dir/$ypservers_file"; } elsif (-r $ypservers_file) { $source = $ypservers_file; } else { print STDERR "Could not read source file: $ypservers_file\n"; return; } $byname = "$dest_dir/ypservers.m"; $mtime = -M $source; if ((! $force) && (-w $byname) && ($mtime > (-M _))) { return; } print "Parsing $source\n\tinto $byname\n"; tie(%byname, MDBM_File, "$byname.$$", O_RDWR|O_CREAT, 0600) || (warn("Failed to open destination database files.\n") && return); open(IN, "<$source") || (warn("Failed to open source file.\n") && return); while () { next if /^\s*[#\n]/; chomp; s/^\s+//; /\s*(\S*)/ || next; $name = $1; $line = $'; if ($byname{$name}) { print STDERR "WARNING: duplicate key: $name\n"; } else { $byname{$name} = $line; } } close(IN); yp_keys(\%byname, $source, $byname); untie(%byname); rename("$byname.$$", $byname); if (! $nopush) { yp_push("ypservers"); } } while ($arg = shift(@ARGV)) { if ($arg eq "-s") { $ns_dir = $source_dir = shift(@ARGV); } elsif ($arg eq "-d") { $dest_dir = shift(@ARGV); } elsif ($arg eq "-m") { $domain = shift(@ARGV); } elsif ($arg eq "-u") { $force = 1; } elsif ($arg eq "-o") { $no_netgroup_expand = 1; } elsif ($arg eq "-n") { $nopush = 1; } elsif ($arg =~ /\s*=\s*/) { $ENV{$`} = $'; } else { push(@maps, $arg); } } set_defaults(); if (! -d $dest_dir) { mkdir($dest_dir, 0700) || die "Could not create destination directory: $dest_dir\n"; } if ($#maps < 0) { ns_aliases(); ns_bootparams(); ns_ethers(); ns_group(); ns_hosts(); ns_netgroup(); ns_networks(); ns_netid(); ns_passwd(); ns_protocols(); ns_rpc(); ns_services(); ns_capability(); ns_clearance(); ns_mac(); ns_ypservers(); exit(0); } for (@maps) { if (/^aliases|mail/i) { ns_aliases(); } elsif (/^bootparam/i) { ns_bootparams(); } elsif (/^ether/i) { ns_ethers(); } elsif (/^group/i) { ns_group(); } elsif (/^host/i) { ns_hosts(); } elsif (/^netgroup/i) { ns_netgroup(); } elsif (/^network/i) { ns_networks(); } elsif (/^netid/i) { ns_netid(); } elsif (/^passw/i) { ns_passwd(); } elsif (/^protocol/i) { ns_protocols(); } elsif (/^rpc/i) { ns_rpc(); } elsif (/^service/i) { ns_services(); } elsif (/^capability/i) { ns_capability(); } elsif (/^clearance/i) { ns_clearance(); } elsif (/^mac/i) { ns_mac(); } elsif (/^shadow/i) { ns_shadow(); } elsif (/^ypservers/i || /^servers/i) { ns_ypservers(); } else { print STDERR "Do not know how to parse map: $_\n"; } }