#
# 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,
# 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;
open O,"$fn_use" or die "$fn_use ($fn_str): $!";
while (<O>) {
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): $!";
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 () {
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;
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;");
}
}
$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;
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 "<DUPLICATE>" if $displaydone{$lu}++;
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; }
$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");
}
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;
}
$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;
}
#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 {
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);
}
sub finish () {
+ my ($record);
+
for $h (keys %wanthost) {
die "host $h not in config file\n" if $wanthost{$h};
}
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;
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();
}
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,
}
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$/) {
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$/) {
$yes= $1 eq 'no' ? 0 : 1;
$_= $2;
@groupglobs=() if $_ eq '*';
- s/[-+._]/\\$1/g;
+ s/[-+._]/\\$&/g;
s/\*/\.\*/g;
s/\?/\./g;
unshift @groupglobs, [ $_, $yes ];