[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#2645: debian doesn't have vipw



You (Lukas Nellen) wrote:
> There seems to be no `vipw' around in debian to edit /etc/passwd with
> locking.

Somebody put this in the base package:

==============================================================================
#! /usr/bin/perl
#
# vipw		VI PAssword file. Locks /etc/passwd and
#		lets you edit it - perl version.
#
# Version:	@(#)vipw.pl  1.10  01-Apr-1996  MvS.
#

$PWLOCK = '/etc/ptmp';
$PWFILE = '/etc/passwd';
$SHADOW = '/etc/shadow';

##
## Lock the password file. Tricky, because we
## have no O_EXCL in perl. So we resort to link().
##
sub pwlock {
  my($tmp, $i);

  # Make temp file.
  $tmp = $PWLOCK . '.' . $$;
  unlink($tmp);
  unless (open(TMP, ">$tmp")) {
	print STDERR "vipw: FAILED to lock $PWFILE: $tmp: $!\n";
	return 0;
  }
  close TMP;

  # Now try to link lockfile to tempfile.
  for($i = 0; $i < 5; $i++) {
	sleep(1) if ($i > 0);
	last if (link($tmp, $PWLOCK));
  }
  if ($i == 5) {
	print STDERR "vipw: FAILED to lock $PWFILE\n";
	return 0;
  }
  unlink($tmp);
  1;
}

##
## Unlock the password file.
##
sub pwunlock {
  unlink($PWLOCK);
  0;
}

#
# Check if we have a shadow password file.
#
if (-f $SHADOW) {
	print STDERR "vipw: you have a shadow password file. This vipw is not compatible with that.\n";
	exit(1);
}

#
# Find out editor.
#
if ($ENV{'VISUAL'}) {
	$edit = $ENV{'VISUAL'};
} elsif ($ENV{'EDITOR'}) {
	$edit = $ENV{'EDITOR'};
} else {
	$edit = 'vi';
}

#
# Try to lock the password file.
#
umask(022);
exit (1) unless (&pwlock());

#
# Copy to a temp file. We could use cp(1), but
# we can't trust its exit status and we want to be sure
# this goes right!.
#
@fmode = stat($PWFILE);
unless (open(OUT, ">$PWLOCK")) {
	print STDERR "vipw: $PWLOCK: $!\n";
	&pwunlock();
	exit(1);
}
unless (open(IN, $PWFILE)) {
	print STDERR "vipw: $PWFILE: $!\n";
	&pwunlock();
	exit(1);
}
$err = 0;
while(<IN>) {
	unless (print OUT) {
		$err = 1;
		last;
	}
}
if ($err) {
	print STDERR "vipw: $PWLOCK: $!\n";
	&pwunlock();
	exit(1);
}
close IN;
close OUT;
# Copy file modes.
chmod($PWLOCK, $fmode[2]);
chown($PWLOCK, $fmode[4], $fmode[5]);

#
# Edit the temp file.
# XXX - "vi" does not return a valid exit status.
#
system("$edit $PWLOCK");

#
# Put new file back into place.
link($PWFILE, "$PWFILE.OLD");
rename($PWLOCK, $PWFILE); # Atomic.

#
# Unlock and exit.
#
&pwunlock();
==============================================================================
--
  Miquel van    | Cistron Internet Services   --    Alphen aan den Rijn.
  Smoorenburg,  | mailto:info@cistron.nl          http://www.cistron.nl/
miquels@het.net | Tel: +31-172-419445 (Voice) 430979 (Fax) 442580 (Data)



Reply to: