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

/*
 * Copyright (c) 2016-2017 Franco Fichtner <franco@opnsense.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

require_once('config.inc');
require_once('auth.inc');
require_once('util.inc');

use OPNsense\Core\Config;
use OPNsense\Auth\User;

function sync_installer_user()
{
    Config::getInstance()->lock();

    $usermdl = new User();
    $ret = false;

    $installer = $usermdl->getUserByName('installer');
    $root = $usermdl->getUserByName('root');

    if (!empty($installer)) {
        /* simply test if it is usable */
        $ret = $installer->uid->isEqual('0') && $installer->scope->isEqual('system') && $installer->disabled->isEmpty();
    } else if (!empty($root) && $root->uid->isEqual('0') && $root->scope->isEqual('system') && $root->disabled->isEmpty()) {
        $installer = $usermdl->user->Add();
        $installer->setNodes($root->getNodeContent());
        $installer->descr = 'System Installer';
        $installer->name = 'installer';
        $installer->uid = '0'; /* needs a reset */

        if ($usermdl->serializeToConfig(false, true)) {
            Config::getInstance()->save();

            /* only sync the user, because local_sync_accounts() cannot cope with overlapping UIDs */
            $user = $installer->getNodeContent();
            local_user_set($user);

            $ret = true;
        }
    }

    Config::getInstance()->unlock();

    return $ret;
}

/*
 * Installer mode requires setting up an extra user and
 * we will protect it with root's password.  We can only
 * do this if root exists and installer does not, though.
 *
 * If an 'installer' account is found with the correct
 * UID and scope we will try to use it, too.
 */
if (is_install_media() && sync_installer_user()) {
    echo "\n";

    /* tailored for OPNsense to occupy same width below */
    $namex = product::getInstance()->name();

    $greeting = "Welcome!  {$namex} is running in live mode from install media.  Please\n" .
                "login as 'root' to continue in live mode, or as 'installer' to start the\n" .
                "installation.  Use the default or previously-imported root password for\n" .
                "both accounts.";

    if (!isset($config['system']['ssh']['noauto']) && is_process_running('sshd')) {
        $greeting .= "  Remote login via SSH is also enabled.";
    }

    echo $greeting . "\n";
} else {
    $users = &config_read_array('system', 'user');
    foreach ($users as $id => $user) {
        if ($user['name'] == 'installer' && $user['scope'] == 'system') {
            unset($users[$id]);
            write_config('Remove installer user');
        }
    }
    shell_safe('/usr/sbin/pw userdel installer 2> /dev/null');
}
