print <<_WARNING
This script massages your netinfo database. This can severely break
your system. If your netinfo database breaks, you get to keep the parts.
No Warranty. Really.
This script tries to create two groups (if they do not already exist):
- postfix
- maildrop
and tries to create a user (if it does not already exist)
- postfix
which is member of group postfix.
_WARNING
;
my $postfixgid = undef;
my $maildropgid = undef;
my $postfixuid = undef;
my @groups = readgroups();
foreach $group (@groups) {
(my $groupname, undef, my $gid, undef) = split( ':', $group);
if ($groupname eq 'postfix') {
warn "You already have a postfix group (with gid $gid)\n";
$postfixgid = $gid;
}
if ($groupname eq 'maildrop') {
warn "You already have a maildrop group (with gid $gid)\n";
$maildropgid = $gid;
}
}
if (not defined $postfixgid) {
$postfixgid = creategroup( 'postfix');
}
if (not defined $maildropgid) {
$maildropgid = creategroup( 'maildrop');
}
my @users = readusers();
foreach $user (@users) {
(my $username, undef, my $uid, undef) = split( ':', $user);
if ($username eq 'postfix') {
warn "You already have a postfix user (with uid $uid)\n";
$postfixuid = $uid;
}
}
if (not defined $postfixuid) {
$postfixuid = createuser( 'postfix', '"Postfix User"',
'/usr/bin/false', '/etc/postfix',
$postfixgid);
addusertogroup( 'postfix', 'postfix');
}
warn "\n";
sub creategroup
{
my $name = shift;
open( NIDUMP, "nidump group .|") or die "Cannot run nidump\n";
my @groups=<NIDUMP>;
close( NIDUMP);
my $tryno;
NEXTNO: for ($tryno = 88; $tryno <= 65535; $tryno++) {
foreach my $group (@groups) {
(my $groupname, undef, my $gid, undef) =
split( ':', $group);
next NEXTNO if $gid == $tryno;
}
last NEXTNO;
}
die "Cannot find free gid\n" if $tryno == 65536;
warn "Will create $name as gid $tryno\n";
system "niutil -create . /groups/$name";
system "niutil -createprop . /groups/$name name $name";
system "niutil -createprop . /groups/$name gid $tryno";
system "niutil -createprop . /groups/$name passwd '*'";
return $tryno;
}
sub addusertogroup
{
my $user = shift;
my $group = shift;
system "niutil -appendprop . /groups/$group users $user";
}
sub readgroups
{
open( NIDUMP, "nidump group .|") or die "Cannot run nidump\n";
my @groups=<NIDUMP>;
close( NIDUMP);
return @groups;
}
sub readusers
{
my @passwd;
open( NIDUMP, "nidump passwd .|") or die "Cannot run nidump\n";
@passwd=<NIDUMP>;
close( NIDUMP);
return @passwd;
}
sub createuser
{
my $name = shift;
my $realname = shift;
my $shell = shift;
my $home = shift;
my $gid = shift;
open( NIDUMP, "nidump passwd .|") or die "Cannot run nidump\n";
my @passwds=<NIDUMP>;
close( NIDUMP);
my $tryno;
NEXTNO: for ($tryno = 88; $tryno <= 65535; $tryno++) {
foreach my $passwd (@passwds) {
(my $passwdname, undef, my $uid, undef) =
split( ':', $passwd);
next NEXTNO if $uid == $tryno;
}
last NEXTNO;
}
die "Cannot find free uid\n" if $tryno == 65536;
warn "Will create $name as uid $tryno\n";
system "niutil -create . /users/$name";
system "niutil -createprop . /users/$name realname $realname";
system "niutil -createprop . /users/$name shell $shell";
system "niutil -createprop . /users/$name uid $tryno";
system "niutil -createprop . /users/$name gid $gid";
system "niutil -createprop . /users/$name home $home";
system "niutil -createprop . /users/$name _shadow_passwd";
system "niutil -createprop . /users/$name passwd '*'";
return $tryno;
}