<?php
/**
 *  Server/Server.php
 *
 *  @author     {$author}
 *  @package    Secioss
 *  @version    $Id: skel.action.php 387 2006-11-06 14:31:24Z cocoitiban $
 */

define('NWNAME', '社内ネットワーク');

/**
 *  server_serverフォームの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Secioss
 */
class Secioss_Form_ServerServer extends Secioss_ActionForm
{
    /** @var    bool    バリデータにプラグインを使うフラグ */
    var $use_validator_plugin = true;

    /**
     *  @access private
     *  @var    array   フォーム値定義
     */
    var $form = array(
        'password' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_PASSWORD,
            'name'          => '管理者パスワード',
            'required'      => false,
            'min'           => 1,
            'max'           => 10
        ),
        'storage' => array(
            'type'          => array(VAR_TYPE_STRING),
            'form_type'     => FORM_TYPE_CHECKBOX,
            'name'          => 'ユーザ情報の管理',
            'option'        => array('LDAP' => 'LDAPを使用'),
            'required'      => false
        ),
        'networks' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '社内ネットワークアドレス',
            'required'      => false,
            'regexp'        => '/^[0-9.,\/ ]*$/'
        ),
        'smtp' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '送信メールサーバ名(SMTP)',
            'required'      => false
        ),
        'port' => array(
            'type'          => VAR_TYPE_INT,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '送信ポート番号(SMTP)',
            'required'      => false,
            'regexp'        => '/^[0-9]*$/'
        ),
        'postmaster' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_TEXT,
            'name'          => '管理者メールアドレス',
            'required'      => false,
            'regexp'        => '/.+@.+/'
        ),
        'operation' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
            'required'       => false
        ),
        'search' => array(
            'type'          => VAR_TYPE_STRING,
            'form_type'     => FORM_TYPE_HIDDEN,
        )
    );
}

/**
 *  serverアクションの実装
 *
 *  @author     {$author}
 *  @access     public
 *  @package    Secioss
 */
class Secioss_Action_ServerServer extends Secioss_ActionClass
{
    /**
     *  serverアクションの前処理
     *
     *  @access public
     *  @return string      遷移名(正常終了ならnull, 処理終了ならfalse)
     */
    function prepare()
    {
        if ($this->af->get('search') == "true") {
            return 'server_menu';
        }

        if ($this->af->get('operation') == 'update' && $this->af->validate() > 0) {
            $this->ae->add(null, $this->getInvalidValMsg($this->getErrorFormName()));

            return 'server_server';
        }

        return null;
    }

    /**
     *  serverアクションの実装
     *
     *  @access public
     *  @return string  遷移名
     */
    function perform()
    {
        $auth =& $this->backend->getManager('Auth');
        $confmgr =& $this->backend->getManager('Config');
        $logger = & $this->backend->getLogger();
        $conf = $this->config->get('secioss');
        $ldapconf = $this->config->get('ldap');

        $id = $this->session->get('user');
        $password = $this->af->get('password');
        $storage = $this->af->get('storage');
        $networks = $this->af->get('networks');
        $smtp = $this->af->get('smtp');
        $port = $this->af->get('port');
        $postmaster = $this->af->get('postmaster');
        $op = $this->af->get('operation');
        $host_select = array();
        $modules = $this->config->get('modules');
        $tenant = null;

        $role = $this->session->get('role');

        if ($role == 'tenant_admin') {
            $tenant = $this->session->get('tenant');
        }

        if (isset($modules['Network'])) {
            $filter = array('cn' => 'internal_network');
            if (isset($conf['system'])) {
                $filter['system'] = 'master';
            }
            if ($tenant) {
                $filter['area'] = $tenant;
            }
            $r = $auth->getObjectList('network', $filter);
            if (Ethna::isError($r)) {
                $logger->log(LOG_ERR, "$login_user failed to get the network:
 ".$r->getMessage());
                $this->ae->add(null, S_INTERNAL_ERR_MSG);

                return 'server_server';
            }
            if ($r[0]) {
                $netgroup = $r[1][0];
            } else {
                $netgroup = null;
            }
        }

        if($op === 'update') {
            //管理者パスワードファイルへの書き込み
            if($password) {
                $r = $confmgr->setPasswdFile(PASSWD, $id, $password);
                if(Ethna::isError($r)) {
                    $logger->log(LOG_ERR, $r->getMessage());
                    $this->ae->add(null, S_INTERNAL_ERR_MSG);

                    return 'server_server';
                }
            }

            $values = null;
            if (!isset($modules['SSO']) && (isset($modules['SaaS']) || isset($modules['OTP']))) {
                if (!$storage[0]) {
                    $master = 'CSV';
                } else {
                    $values = $confmgr->getXmlFile(LISMCONF, array('master'));
                    if (Ethna::isError($values)) {
                        $logger->log(LOG_ERR,$values->getMessage());
                        $this->ae->add(null, S_INTERNAL_ERR_MSG);

                        return 'server_server';
                    }
                    $master = $values[0] == 'CSV' ? 'LDAP' : $values[0];
                }
                $params['master'] = $master;
                $r = $confmgr->setXmlFile(LISMCONF, $params);
                if(Ethna::isError($r)) {
                    $logger->log(LOG_ERR,$r->getMessage());
                    $this->ae->add(null, S_INTERNAL_ERR_MSG);

                    return 'server_server';
                }
                if (system(LISMRELOAD) == "0") {
                    $logger->log(LOG_ERR, "Can't reload LISM");
                    $this->ae->add(null, C_RELOAD_ERR_MSG);

                    return 'server_server';
                }

                if (file_exists(LISMSVRCONF)) {
                    $values = $confmgr->getLismConf(LISMSVRCONF, array('basedn', 'admindn', 'adminpw'));
                    $params['bindpw'] = $values[2];
                }
            }

            if ($values && $storage[0] != 'LDAP') {
                $updated = array();
                unset($params);
                $params['uri'] = 'ldap://127.0.0.1:3890';
                $params['basedn'] = 'ou=Master,'.$values[0];
                $params['binddn'] = $values[1];
                $params['bindpw'] = $values[2];
                if (!$storage[0]) {
                    $params['userattr'] = 'uid';
                }

                if (isset($modules['SaaS'])) {
                    if (file_exists(OPENIDCONF)) {
                        $r = $confmgr->setIniFile(OPENIDCONF, $params);
                        if(Ethna::isError($r)) {
                            $logger->log(LOG_ERR,$r->getMessage());
                            $this->ae->add(null, S_INTERNAL_ERR_MSG);

                            return 'server_server';
                        }
                    }

                    if (file_exists(SAMLLDAPCONF)) {
                        $r = $confmgr->setPHPConf(SAMLLDAPCONF, $params);
                        if(Ethna::isError($r)) {
                            $logger->log(LOG_ERR,$r->getMessage());
                            $this->ae->add(null, S_INTERNAL_ERR_MSG);

                            return 'server_server';
                        }
                    }
                }

                if (isset($modules['OTP'])) {
                    $r = $confmgr->setIniFile(LOGINCONF, $params);
                    if (Ethna::isError($r)) {
                        $logger->log(LOG_ERR, $r->getMessage());
                        $this->ae->add(null, S_INTERNAL_ERR_MSG);

                        return 'server_server';
                    }
                }
            }

            if (isset($modules['Network']) && $role == 'tenant_admin') {
                $prop = array(
                    'cn' => 'internal_network',
                    'description' => NWNAME,
                    'seciossipnetworkaddress' => split(", *", $networks)
                );
                if (isset($conf['system'])) {
                    $prop['system'] = 'master';
                }
                if ($tenant) {
                    $prop['o'] = $tenant;
                    $prop['area'] = $tenant;
                }
                if ($netgroup) {
                    $netgroup = $auth->updateObject('network', null, null, $prop);
                    if (Ethna::isError($netgroup)) {
                        $logger->log(LOG_ERR, "$login_user failed to update the internal network: ".$netgroup->getMessage());
                        $this->ae->add(null, O_UPDATE_ERR_MSG);

                        return 'server_server';
                    }
                } else {
                    $netgroup = $auth->addObject('network', $prop);
                    if (Ethna::isError($netgroup)) {
                        $logger->log(LOG_ERR, "$login_user failed to add the internal network: ".$netgroup->getMessage());
                        $this->ae->add(null, O_UPDATE_ERR_MSG);

                        return 'server_server';
                    }
                }
            }

            //config.iniの一時ファイルへの書き込み
            if (!$storage[0]) {
                $params['winpasswd'] = 'off';
            }
            if ($params) {
                $r = $confmgr->setIniFile(CONFIG, $params);
                if(Ethna::isError($r)) {
                    $logger->log(LOG_ERR,$r->getMessage());
                    $this->ae->add(null, S_INTERNAL_ERR_MSG);

                    return 'server_server';
                }
            }

            if (isset($modules['Mail'])) {
                $params = array();
                if ($port) {
                    $params['smtp'] = "$smtp:$port";
                } else {
                    $params['smtp'] = $smtp;
                }
                $params['postmaster'] = $postmaster;

                $r = $confmgr->setIniFile(BASEDIR.'/conf/mail/config.ini', $params);
                if(Ethna::isError($r)) {
                    $logger->log(LOG_ERR,$r->getMessage());
                    $this->ae->add(null, S_INTERNAL_ERR_MSG);

                    return 'server_server';
                }
            }

            $this->af->setApp('message', C_UPDATE_SUCCESS_MSG);
            $logger->log(LOG_INFO, "Succeeded to update sso server config");
        } else {
            if (!isset($modules['SSO']) && (isset($modules['SaaS']) || isset($modules['OTP']))) {
                $values = $confmgr->getXmlFile(LISMCONF, array('master'));
                if (Ethna::isError($values)) {
                    $logger->log(LOG_ERR,$values->getMessage());
                    $this->ae->add(null, S_INTERNAL_ERR_MSG);

                    return 'server_server';
                }
                $this->af->set('storage', $values[0] == 'LDAP' || $values[0] == 'AD' ? 'LDAP' : null);
            }

            if (isset($modules['Network'])) {
                if ($netgroup) {
                    $networks = $netgroup->get('seciossipnetworkaddress');
                    if (is_array($networks)) {
                        $networks = join(", ", $networks);
                    }
                    $this->af->set('networks', $networks);
                }
            }

            if (isset($modules['Mail'])) {
                $params = array('smtp', 'postmaster');
                $values = $confmgr->getIniFile(BASEDIR.'/conf/mail/config.ini', $params);
                if(Ethna::isError($values)) {
                    $logger->log(LOG_ERR,$values->getMessage());
                    $this->ae->add(null, S_INTERNAL_ERR_MSG);

                    return 'server_server';
                }
                list($smtp, $port) = split(':', $values[0]);
                $this->af->set('smtp', $smtp);
                $this->af->set('port', $port);
                $this->af->set('postmaster', $values[1]);
            }
        }

        return 'server_server';
    }
}
?>
