X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=sync-accounts%2Fsync-accounts;h=5e26a988e4371e60e075bda8b52b3f94dbd68823;hp=3efa06e334dc15ba439c305d3de5dd1f82dd4682;hb=d9d8b1a736946ae91c521133dc32d5e1d6b5e506;hpb=f791716cd4ca5f25a2b1977c3a635722a8a5c316 diff --git a/sync-accounts/sync-accounts b/sync-accounts/sync-accounts index 3efa06e..5e26a98 100755 --- a/sync-accounts/sync-accounts +++ b/sync-accounts/sync-accounts @@ -1,22 +1,25 @@ #!/usr/bin/perl -# $Id: sync-accounts,v 1.20 2002-07-14 19:29:37 ianmdlvl Exp $ +# This is part of sync-accounts, a tool for synchronising UN*X password data. # -# Copyright 1999-2000,2002 Ian Jackson -# Copyright 2000-2001 nCipher Corporation Ltd +# sync-accounts is +# Copyright 1999-2000,2002 Ian Jackson +# Copyright 2000-2001 nCipher Corporation Ltd # -# This is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 2, or (at your option) any later -# version. +# sync-accounts is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. # -# This is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. +# sync-accounts is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # # You should already have a copy of the GNU General Public License. # If not, write to the Free Software Foundation, Inc., 59 Temple # Place - Suite 330, Boston, MA 02111-1307, USA. +# +# $Id: sync-accounts,v 1.24 2007-09-21 20:59:02 ianmdlvl Exp $ use POSIX; @@ -196,9 +199,13 @@ sub fetchownfile (\@$$$$) { open O,"$fn_use" or die "$fn_use ($fn_str): $!"; while () { chomp; - $record= [ split(/\:/,$_,-1) ]; - die "$fn_emsg:$.:wrong number of fields:\`$_'\n" - unless @$record == $nfields; + if (m/^\#/ || !m/\S/) { + $record= $_; + } else { + $record= [ split(/\:/,$_,-1) ]; + die "$fn_emsg:$.:wrong number of fields:\`$_'\n" + unless @$record == $nfields; + } push @$ary_ref, $record; } close O or die "$fn_use ($fn_str): $!"; @@ -216,7 +223,7 @@ sub regroupglobs () { for $g (@groupglobs) { $ggfunc.= " m/^$g->[0]\$/ ? $g->[1] :\n"; } $ggfunc.= " die;\n};\n1;\n"; #print STDERR "$ggfunc\n"; - eval $ggfunc or die "$ggfunc // $@"; + must_eval($ggfunc); } sub fetchown () { @@ -247,6 +254,7 @@ sub fetchown () { sub checkuid ($$) { my ($useuid,$foruser) = @_; for $e (@ownpasswd) { + next unless ref $e; if ($e->[$PW_USER] ne $foruser && $e->[$PW_UID] == $useuid) { diag("uid clash with $e->[$PW_USER] (uid $e->[$PW_UID])"); return 0; @@ -255,16 +263,20 @@ sub checkuid ($$) { return 1; } +sub must_eval ($) { + eval $_[0] or die "$_[0] // $@"; +} + sub copyfield ($$$$) { my ($file,$entry,$field,$value) = @_; - eval "\$ary_ref= \\\@own$file; 1;" or die $@; + must_eval("\$ary_ref= \\\@own$file; 1;"); #print STDERR "copyfield($file,$entry,$field,$value)\n"; for $e (@$ary_ref) { #print STDERR "copyfield($file,$entry,$field,$value) $e->[0] $e->[field] ".join(':',@$e)."\n"; next unless $e->[0] eq $entry; next if $e->[$field] eq $value; $e->[$field]= $value; - eval "\$modified$file= 1; 1;" or die $@; + must_eval("\$modified$file= 1; 1;"); } } @@ -303,6 +315,7 @@ sub syncusergroup ($$) { $ugfound=0; for $e (@owngroup) { + next unless ref $e; $samename= $e->[$GR_GROUP] eq $lu; $sameid= $e->[$GR_GID] eq $luid; next unless $samename || $sameid; @@ -352,7 +365,7 @@ sub syncuser ($$) { if ($display) { for $e (@ownpasswd) { - next unless $e->[$PW_USER] eq $lu; + next unless ref $e && $e->[$PW_USER] eq $lu; hosthead("from $ch_name"); print ($lu eq $ru ? " $lu" : " $lu($ru)") or die $!; print "" if $displaydone{$lu}++; @@ -372,7 +385,7 @@ sub syncuser ($$) { return; } - if (!grep($_->[$PW_USER] eq $lu, @ownpasswd)) { + if (!grep(ref $_ && $_->[$PW_USER] eq $lu, @ownpasswd)) { if (!length $opt_createuser) { diag("account creation not enabled"); return; } if ($no_act) { diag("-n specified; not creating account"); return; } @@ -387,6 +400,7 @@ sub syncuser ($$) { $useuid= $ch_uidmin; for $e ($defaultgid==-1 ? (@ownpasswd, @owngroup) : (@ownpasswd)) { + next unless ref $e; $tuid= $e->[$PW_UID]; next if $tuid<$useuid || $tuid>$ch_uidmax; if ($tuid==$ch_uidmax) { diag("uid (or gid?) $ch_uidmax used, cannot create users"); @@ -445,7 +459,7 @@ sub syncuser ($$) { } for $e (@ownpasswd) { - next unless $e->[$PW_USER] eq $lu; + next unless ref $e && $e->[$PW_USER] eq $lu; syncusergroup($lu,$e->[$PW_UID]) or return; } @@ -453,7 +467,7 @@ sub syncuser ($$) { $rgid= $rempasswd{$ru}->[$REM_GID]; if ($opt_sameuid && checkuid($ruid,$lu)) { for $e (@ownpasswd) { - next unless $e->[$PW_USER] eq $lu; + next unless ref $e && $e->[$PW_USER] eq $lu; $luid= $e->[$PW_UID]; $lgid= $e->[$PW_GID]; die "$diagstr: local uid $luid, remote uid $ruid\n" if $luid ne $ruid; die "$diagstr: local gid $lgid, remote gid $rgid\n" if $lgid ne $rgid; @@ -461,7 +475,7 @@ sub syncuser ($$) { } #print STDERR "syncuser($lu,$ru) exists $own_haveshadow\n"; - if ($own_haveshadow && grep($_->[$PW_USER] eq $lu, @ownshadow)) { + if ($own_haveshadow && grep(ref $_ && $_->[$PW_USER] eq $lu, @ownshadow)) { #print STDERR "syncuser($lu,$ru) shadow $rempasswd{$ru}->[$REM_PW]\n"; copyfield('shadow',$lu,$SP_PW, $rempasswd{$ru}->[$REM_PW]); } else { @@ -477,6 +491,7 @@ sub syncuser ($$) { if (!$nogroups) { for $e (@owngroup) { + next unless ref $e; $tgroup= $e->[$GR_GROUP]; #print STDERR "syncuser($lu,$ru) group $tgroup\n"; next unless &wantsyncgroup($tgroup); @@ -509,6 +524,8 @@ sub banner () { } sub finish () { + my ($record); + for $h (keys %wanthost) { die "host $h not in config file\n" if $wanthost{$h}; } @@ -516,13 +533,14 @@ sub finish () { if ($display) { #print STDERR "\n\nfinish display=$display pw=$pw\n\n"; for $e (@ownpasswd) { + next unless ref $e; $tu= $e->[$PW_USER]; $tuid= $e->[$PW_UID]; next if $displaydone{$tu}; $tpw= $e->[$PW_PW]; #print STDERR ">$tu|$tpw<\n"; for $e2 (@ownshadow) { - next unless $e2->[$SP_USER] eq $tu; + next unless ref $e2 && $e2->[$SP_USER] eq $tu; $tpw= $e2->[$SP_PW]; last; } $tpw= length($tpw)>=13 ? 1 : length($tpw) ? -1 : 0; @@ -543,8 +561,8 @@ sub finish () { umask 077; for $file (qw(passwd shadow group)) { $realfile= $file{$file,$PW_format}; - eval "\$modified= \$modified$file; \$data_ref= \\\@own$file;". - " \$fetched= \$own_fetched$file; 1;" or die $@; + must_eval("\$modified= \$modified$file; \$data_ref= \\\@own$file;". + " \$fetched= \$own_fetched$file; 1;"); next if !$modified; die $file unless $fetched; banner(); @@ -557,7 +575,8 @@ sub finish () { } open NF,"> $newfile" or die "$newfile: $!"; for $e (@$data_ref) { - print NF join(':',@$e),"\n" or die $!; + $record= ref $e ? join(':',@$e) : $e; + print NF $record,"\n" or die $!; } close NF or die $!; system 'diff','-U0','--label',$realfile,$newfileinst, @@ -592,19 +611,19 @@ while () { } fields_fmt('REM','std'); } elsif (m/^(getpasswd|getshadow|getgroup)\s+(.*\S)$/) { - eval "\$ch_$1= \$2; 1;" or die $@; + must_eval("\$ch_$1= \$2; 1;"); } elsif (m/^(local|remote)format\s+(\w+)$/) { fields_fmt($1 eq 'local' ? 'PW' : $1 eq 'remote' ? 'REM' : die, $2); } elsif (m/^lock(passwd|group)\s+(runvia|link)\s+(\S+)$/) { - eval "\$ch_lock_$1= \$3; \$ch_lockstyle_$1= \$2; 1;" or die $@; + must_eval("\$ch_lock_$1= \$3; \$ch_lockstyle_$1= \$2; 1;"); } elsif (m/^lock(passwd|group)\s+(none)$/) { - eval "\$ch_lockstyle_$1= \$2; 1;" or die $@; + must_eval("\$ch_lockstyle_$1= \$2; 1;"); } elsif (m,^(homebase|defaultshell)\s+(/\S+)$,) { - eval "\$ch_$1= \$2; 1;" or die $@; + must_eval("\$ch_$1= \$2; 1;"); } elsif (m/^(uidmin|uidmax)\s+(\d+)$/ && $2>0) { - eval "\$ch_$1= \$2; 1;" or die $@; + must_eval("\$ch_$1= \$2; 1;"); } elsif (m/^createuser$/) { $opt_createuser= $def_createuser; } elsif (m/^nocreateuser$/) { @@ -619,7 +638,7 @@ while () { print "would log to $1\n" or die $!; } } elsif (m/^(no|)(sameuid)$/) { - eval "\$opt_$2= ".($1 eq 'no' ? 0 : 1)."; 1;" or die $@; + must_eval("\$opt_$2= ".($1 eq 'no' ? 0 : 1)."; 1;"); } elsif (m/^usergroups$/) { $defaultgid= -1; } elsif (m/^nousergroups$/) { @@ -630,7 +649,7 @@ while () { $yes= $1 eq 'no' ? 0 : 1; $_= $2; @groupglobs=() if $_ eq '*'; - s/[-+._]/\\$1/g; + s/[-+._]/\\$&/g; s/\*/\.\*/g; s/\?/\./g; unshift @groupglobs, [ $_, $yes ];