1999-05-18 12:39:02 -04:00
|
|
|
#!/usr/bin/perl
|
1999-08-21 16:56:05 -04:00
|
|
|
# $OpenBSD: createuser,v 1.2 1999/08/21 20:56:05 niklas Exp $
|
1999-05-18 12:39:02 -04:00
|
|
|
|
|
|
|
# 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)
|
1999-08-21 16:56:05 -04:00
|
|
|
{ die "Bad chpass field $_\n" unless m/^[\d\w ()\-\/.]+$/; }
|
1999-05-18 12:39:02 -04:00
|
|
|
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}));
|
1999-08-21 16:56:05 -04:00
|
|
|
$local = `ypwhich >/dev/null 2>&1 && echo -n l`;
|
|
|
|
print "/usr/bin/chpass -${local}a $passargs\n";
|
|
|
|
system('/usr/bin/chpass', "-${local}a", $passargs);
|