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=cef131c78b8b7d3aa0e5d7b5a5cdec943a1bdc8d;hp=949ebec1718e1f5702835ff327bb3152105f23ba;hb=0c4097e39d4a171813346504f888d933ea926dde;hpb=0a4003f95dcf02aed15a6ecbe46d98d4212d310f diff --git a/sync-accounts/sync-accounts b/sync-accounts/sync-accounts index 949ebec..cef131c 100755 --- a/sync-accounts/sync-accounts +++ b/sync-accounts/sync-accounts @@ -7,7 +7,7 @@ # # 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 2, or (at +# published by the Free Software Foundation; either version 3, or (at # your option) any later version. # # sync-accounts is distributed in the hope that it will be useful, @@ -16,10 +16,10 @@ # 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. +# If not, consult the Free Software Foundation's website at +# www.fsf.org, or the GNU Project website at www.gnu.org. # -# $Id: sync-accounts,v 1.21 2002-07-14 19:42:38 ianmdlvl Exp $ +# $Id: sync-accounts,v 1.25 2007-09-21 21:21:15 ianmdlvl Exp $ use POSIX; @@ -199,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): $!"; @@ -219,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 () { @@ -250,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; @@ -258,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;"); } } @@ -306,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; @@ -355,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}++; @@ -375,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; } @@ -390,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"); @@ -448,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; } @@ -456,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; @@ -464,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 { @@ -480,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); @@ -512,6 +524,8 @@ sub banner () { } sub finish () { + my ($record); + for $h (keys %wanthost) { die "host $h not in config file\n" if $wanthost{$h}; } @@ -519,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; @@ -546,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(); @@ -560,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, @@ -595,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$/) { @@ -622,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$/) { @@ -633,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 ];