openbsd-ports/infrastructure/install/createuser

96 lines
2.4 KiB
Perl

#!/usr/bin/perl
# $OpenBSD: createuser,v 1.2 1999/08/21 20:56:05 niklas Exp $
# user creation script.
# All ports that need to create new users should defer to this script
# If specific capabilities are needed they should be added HERE as well.
require '/usr/ports/infrastructure/db/user.db';
use Fcntl ':flock'; # import LOCK_* constants
sub check_root
{
if ($>)
{ die "Only root can run this script\n"; }
if ($<)
{ die "There is something fishy going on, I'd better quit\n"; }
}
sub fill_user
{
my ($key) = shift;
unless (defined $users{$key})
{die "Sorry, no such user: $key, maybe you need to upgrade your createuser database ?\n"; }
my ($r) = $users{$key};
unless (defined $r->{fullname} && defined $r->{uid})
{ die "Incompletely defined user: $key\n"; }
$r->{user} = $key unless defined $r->{user};
$r->{group} = $r->{user} unless defined $r->{group};
$r->{gid} = $r->{uid} unless defined $r->{gid};
$r->{shell} = '/sbin/nologin' unless defined $r->{shell};
$r->{home} = '/root' unless defined $r->{home};
# avoid characters such as + or : in password entries...
my $k;
local $_;
while (($k, $_) = each %$r)
{ die "Bad chpass field $_\n" unless m/^[\d\w ()\-\/.]+$/; }
return $r;
}
sub atomic_append
{
my ($file,@list) = @_;
open F, ">> $file" or die "$file: $!\n";
unless (flock(F, LOCK_EX | LOCK_NB))
{ die "Cannot lock $file\n"; }
# prevent the rare case where someone is already appending to that file
seek F, 0, 2;
print F join( "\n", @list) . "\n";
close F;
flock F, LOCK_UN ;
}
# the main routine
check_root();
if ($#ARGV < 0)
{ die "Must supply one argument\n"; }
my $r = fill_user($ARGV[0]);
my ($uid, $gid);
# find matching uid/gids.
unless ( $uid = (getpwnam $r->{user})[2])
{
$uid = $r->{uid};
$uid++ while getpwuid $uid;
}
unless ( $gid = (getgrnam $r->{group})[2])
{
$gid = $r->{gid};
$gid++ while getgrgid $gid;
}
# check mandatory ids
if ($r->{mandatory} =~ m/uid/ && $uid != $r->{uid})
{ die "Uid mismatch for $r->{user}\n"; }
if ($r->{mandatory} =~ m/gid/ && $gid != $r->{gid})
{ die "Gid mismatch for $r->{user}\n"; }
atomic_append( '/etc/group', "$r->{group}:*:$gid:" );
print "$r->{user} with uid $uid, of group $r->{group} with gid $gid\n";
$passargs = join(':',
($r->{user}, '*', $uid, $gid, '', '', '', $r->{fullname}, $r->{home}, $r->{shell}));
$local = `ypwhich >/dev/null 2>&1 && echo -n l`;
print "/usr/bin/chpass -${local}a $passargs\n";
system('/usr/bin/chpass', "-${local}a", $passargs);