#!/usr/local/bin/php -f
<?php

/*
 * pf_useradm [action] [arg0=...] [arg1=....] ...
 * action: create | delete | modify
 *   args: name, password, descr, expires, disabled, groups (comma separated), privs (comma separated)
 *
 * Note : a lot of this code is borrowed from pfsense /usr/local/www/system_usermanager.php
 *
 */

$actions = array("create", "update", "delete");
$keys = array("name", "password", "descr", "expires", "disabled", "groups", "privs");

array_shift($argv);

$action = $argv[0];
if (!in_array($action, $actions)) {
	echo "BAD SYNTAX: incorrect action '" . $action . "'\n";
	exit(2);
}

array_shift($argv);

$userargs=array();

foreach ($argv as $arg) {
	list($name, $value) = explode('=', $arg, 2);
	if (in_array($name, $keys)) {
		$userargs[$name] = $value;
	} else {
		echo "BAD SYNTAX: incorrect arg '" . $name . "'\n";
		exit(2);
	}
}


// check and normalize 

if (!$userargs['name']) {
	echo "ERROR: missing name\n";
	exit(2);
}

if (preg_match("/[^a-zA-Z0-9\.\-_]/", $userargs['name'])) {
	echo "ERROR: invalid characters in name\n";
	exit(2);
}
if (strlen($userargs['name']) > 16) {
	echo "ERROR: too long name (16 chars max)\n";
	exit(2);
}

if ($userargs['expires']) {
	$expires = strtotime($userargs['expires']);
	if ($expires > 0) {
		$userargs['expires'] = date("m/d/Y",$expires);
	} else {
		echo "CANNOT CREATE: bad expiration '" . $userargs['expires'] . "'date (use mm/dd/yyyy)\n";
		exit(3);
	}
} else
	unset($userargs['expires']);

if (preg_match("/^[Yy]/i", $userargs['disabled']))
	$userargs['disabled']= true;
else
	unset($userargs['disabled']);

if ($userargs['privs'])
	$userargs['priv'] = explode(',', $userargs['privs']);
elseif (isset($userargs['privs'])) // handle privs=""
	$userargs['priv'] = array();
unset($userargs['privs']);

if ($userargs['groups'])
	$groups = explode(',', $userargs['groups']);
elseif (isset($userargs['groups'])) // handle groups="" 
	$groups = array();
else
	unset($groups);
unset($userargs['groups']);


// now we need some functions and globals variables ($config)

require("auth.inc");


// check that groups exist

if (isset($groups)) {
	$conf_groups = array();
	foreach ($config['system']['group'] as $gidx => $group) {
		$conf_groups[] = $group['name'];
	}
	foreach ($groups as $group)
		if (!in_array($group, $conf_groups)) {
			echo "ERROR: group '" . $group . "' does not exist\n";
			exit(2);
		}
}


// search the user...

$user = getUserEntry($userargs["name"]);


// handle the action

if ($action == "create") {
	if ($user) {
		echo "CANNOT CREATE: user '" . $userargs['name'] . "' already exists\n";
		exit(3);
	}
	// encrypt password
	if ($userargs['password'])
		local_user_set_password($userargs, $userargs['password']);
	else {
		echo "CANNOT CREATE: missing password\n";
		exit(3);
	}

	// add last bits in the user
	$userargs['scope'] = 'user';
	$userargs['authorizedkeys'] = '';
	$userargs['ipsecpsk'] = '';

	$system_users = explode("\n", file_get_contents("/etc/passwd"));
	foreach ($system_users as $s_user) {
		$ent = explode(":", $s_user);
		if ($ent[0] == $userargs['name']) {
			echo "ERROR: name '" . $userargs['name'] . "' is reserved by the system\n";
			exit(2);
		}
	}

	conf_mount_rw();

	$new_user = $userargs;
	$new_user['uid'] = $config['system']['nextuid']++;

	// Add the user to "All Users" group (borrowed from pfsense, don't known if its usefull)
        foreach ($config['system']['group'] as $gidx => $group) {
		if ($group['name'] == "all") {
			if (!is_array($config['system']['group'][$gidx]['member']))
				$config['system']['group'][$gidx]['member'] = array();
			$config['system']['group'][$gidx]['member'][] = $new_user['uid'];
			break;
		}
	}

	$all_users = &$config['system']['user'];
	$all_users[] = $new_user;

	if (isset($groups))
		local_user_set_groups($new_user, $groups);
	local_user_set($new_user);

	write_config();
	conf_mount_ro();
	echo "USER CREATED: " . $userargs['name'] . " \n";

	exit(0);
}

// delete ou update : search the user...
if (!$user) {
	echo "CANNOT " . strtoupper($action) . ": user '" . $userargs['name'] . "' is unknown\n";
	exit(3);
}

unset($id);
$all_users = &$config['system']['user'];
foreach ($all_users as $iter_id=>$iter_user) {
	if ($iter_user['name'] == $user['name']) {
		$id = $iter_id;
	}
}
if (!isset($id)) {
	echo "CANNOT " . strtoupper($action) . ": cannot find user '" . $userargs['name'] . "' (please report this error)\n";
	exit(3);
}

if ($action == "update") {

	// encrypt password
	if ($userargs['password'])
		local_user_set_password($userargs, $userargs['password']);
	else 
		unset($userargs['password']);

	conf_mount_rw();

	$updated_user = $all_users[$id];
	// echo "BEFORE\n"; print_r($updated_user);
	foreach ($userargs as $key=>$value)
		$updated_user[$key] = $value;

	if (!$userargs['disabled'])
		unset($updated_user['disabled']);
	// echo "AFTER\n"; print_r($updated_user);
	
	$all_users[$id] = $updated_user;
	if (isset($groups))
		local_user_set_groups($updated_user, $groups);
        local_user_set($updated_user);
	write_config();
        conf_mount_ro();

	echo "UPDATED USER: " . $userargs['name'] . "\n";
	exit(0);
}

if ($action == "delete") {
	local_user_del($all_users[$id]);
        unset($all_users[$id]);
        write_config();
	echo "DELETED USER: " . $userargs['name'] . "\n";
	exit(0);
}

exit(1);

?>
