/ag-update-openbsd
#!/usr/bin/perl
use strict;

use AwesomeGrid;
use AwesomeGrid::Config;
use AwesomeGrid::User;

my $etc = '/etc';	# In production, this should be '/etc'

my $config = AwesomeGrid::Config::config();

# Get a list of awesomegrid users
opendir USERS, "$AwesomeGrid::confdir/users";
my @agusers = grep {/^[^.]/} readdir USERS;
close USERS;

# Get a list of system users
my @sysusers;
my @allsysusers;

open PASSWD, "$etc/master.passwd";
while (<PASSWD>) {
	my ($username, undef, $uid, $gid, $class, $change, $expire, $gecos, $home, $shell) = split(/:/);
	push(@allsysusers, $username);
	next unless $gecos =~ /^\[AG\]/;	# Skip non-AG-managed users
	push(@sysusers, $username);
}
close PASSWD;

# Check to see what there is in /etc/master.passwd that should be removed.
my @deletes;
for my $sysuser (@sysusers) {
	unless (grep { $_ eq $sysuser } @agusers) {
		push(@deletes, $sysuser);
	}
}

# Check to see which users are going to be added
my @adds;
for my $aguser (@agusers) {
	unless (grep { $_ eq $aguser } @allsysusers) {
		push(@adds, $aguser);
	}
}

# Check to see which users should be updated
my @updates;
for my $user (@allsysusers) {
	if (grep { $_ eq $user } @agusers) {
		push(@updates, $user);
	}
}

unless (@adds or @deletes or @updates) {
	print "Nothing to do.\n";
	exit 0;
}

print "Adding: ",join(' ',@adds),"\n" if @adds;
print "Deleting: ",join(' ',@deletes),"\n" if @deletes;
print "Updating: ",join(' ',@updates),"\n" if @updates;

print "Proceed? [y/N] ";
my $ans = <STDIN>;
unless ($ans =~ /^[Yy]$/) {
	exit(0);
}

# Before proceeding, make a backup copy of /etc/master.passwd
system("cp $etc/master.passwd $etc/master.passwd.ag_backup");

# Deletes first
if (@deletes or @updates) {
	open PASSWD, "$etc/master.passwd";
	open PASSWDOUT, ">$etc/master.passwd.out";
	while (<PASSWD>) {
		my ($username) = split(/:/);
		next if grep { $username eq $_ } (@deletes,@updates);
		print PASSWDOUT;
	}
	close PASSWDOUT;
	close PASSWD;
}

# Then add new ones.
if (@adds or @updates) {
	open PASSWD, ">>$etc/master.passwd.out";

	for my $add (@updates,@adds) {
		my $agu = AwesomeGrid::User->load($add);
		unless (exists $agu->{'passwd-bcrypt'}) {
			print "$agu->{username} does not have a bcrypt password! Not adding user!\n";
			next;
		}

		printf PASSWD "%s:%s:%d:%d::0:0:[AG]:%s:%s\n",
			$agu->{username}, $agu->{'passwd-bcrypt'},
			$agu->{uid}, $agu->{uid},
			"$config->{homedir}/$agu->{username}",
			$config->{'default-shell'};

		unless (-d "$config->{homedir}/$agu->{username}") {
			print "Creating homedir for $agu->{username}\n";
			mkdir "$config->{homedir}/$agu->{username}";
			chown $agu->{uid}, $agu->{uid},
				"$config->{homedir}/$agu->{username}";
		}
	}
	close PASSWD;
}

# Update the passwd databases
system('/usr/sbin/pwd_mkdb /etc/master.passwd.out')