chiark / gitweb /
close branch
[chiark-utils.git] / sync-accounts / sync-accounts
index 3efa06e334dc15ba439c305d3de5dd1f82dd4682..44daddbff72df601b9703259abe6e23804cefa71 100755 (executable)
@@ -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 <ian@davenant.greenend.org.uk>
-# Copyright 2000-2001 nCipher Corporation Ltd
+# sync-accounts is
+#  Copyright 1999-2000,2002 Ian Jackson <ian@davenant.greenend.org.uk>
+#  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 2, 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.22 2002-07-14 22:21:29 ianmdlvl Exp $
 
 use POSIX;
 
@@ -196,9 +199,13 @@ sub fetchownfile (\@$$$$) {
     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): $!";
@@ -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;
@@ -303,6 +311,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 +361,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 "<DUPLICATE>" if $displaydone{$lu}++;
@@ -372,7 +381,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 +396,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 +455,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 +463,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 +471,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 +487,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 +520,8 @@ sub banner () {
 }
 
 sub finish () {
+    my ($record);
+
     for $h (keys %wanthost) {
        die "host $h not in config file\n" if $wanthost{$h};
     }
@@ -516,13 +529,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;
@@ -557,7 +571,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,