Exemple #1
0
function gs_user_rename($username, $new_username)
{
    if (!preg_match('/^[a-z0-9\\-_.]+$/', $username)) {
        return new GsError('Username must be alphanumeric.');
    }
    $ret = gs_user_is_valid_name($new_username);
    if (isGsError($ret)) {
        return $ret;
    } elseif (!$ret) {
        return new GsError('Invalid new username.');
    }
    if ($new_username === $username) {
        //return new GsError( 'New username = old username.' );
        return true;
    }
    # connect to db
    #
    $db = gs_db_master_connect();
    if (!$db) {
        return new GsError('Could not connect to database.');
    }
    # start transaction
    #
    gs_db_start_trans($db);
    # get user_id
    #
    $user_id = (int) $db->executeGetOne('SELECT `id` FROM `users` WHERE `user`=\'' . $db->escape($username) . '\'');
    if (!$user_id) {
        gs_db_rollback_trans($db);
        return new GsError("Unknown user \"{$username}\".");
    }
    # check if new username exists
    #
    $user_id_new_test = (int) $db->executeGetOne('SELECT `id` FROM `users` WHERE `user`=\'' . $db->escape($new_username) . '\'');
    if ($user_id_new_test) {
        gs_db_rollback_trans($db);
        return new GsError("A user with username \"{$new_username}\" already exists.");
    }
    # get host
    #
    $host_id = (int) $db->executeGetOne('SELECT `host_id` FROM `users` WHERE `id`=' . $user_id);
    $host = gs_host_by_id_or_ip($host_id);
    if (isGsError($host) || !is_array($host)) {
        gs_db_rollback_trans($db);
        return new GsError('Host not found.');
    }
    # get info needed for foreign users
    #
    if ($host['is_foreign']) {
        # get user's extension and password
        $rs = $db->execute('SELECT `name`, `secret` FROM `ast_sipfriends` WHERE `_user_id`=' . $user_id);
        if (!$rs || !($r = $rs->fetchRow())) {
            gs_db_rollback_trans($db);
            return new GsError('DB error.');
        }
        $ext = $r['name'];
        $sip_pwd = $r['secret'];
        # get user info
        $rs = $db->execute('SELECT `pin`, `firstname`, `lastname`, `email` FROM `users` WHERE `id`=' . $user_id);
        if (!$rs || !($user_info = $rs->fetchRow())) {
            gs_db_rollback_trans($db);
            return new GsError('DB error.');
        }
    } else {
        $ext = null;
    }
    # update user
    #
    $ok = $db->execute('UPDATE `users` SET `user`=\'' . $db->escape($new_username) . '\' WHERE `id`=' . $user_id);
    if (!$ok) {
        @$db->execute('UPDATE `users` SET `user`=\'' . $db->escape($username) . '\' WHERE `id`=' . $user_id);
        gs_db_rollback_trans($db);
        return new GsError('Failed to rename user.');
    }
    # rename user on foreign host
    #
    if ($host['is_foreign']) {
        include_once GS_DIR . 'inc/boi-soap/boi-api.php';
        $api = gs_host_get_api($host_id);
        switch ($api) {
            case 'm01':
            case 'm02':
                if (!extension_loaded('soap')) {
                    @$db->execute('UPDATE `users` SET `user`=\'' . $db->escape($username) . '\' WHERE `id`=' . $user_id);
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to rename user on foreign host (SoapClient not available).');
                } else {
                    $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $host['id'] . ' AND `param`=\'route_prefix\'');
                    $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                    gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                    include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                    $soap_faultcode = null;
                    $ok = gs_boi_update_extension($api, $host['host'], $hp_route_prefix, $sub_ext, $new_username, $sip_pwd, $user_info['pin'], $user_info['firstname'], $user_info['lastname'], $user_info['email'], $soap_faultcode);
                    if (!$ok) {
                        @$db->execute('UPDATE `users` SET `user`=\'' . $db->escape($username) . '\' WHERE `id`=' . $user_id);
                        gs_db_rollback_trans($db);
                        return new GsError('Failed to rename user on foreign host (SOAP error).');
                    }
                }
                break;
            case '':
                # host does not provide any API
                gs_log(GS_LOG_NOTICE, 'Renaming user on foreign host ' . $host['host'] . ' without any API');
                break;
            default:
                gs_log(GS_LOG_WARNING, 'Failed to rename user on foreign host ' . $host['host'] . ' - invalid API "' . $api . '"');
                @$db->execute('UPDATE `users` SET `user`=\'' . $db->escape($username) . '\' WHERE `id`=' . $user_id);
                gs_db_rollback_trans($db);
                return new GsError('Failed to rename user on foreign host (Invalid API).');
        }
    }
    # commit transaction
    #
    if (!gs_db_commit_trans($db)) {
        @$db->execute('UPDATE `users` SET `user`=\'' . $db->escape($username) . '\' WHERE `id`=' . $user_id);
        return new GsError('Failed to rename user.');
    }
    # reboot the phone
    #
    if ($ext === null) {
        # get user's extension
        $ext = $db->executeGetOne('SELECT `name` FROM `ast_sipfriends` WHERE `_user_id`=' . $user_id);
    }
    @gs_prov_phone_checkcfg_by_ext($ext, true);
    # update fax authentication file if fax enabled
    #
    if (gs_get_conf('GS_FAX_ENABLED')) {
        $ok = gs_hylafax_authfile_sync();
        if (isGsError($ok)) {
            return new GsError($ok->getMsg());
        }
        if (!$ok) {
            return new GsError('Failed to update fax authentication file.');
        }
    }
    return true;
}
Exemple #2
0
function gs_user_change($user, $pin, $firstname, $lastname, $language, $host_id_or_ip, $force = false, $email = '', $reload = true)
{
    if (!preg_match('/^[a-z0-9\\-_.]+$/', $user)) {
        return new GsError('User must be alphanumeric.');
    }
    if (!preg_match('/^[0-9]+$/', $pin)) {
        return new GsError('PIN must be numeric.');
    }
    if (strLen($pin) < 3) {
        return new GsError('PIN too short (min. 3 digits).');
    } elseif (strLen($pin) > 10) {
        return new GsError('PIN too long (max. 10 digits).');
    }
    //if (! preg_match( '/^[a-zA-Z\d.\-\_ ]+$/', $firstname ))
    //	return new GsError( 'Invalid characters in first name.' );
    $firstname = preg_replace('/\\s+/', ' ', trim($firstname));
    //if (! preg_match( '/^[a-zA-Z\d.\-\_ ]+$/', $lastname ))
    //	return new GsError( 'Invalid characters in last name.' );
    $lastname = preg_replace('/\\s+/', ' ', trim($lastname));
    // prepare language code
    $language = substr(trim($language), 0, 2);
    if (strlen($language) != 2) {
        return new GsError('Invalid language code.');
    }
    if (!defined('GS_EMAIL_PATTERN_VALID')) {
        return new GsError('GS_EMAIL_PATTERN_VALID not defined.');
    }
    if ($email != '' && !preg_match(GS_EMAIL_PATTERN_VALID, $email)) {
        return new GsError('Invalid e-mail address.');
    }
    include_once GS_DIR . 'lib/utf8-normalize/gs_utf_normal.php';
    # connect to db
    #
    $db = gs_db_master_connect();
    if (!$db) {
        return new GsError('Could not connect to database.');
    }
    # start transaction
    #
    gs_db_start_trans($db);
    # get user_id
    #
    $user_id = (int) $db->executeGetOne('SELECT `id` FROM `users` WHERE `user`=\'' . $db->escape($user) . '\'');
    if (!$user_id) {
        gs_db_rollback_trans($db);
        return new GsError('Unknown user.');
    }
    # get old host_id
    #
    $old_host_id = (int) $db->executeGetOne('SELECT `host_id` FROM `users` WHERE `id`=' . $user_id);
    $old_host = gs_host_by_id_or_ip($old_host_id);
    if (isGsError($old_host) || !is_array($old_host)) {
        $old_host = false;
    }
    # get user's peer name (extension)
    #
    $ext = $db->executeGetOne('SELECT `name` FROM `ast_sipfriends` WHERE `_user_id`=' . $user_id);
    # check if (new) host exists
    #
    $host = gs_host_by_id_or_ip($host_id_or_ip);
    if (isGsError($host)) {
        gs_db_rollback_trans($db);
        return new GsError($host->getMsg());
    }
    if (!is_array($host)) {
        gs_db_rollback_trans($db);
        return new GsError('Unknown host.');
    }
    if ($old_host_id != $host['id'] && !$force) {
        gs_db_rollback_trans($db);
        return new GsError('Changing the host will result in loosing mailbox messages etc. and thus will not be done without force.');
    }
    /*
    # check if queue with same ext exists
    #
    $num = (int)$db->executeGetOne( 'SELECT COUNT(*) FROM `ast_queues` WHERE `name`=\''. $db->escape($ext) .'\'' );
    if ($num > 0) {
    	gs_db_rollback_trans($db);
    	return new GsError( 'A queue with that name already exists.' );
    }
    */
    # update user
    #
    $ok = $db->execute('UPDATE `users` SET `pin`=\'' . $db->escape($pin) . '\', `firstname`=\'' . $db->escape($firstname) . '\', `lastname`=\'' . $db->escape($lastname) . '\', `email`=\'' . $db->escape($email) . '\', `host_id`=' . $host['id'] . ' WHERE `id`=' . $user_id);
    if (!$ok) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to change user.');
    }
    # update sip account (including language code)
    #
    $calleridname = trim(gs_utf8_decompose_to_ascii($firstname . ' ' . $lastname));
    $ok = $db->execute('UPDATE `ast_sipfriends` SET `callerid`=CONCAT(_utf8\'' . $db->escape($calleridname) . '\', \' <\', `name`, \'>\'), `language`=\'' . $db->escape($language) . '\' WHERE `_user_id`=' . $user_id);
    if (!$ok) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to change SIP account.');
    }
    # delete stuff not used for users on foreign hosts
    #
    if ($host['is_foreign']) {
        $db->execute('DELETE FROM `clir` WHERE `user_id`=' . $user_id);
        $db->execute('DELETE FROM `dial_log` WHERE `user_id`=' . $user_id);
        $db->execute('DELETE FROM `callforwards` WHERE `user_id`=' . $user_id);
        $db->execute('DELETE FROM `pickupgroups_users` WHERE `user_id`=' . $user_id);
        $db->execute('DELETE FROM `ast_queue_members` WHERE `_user_id`=' . $user_id);
        $db->execute('DELETE FROM `vm` WHERE `user_id`=' . $user_id);
        $db->execute('DELETE FROM `ast_voicemail` WHERE `_user_id`=' . $user_id);
    }
    # update mailbox
    #
    if (!$host['is_foreign']) {
        $ok = $db->execute('UPDATE `ast_voicemail` SET `password`=\'' . $db->escape($pin) . '\', `fullname`=\'' . $db->escape($firstname . ' ' . $lastname) . '\' WHERE `_user_id`=' . $user_id);
        if (!$ok) {
            gs_db_rollback_trans($db);
            return new GsError('Failed to change mailbox.');
        }
    }
    # new host?
    #
    if ($host['id'] != $old_host_id) {
        # delete from queue members
        #
        $db->execute('DELETE FROM `ast_queue_members` WHERE `_user_id`=' . $user_id);
        # delete from pickup groups
        #
        $db->execute('DELETE FROM `pickupgroups_users` WHERE `user_id`=' . $user_id);
    }
    # get info needed for foreign hosts
    #
    if (is_array($old_host) && $old_host['is_foreign'] || $host['is_foreign']) {
        # get user's sip name and password
        $rs = $db->execute('SELECT `name`, `secret` FROM `ast_sipfriends` WHERE `_user_id`=' . $user_id);
        if (!$rs || !($r = $rs->fetchRow())) {
            gs_db_rollback_trans($db);
            return new GsError('DB error.');
        }
        $ext = $r['name'];
        $sip_pwd = $r['secret'];
    }
    # modify user on foreign host(s)
    #
    if ($host['id'] != $old_host_id) {
        # host changed. delete user on old host and add on new one
        if (is_array($old_host) && $old_host['is_foreign']) {
            include_once GS_DIR . 'inc/boi-soap/boi-api.php';
            $api = gs_host_get_api($old_host_id);
            switch ($api) {
                case 'm01':
                case 'm02':
                    //if (! class_exists('SoapClient')) {
                    if (!extension_loaded('soap')) {
                        gs_db_rollback_trans($db);
                        return new GsError('Failed to delete user on old foreign host (SoapClient not available).');
                    } else {
                        $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $old_host['id'] . ' AND `param`=\'route_prefix\'');
                        $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                        gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                        include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                        $soap_faultcode = null;
                        $ok = gs_boi_delete_extension($api, $old_host['host'], $hp_route_prefix, $sub_ext, $soap_faultcode);
                        if (!$ok) {
                            gs_db_rollback_trans($db);
                            return new GsError('Failed to delete user on old foreign host (SOAP error).');
                        }
                    }
                    break;
                case '':
                    # host does not provide any API
                    gs_log(GS_LOG_NOTICE, 'Deleting user ' . $user . ' on foreign host ' . $old_host['host'] . ' without any API');
                    break;
                default:
                    gs_log(GS_LOG_WARNING, 'Failed to delete user ' . $user . ' on foreign host ' . $old_host['host'] . ' - invalid API "' . $api . '"');
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to delete user on foreign host (Invalid API).');
            }
        }
        if ($host['is_foreign']) {
            include_once GS_DIR . 'inc/boi-soap/boi-api.php';
            $api = gs_host_get_api($host['id']);
            switch ($api) {
                case 'm01':
                case 'm02':
                    //if (! class_exists('SoapClient')) {
                    if (!extension_loaded('soap')) {
                        gs_db_rollback_trans($db);
                        return new GsError('Failed to add user on new foreign host (SoapClient not available).');
                    } else {
                        $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $host['id'] . ' AND `param`=\'route_prefix\'');
                        $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                        gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                        include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                        $soap_faultcode = null;
                        $ok = gs_boi_update_extension($api, $host['host'], $hp_route_prefix, $sub_ext, $user, $sip_pwd, $pin, $firstname, $lastname, $email, $soap_faultcode);
                        if (!$ok) {
                            gs_db_rollback_trans($db);
                            return new GsError('Failed to add user on new foreign host (SOAP error).');
                        }
                    }
                    break;
                case '':
                    # host does not provide any API
                    gs_log(GS_LOG_NOTICE, 'Adding user ' . $user . ' on foreign host ' . $host['host'] . ' without any API');
                    break;
                default:
                    gs_log(GS_LOG_WARNING, 'Failed to add user ' . $user . ' on foreign host ' . $host['host'] . ' - invalid API "' . $api . '"');
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to add user on foreign host (Invalid API).');
            }
        }
    } else {
        # host did not change
        if ($host['is_foreign']) {
            include_once GS_DIR . 'inc/boi-soap/boi-api.php';
            $api = gs_host_get_api($host['id']);
            switch ($api) {
                case 'm01':
                case 'm02':
                    //if (! class_exists('SoapClient')) {
                    if (!extension_loaded('soap')) {
                        gs_db_rollback_trans($db);
                        return new GsError('Failed to modify user on foreign host (SoapClient not available).');
                    } else {
                        $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $host['id'] . ' AND `param`=\'route_prefix\'');
                        $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                        gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                        include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                        $soap_faultcode = null;
                        $ok = gs_boi_update_extension($api, $host['host'], $hp_route_prefix, $sub_ext, $user, $sip_pwd, $pin, $firstname, $lastname, $email, $soap_faultcode);
                        if (!$ok) {
                            gs_db_rollback_trans($db);
                            return new GsError('Failed to modify user on foreign host (SOAP error).');
                        }
                    }
                    break;
                case '':
                    # host does not provide any API
                    gs_log(GS_LOG_NOTICE, 'Modifying user ' . $user . ' on foreign host ' . $host['host'] . ' without any API');
                    break;
                default:
                    gs_log(GS_LOG_WARNING, 'Failed to modify user ' . $user . ' on foreign host ' . $host['host'] . ' - invalid API "' . $api . '"');
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to modify user on foreign host (Invalid API).');
            }
        }
    }
    # commit transaction
    #
    if (!gs_db_commit_trans($db)) {
        return new GsError('Failed to modify user.');
    }
    # new host?
    #
    if ($host['id'] != $old_host_id) {
        # reload dialplan (hints!)
        #
        if (is_array($old_host) && !$old_host['is_foreign']) {
            $ok = @gs_asterisks_prune_peer($ext, array($old_host_id));
            if ($reload) {
                @gs_asterisks_reload(array($old_host_id), true);
            }
        }
        if (!$host['is_foreign']) {
            if ($reload) {
                @gs_asterisks_reload(array($host['id']), true);
            }
        }
    } else {
        $ok = @gs_asterisks_prune_peer($ext, array($host['id']));
    }
    # reboot the phone
    #
    //@ shell_exec( 'asterisk -rx \'sip notify snom-reboot '. $ext .'\' >>/dev/null' );
    @gs_prov_phone_checkcfg_by_ext($ext, true);
    # update fax authentication file if fax enabled
    #
    if (gs_get_conf('GS_FAX_ENABLED')) {
        $ok = gs_hylafax_authfile_sync();
        if (isGsError($ok)) {
            return new GsError($ok->getMsg());
        }
        if (!$ok) {
            return new GsError('Failed to update fax authentication file.');
        }
    }
    return true;
}
Exemple #3
0
function _update_users($DB, $host_id, $host, $api, &$msg)
{
    $host_id = (int) $host_id;
    $num_users_total = (int) $DB->executeGetOne('SELECT COUNT(*) FROM `users` WHERE `host_id`=' . $host_id);
    $num_users_updated = 0;
    $msg = '';
    if ($num_users_total < 1) {
        return null;
    }
    switch ($api) {
        case 'm01':
        case 'm02':
            # update all users on the host
            $hp_route_prefix = (string) $DB->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . $host_id . ' AND `param`=\'route_prefix\'');
            if (!extension_loaded('soap')) {
                $msg = 'Failed to sync users on foreign host (SoapClient not available).';
                return false;
            }
            include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
            $rs = $DB->execute('SELECT ' . '`u`.`user`, `u`.`pin`, `u`.`firstname`, `u`.`lastname`, `u`.`email`, ' . '`s`.`secret` `sip_pwd`, `s`.`name` `ext` ' . 'FROM ' . '`users` `u` JOIN ' . '`ast_sipfriends` `s` ON (`s`.`_user_id`=`u`.`id`) ' . 'WHERE `u`.`host_id`=' . $host_id);
            if ($rs->numRows() == 0) {
                return null;
            }
            $soap_errors = array();
            while ($userinfo = $rs->fetchRow()) {
                $ext = $userinfo['ext'];
                $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                $ok = gs_boi_update_extension($api, $host, $hp_route_prefix, $sub_ext, $userinfo['user'], $userinfo['sip_pwd'], $userinfo['pin'], $userinfo['firstname'], $userinfo['lastname'], $userinfo['email'], $soap_faultcode);
                if (!$ok) {
                    # SOAP error
                    if (strToUpper($soap_faultcode) === 'HTTP') {
                        # SOAP error: Could not connect to host
                        $msg = sPrintF(__('Die Benutzer auf Host %s konnten nicht aktualisiert werden! (Verbindung fehlgeschlagen.)'), htmlEnt($host) . ' (ID ' . $host_id . ')');
                        return false;
                    }
                    if (!array_key_exists($soap_faultcode, $soap_errors)) {
                        $soap_errors[$soap_faultcode] = 1;
                    } else {
                        $soap_errors[$soap_faultcode] = $soap_errors[$soap_faultcode] + 1;
                    }
                } else {
                    ++$num_users_updated;
                }
            }
            if ($num_users_updated < $num_users_total) {
                $msg = sPrintF(__('%u von %u Benutzern auf Host %s konnten nicht aktualisiert werden!'), $num_users_total - $num_users_updated, $num_users_total, htmlEnt($host) . ' (ID ' . $host_id . ')');
                if (count($soap_errors) > 0) {
                    $msg .= ' (SOAP errors: ';
                    $i = 0;
                    foreach ($soap_errors as $soap_faultcode => $num) {
                        if ($i === 0) {
                            ++$i;
                        } else {
                            $msg .= ', ';
                        }
                        $msg .= htmlEnt($soap_faultcode) . ' (' . $num . ')';
                    }
                    $msg .= ')';
                }
                return false;
            } else {
                $msg = sPrintF(__('Die Benutzer auf Host %s wurden aktualisiert.'), htmlEnt($host) . ' (ID ' . $host_id . ')');
                return true;
            }
            break;
        case '':
            # host does not provide any API
            return null;
            break;
        default:
            $msg = 'Failed to sync users on foreign host! (unknown API)';
            return false;
            # unknown API
    }
    return null;
}
function gs_prov_add_phone_get_nobody_user_id($db, $mac_addr, $phone_type, $phone_ip)
{
    $add_nobody_locally_if_foreign_failed = false;
    # hack
    $mac_addr = preg_replace('/[^0-9A-F\\-]/', '', strToUpper($mac_addr));
    @gs_db_start_trans($db);
    # find host for the new nobody user
    #
    $boi_host_id = gs_prov_new_phone_find_boi_host_id($db, $phone_ip);
    if ($boi_host_id === false) {
        @gs_db_rollback_trans($db);
        return false;
    }
    if ($boi_host_id < 1) {
        # Gemeinschaft
        switch (gs_get_conf('GS_PROV_AUTO_ADD_PHONE_HOST')) {
            case 'last':
                $host_id_sql = 'SELECT MAX(`id`) FROM `hosts` WHERE `is_foreign`=0';
                break;
            case 'random':
                $host_id_sql = 'SELECT `id` FROM `hosts` WHERE `is_foreign`=0 ORDER BY RAND() LIMIT 1';
                break;
            case 'first':
            default:
                $host_id_sql = 'SELECT MIN(`id`) FROM `hosts` WHERE `is_foreign`=0';
                break;
        }
        $host_id = (int) $db->executeGetOne($host_id_sql);
        if ($host_id < 1) {
            gs_log(GS_LOG_WARNING, 'Could not find a host for adding a nobody user');
            @gs_db_rollback_trans($db);
            return false;
        }
    } else {
        # foreign host (BOI)
        $host_id = $boi_host_id;
    }
    # add a nobody user
    #
    $new_nobody_index = (int) ((int) $db->executeGetOne('SELECT MAX(`nobody_index`) FROM `users`') + 1);
    $new_nobody_num = 0;
    $hp_route_prefix = 0;
    $soap_user_ext = 0;
    if ($boi_host_id > 0) {
        $new_nobody_num = (int) $db->executeGetOne('SELECT COUNT(`user`) FROM `users` WHERE `nobody_index` IS NOT NULL AND `host_id`=' . $boi_host_id);
        $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $boi_host_id . ' AND `param`=\'route_prefix\'');
        $username = '******' . $hp_route_prefix . '-' . str_pad($new_nobody_num, 5, '0', STR_PAD_LEFT);
    } else {
        $username = '******' . str_pad($new_nobody_index, 5, '0', STR_PAD_LEFT);
    }
    $ok = $db->execute('INSERT INTO `users` ' . '(`id`, `user`, `pin`, `firstname`, `lastname`, `honorific`, `email`, `nobody_index`, `host_id`) ' . 'VALUES ' . '(NULL, \'' . $db->escape($username) . '\', \'\', \'\', \'\', \'\', \'\', ' . $new_nobody_index . ', ' . $host_id . ')');
    if (!$ok || !($user_id = (int) $db->getLastInsertId())) {
        gs_log(GS_LOG_WARNING, 'Failed to add nobody user ' . $username . ' to database');
        @gs_db_rollback_trans($db);
        return false;
    } else {
        //gs_log( GS_LOG_DEBUG, 'Nobody user '. $username .' added to database (pending)' );
    }
    # add a SIP account:
    #
    if ($boi_host_id > 0) {
        $user_ext = $hp_route_prefix . gs_nobody_index_to_extension($new_nobody_num, true);
        $soap_user_ext = gs_nobody_index_to_extension($new_nobody_num, true);
        //$user_ext = $hp_route_prefix . $soap_user_ext;
    } else {
        $user_ext = gs_nobody_index_to_extension($new_nobody_index, false);
    }
    $sip_pwd = gs_prov_gen_sip_pwd();
    $ok = $db->execute('INSERT INTO `ast_sipfriends` ' . '(`_user_id`, `name`, `secret`, `context`, `callerid`, `setvar`) ' . 'VALUES ' . '(' . $user_id . ', \'' . $db->escape($user_ext) . '\', \'' . $db->escape($sip_pwd) . '\', \'from-internal-nobody\', _utf8\'' . $db->escape(GS_NOBODY_CID_NAME . $new_nobody_index . ' <' . $user_ext . '>') . '\', \'' . $db->escape('__user_id=' . $user_id . ';__user_name=' . $user_ext) . '\')');
    if (!$ok) {
        gs_log(GS_LOG_WARNING, 'Failed to add a nobody user');
        @gs_db_rollback_trans($db);
        return false;
    }
    # add nobody user at foreign host?
    #
    if ($boi_host_id > 0) {
        gs_log(GS_LOG_DEBUG, "Adding a nobody user at foreign host ID {$boi_host_id}");
        if (!gs_get_conf('GS_BOI_ENABLED')) {
            gs_log(GS_LOG_WARNING, 'Failed to add nobody user on foreign host (BOI not enabled)');
            @gs_db_rollback_trans($db);
            return false;
        }
        include_once GS_DIR . 'inc/boi-soap/boi-api.php';
        $api = gs_host_get_api($boi_host_id);
        switch ($api) {
            case 'm01':
            case 'm02':
                if (!extension_loaded('soap')) {
                    gs_log(GS_LOG_WARNING, 'Failed to add nobody user on foreign host (SoapClient not available)');
                    @gs_db_rollback_trans($db);
                    return false;
                }
                include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                $boi_host = $db->executeGetOne('SELECT `host` FROM `hosts` WHERE `id`=' . $host_id);
                if (!$boi_host) {
                    gs_log(GS_LOG_WARNING, 'DB error: Failed to get host');
                    @gs_db_rollback_trans($db);
                    return false;
                }
                $soap_faultcode = null;
                $ok = gs_boi_update_extension($api, $boi_host, '', $soap_user_ext, $username, $sip_pwd, '', '', '', '', $soap_faultcode);
                if (!$ok) {
                    gs_log(GS_LOG_WARNING, "Failed to add nobody user {$username} on foreign host {$boi_host} (SOAP error)");
                    if (!$add_nobody_locally_if_foreign_failed) {
                        // normal behavior
                        @gs_db_rollback_trans($db);
                        return false;
                    } else {
                        //FIXME - remove me - ugly hack
                        $host_id = 1;
                        gs_log(GS_LOG_DEBUG, "Failed to add nobody user on foreign host. Updating user {$username}, id: {$user_id} to host id {$host_id}");
                        $ok = $db->execute('UPDATE `users` SET ' . '`host_id`=' . $host_id . ' ' . 'WHERE ' . '`id`=' . $user_id);
                        if (!$ok) {
                            gs_log(GS_LOG_WARNING, "Failed to update nobody user {$username} at host id {$host_id}");
                            @gs_db_rollback_trans($db);
                            return false;
                        }
                    }
                }
                break;
            case '':
                # host does not provide any API
                gs_log(GS_LOG_NOTICE, 'Adding user ' . $username . ' on foreign host ' . $boi_host_id . ' without any API');
                break;
            default:
                gs_log(GS_LOG_WARNING, 'Failed to add user ' . $username . ' on foreign host ' . $boi_host_id . ' - invalid API "' . $api . '"');
                @gs_db_rollback_trans($db);
                return false;
        }
    }
    # add the phone - but if it already exist only update the nobody-user
    #
    $old_id = $db->executeGetOne('SELECT `id` FROM `phones` WHERE `mac_addr`=\'' . $mac_addr . '\'');
    if ($old_id) {
        $ok = $db->execute('UPDATE `phones` SET `nobody_index`=' . $new_nobody_index . ' WHERE `id`=' . $old_id);
        if (!$ok) {
            gs_log(GS_LOG_WARNING, "Failed to update nobody_index {$new_nobody_index} of phone {$mac_addr}");
            @gs_db_rollback_trans($db);
            return false;
        }
    } else {
        $ok = $db->execute('INSERT INTO `phones` ' . '(`id`, `type`, `mac_addr`, `user_id`, `nobody_index`, `added`) ' . 'VALUES ' . '(NULL, \'' . $db->escape($phone_type) . '\', \'' . $db->escape($mac_addr) . '\', ' . $user_id . ', ' . $new_nobody_index . ', ' . time() . ')');
        if (!$ok) {
            gs_log(GS_LOG_WARNING, "Failed to add new phone {$mac_addr}");
            @gs_db_rollback_trans($db);
            return false;
        }
    }
    $ok = @gs_db_commit_trans($db);
    if (!$ok) {
        gs_log(GS_LOG_WARNING, 'DB error');
        return false;
    }
    return $user_id;
}
function gs_user_add($user, $ext, $pin, $firstname, $lastname, $language, $host_id_or_ip, $email, $group_id = NULL, $reload = true)
{
    $ret = gs_user_is_valid_name($user);
    if (isGsError($ret)) {
        return $ret;
    } elseif (!$ret) {
        return new GsError('Invalid username.');
    }
    if (!preg_match('/^[1-9][0-9]{1,9}$/', $ext)) {
        return new GsError('Please use 2-10 digit extension.');
    }
    if (!preg_match('/^[0-9]+$/', $pin)) {
        return new GsError('PIN must be numeric.');
    }
    if (strLen($pin) < 3) {
        return new GsError('PIN too short (min. 3 digits).');
    } elseif (strLen($pin) > 10) {
        return new GsError('PIN too long (max. 10 digits).');
    }
    //if (! preg_match( '/^[a-zA-Z\d.\-\_ ]+$/', $firstname ))
    //	return new GsError( 'Invalid characters in first name.' );
    $firstname = preg_replace('/\\s+/', ' ', trim($firstname));
    //if (! preg_match( '/^[a-zA-Z\d.\-\_ ]+$/', $lastname ))
    //	return new GsError( 'Invalid characters in last name.' );
    $lastname = preg_replace('/\\s+/', ' ', trim($lastname));
    // prepare language code
    $language = substr(trim($language), 0, 2);
    if (strlen($language) != 2) {
        return new GsError('Invalid language code.');
    }
    if (!defined('GS_EMAIL_PATTERN_VALID')) {
        return new GsError('GS_EMAIL_PATTERN_VALID not defined.');
    }
    if ($email != '' && !preg_match(GS_EMAIL_PATTERN_VALID, $email)) {
        return new GsError('Invalid e-mail address.');
    }
    if ($group_id != null && $group_id != '' && !preg_match('/^[0-9]+$/', $group_id)) {
        return new GsError('Group ID must be numeric.');
    }
    $group_id = (int) $group_id;
    if ($group_id < 1) {
        $group_id = null;
    }
    include_once GS_DIR . 'lib/utf8-normalize/gs_utf_normal.php';
    # connect to db
    #
    $db = gs_db_master_connect();
    if (!$db) {
        return new GsError('Could not connect to database.');
    }
    # start transaction
    #
    gs_db_start_trans($db);
    # check if user exists
    #
    $num = $db->executeGetOne('SELECT COUNT(*) FROM `users` WHERE `user`=\'' . $db->escape($user) . '\'');
    if ($num > 0) {
        gs_db_rollback_trans($db);
        return new GsError('User exists.');
    }
    # check if ext exists
    #
    $num = $db->executeGetOne('SELECT COUNT(*) FROM `ast_sipfriends` WHERE `name`=\'' . $db->escape($ext) . '\'');
    if ($num > 0) {
        gs_db_rollback_trans($db);
        return new GsError('Extension exists.');
    }
    # check if queue with same ext exists
    #
    $num = (int) $db->executeGetOne('SELECT COUNT(*) FROM `ast_queues` WHERE `name`=\'' . $db->escape($ext) . '\'');
    if ($num > 0) {
        gs_db_rollback_trans($db);
        return new GsError('A queue with that name already exists.');
    }
    # check if ivr exists
    #
    $num = (int) $db->executeGetOne('SELECT COUNT(*) FROM `ivrs` WHERE `name`=\'' . $db->escape($ext) . '\'');
    if ($num > 0) {
        return new GsError('A ivr with that extension already exists.');
    }
    # check if host exists
    #
    $host = gs_host_by_id_or_ip($host_id_or_ip);
    if (isGsError($host)) {
        gs_db_rollback_trans($db);
        return new GsError($host->getMsg());
    }
    if (!is_array($host)) {
        gs_db_rollback_trans($db);
        return new GsError('Unknown host.');
    }
    # check if user group exists
    #
    if ($group_id > 0) {
        $num = $db->executeGetOne('SELECT 1 FROM `user_groups` WHERE `id`=' . (int) $group_id);
        if ($num < 1) {
            gs_db_rollback_trans($db);
            return new GsError('Unknown user group ID ' . $group_id);
        }
    }
    # add user
    #
    $ok = $db->execute('INSERT INTO `users` (`id`, `user`, `pin`, `firstname`, `lastname`, `email`, `nobody_index`, `host_id`, `group_id`) VALUES (NULL, \'' . $db->escape($user) . '\', \'' . $db->escape($pin) . '\', _utf8\'' . $db->escape($firstname) . '\', _utf8\'' . $db->escape($lastname) . '\', _utf8\'' . $db->escape($email) . '\', NULL, ' . $host['id'] . ', ' . ($group_id > 0 ? $group_id : 'NULL') . ' )');
    if (!$ok) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to add user (table users).');
    }
    # get user_id
    #
    $user_id = (int) $db->executeGetOne('SELECT `id` FROM `users` WHERE `user`=\'' . $db->escape($user) . '\'');
    if (!$user_id) {
        gs_db_rollback_trans($db);
        return new GsError('DB error.');
    }
    # add sip account
    #
    $callerid = trim(gs_utf8_decompose_to_ascii($firstname . ' ' . $lastname)) . ' <' . $ext . '>';
    $sip_pwd = rand(10000, 99999) . rand(10000, 99999);
    $ok = $db->execute('INSERT INTO `ast_sipfriends` (`_user_id`, `name`, `secret`, `callerid`, `mailbox`, `setvar`, `language`) VALUES (' . $user_id . ', \'' . $db->escape($ext) . '\', \'' . $db->escape($sip_pwd) . '\', _utf8\'' . $db->escape($callerid) . '\', \'' . $db->escape($ext) . '\', \'' . $db->escape('__user_id=' . $user_id . ';__user_name=' . $ext) . '\', \'' . $db->escape($language) . '\')');
    if (!$ok) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to add user (table ast_sipfriends).');
    }
    # add mailbox
    #
    if (!$host['is_foreign']) {
        $ok = $db->execute('INSERT INTO `ast_voicemail` (`uniqueid`, `_user_id`, `mailbox`, `password`, `email`, `fullname`) VALUES (NULL, ' . $user_id . ', \'' . $db->escape($ext) . '\', \'' . $db->escape($pin) . '\', \'\', _utf8\'' . $db->escape($firstname . ' ' . $lastname) . '\')');
        if (!$ok) {
            gs_db_rollback_trans($db);
            return new GsError('Failed to add user (table ast_voicemail).');
        }
    }
    # add mailbox (de)active entry
    #
    if (!$host['is_foreign']) {
        $ok = $db->execute('INSERT INTO `vm` (`user_id`, `internal_active`, `external_active`) VALUES (' . $user_id . ', 0, 0)');
        if (!$ok) {
            gs_db_rollback_trans($db);
            return new GsError('Failed to add user (table vm).');
        }
    }
    # add user on foreign host
    #
    if ($host['is_foreign']) {
        include_once GS_DIR . 'inc/boi-soap/boi-api.php';
        $api = gs_host_get_api($host['id']);
        switch ($api) {
            case 'm01':
            case 'm02':
                $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $host['id'] . ' AND `param`=\'route_prefix\'');
                $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                //if (! class_exists('SoapClient')) {
                if (!extension_loaded('soap')) {
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to add user on foreign host (SoapClient not available).');
                }
                include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                $soap_faultcode = null;
                $ok = gs_boi_update_extension($api, $host['host'], $hp_route_prefix, $sub_ext, $user, $sip_pwd, $pin, $firstname, $lastname, $email, $soap_faultcode);
                if (!$ok) {
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to add user on foreign host (SOAP error).');
                }
                break;
            case '':
                # host does not provide any API
                gs_log(GS_LOG_NOTICE, 'Adding user ' . $user . ' on foreign host ' . $host['host'] . ' without any API');
                break;
            default:
                gs_log(GS_LOG_WARNING, 'Failed to add user ' . $user . ' on foreign host ' . $host['host'] . ' - invalid API "' . $api . '"');
                gs_db_rollback_trans($db);
                return new GsError('Failed to add user on foreign host (Invalid API).');
        }
    }
    # commit transaction
    #
    if (!gs_db_commit_trans($db)) {
        return new GsError('Failed to add user.');
    }
    # reload dialplan (hints!)
    #
    if (!$host['is_foreign'] && $reload) {
        $ok = @gs_asterisks_reload(array($host['id']), true);
        if (isGsError($ok)) {
            return new GsError($ok->getMsg());
        }
        if (!$ok) {
            return new GsError('Failed to reload dialplan.');
        }
    }
    # update fax authentication file if fax enabled
    #
    if (gs_get_conf('GS_FAX_ENABLED')) {
        $ok = gs_hylafax_authfile_sync();
        if (isGsError($ok)) {
            return new GsError($ok->getMsg());
        }
        if (!$ok) {
            return new GsError('Failed to update fax authentication file.');
        }
    }
    return true;
}
Exemple #6
0
function gs_user_pin_set($user, $pin = '')
{
    if (!preg_match('/^[a-z0-9\\-_.]+$/', $user)) {
        return new GsError('User must be alphanumeric.');
    }
    if (!preg_match('/^[0-9]+$/', $pin)) {
        return new GsError('PIN must be numeric.');
    }
    if (strLen($pin) < 3) {
        return new GsError('PIN too short (min. 3 digits).');
    } elseif (strLen($pin) > 10) {
        return new GsError('PIN too long (max. 10 digits).');
    }
    # connect to db
    #
    $db = gs_db_master_connect();
    if (!$db) {
        return new GsError('Could not connect to database.');
    }
    # start transaction
    #
    gs_db_start_trans($db);
    # get user_id
    #
    $user_id = $db->executeGetOne('SELECT `id` FROM `users` WHERE `user`=\'' . $db->escape($user) . '\'');
    if (!$user_id) {
        gs_db_rollback_trans($db);
        return new GsError('Unknown user.');
    }
    # set PIN
    #
    $ok = $db->execute('UPDATE `users` SET `pin`=\'' . $db->escape($pin) . '\' WHERE `id`=' . $user_id);
    if (!$ok) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to set PIN.');
    }
    $ok = $db->execute('UPDATE `ast_voicemail` SET `password`=\'' . $db->escape($pin) . '\' WHERE `_user_id`=' . $user_id);
    if (!$ok) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to change PIN.');
    }
    # get host
    #
    $host_id = (int) $db->executeGetOne('SELECT `host_id` FROM `users` WHERE `id`=' . $user_id);
    if ($host_id < 1) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to change PIN.');
    }
    $host = gs_host_by_id_or_ip($host_id);
    if (isGsError($host)) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to change PIN. (' . $host->getMsg() . ')');
    }
    if (!is_array($host)) {
        gs_db_rollback_trans($db);
        return new GsError('Failed to change PIN.');
    }
    # change PIN on foreign host
    #
    if ($host['is_foreign']) {
        include_once GS_DIR . 'inc/boi-soap/boi-api.php';
        $api = gs_host_get_api($host['id']);
        switch ($api) {
            case 'm01':
            case 'm02':
                $rs = $db->execute('SELECT ' . '`u`.`firstname`, `u`.`lastname`, `u`.`email`, ' . '`s`.`secret` `sip_pwd`, `s`.`name` `ext` ' . 'FROM ' . '`users` `u` JOIN ' . '`ast_sipfriends` `s` ON (`s`.`_user_id`=`u`.`id`) ' . 'WHERE `u`.`id`=' . $user_id);
                if (!($userinfo = $rs->getRow())) {
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to get user.');
                }
                $ext = $userinfo['ext'];
                $hp_route_prefix = (string) $db->executeGetOne('SELECT `value` FROM `host_params` ' . 'WHERE `host_id`=' . (int) $host['id'] . ' AND `param`=\'route_prefix\'');
                $sub_ext = subStr($ext, 0, strLen($hp_route_prefix)) === $hp_route_prefix ? subStr($ext, strLen($hp_route_prefix)) : $ext;
                gs_log(GS_LOG_DEBUG, "Mapping ext. {$ext} to {$sub_ext} for SOAP call");
                //if (! class_exists('SoapClient')) {
                if (!extension_loaded('soap')) {
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to change PIN on foreign host (SoapClient not available).');
                }
                include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
                $soap_faultcode = null;
                $ok = gs_boi_update_extension($api, $host['host'], $hp_route_prefix, $sub_ext, $user, $userinfo['sip_pwd'], $pin, $userinfo['firstname'], $userinfo['lastname'], $userinfo['email'], $soap_faultcode);
                if (!$ok) {
                    gs_db_rollback_trans($db);
                    return new GsError('Failed to change PIN on foreign host (SOAP error).');
                }
                break;
            case '':
                # host does not provide any API
                gs_log(GS_LOG_NOTICE, 'Changing PIN of user ' . $user . ' on foreign host ' . $host['host'] . ' without any API');
                break;
            default:
                gs_log(GS_LOG_WARNING, 'Failed to change PIN of user ' . $user . ' on foreign host ' . $host['host'] . ' - invalid API "' . $api . '"');
                gs_db_rollback_trans($db);
                return new GsError('Failed to add user on foreign host (Invalid API).');
        }
    }
    # commit transaction
    #
    if (!gs_db_commit_trans($db)) {
        return new GsError('Failed to change PIN.');
    }
    # update fax authentication file if fax enabled
    #
    if (gs_get_conf('GS_FAX_ENABLED')) {
        $ok = gs_hylafax_authfile_sync();
        if (isGsError($ok)) {
            return new GsError($ok->getMsg());
        }
        if (!$ok) {
            return new GsError('Failed to update fax authentication file.');
        }
    }
    return true;
}
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
\*******************************************************************/
define('GS_VALID', true);
/// this is a parent file
require_once dirName(__FILE__) . '/../../inc/conf.php';
include_once GS_DIR . 'inc/util.php';
include_once GS_DIR . 'inc/boi-soap/boi-soap.php';
if ($argc < 2) {
    echo "Arg 1 must be the host!\n";
    exit(1);
}
$host = @$argv[1];
$nobody_index = rand(1, 9999);
$nbistr = str_pad($nobody_index, 5, '0', STR_PAD_LEFT);
$ext = '86' . $nbistr;
$user = '******' . $nbistr;
$sip_pwd = 'abcdefghijklmn' . rand(10, 99);
$pin = rand(1000, 999999);
$firstname = '';
$lastname = '';
$email = '';
$soap_faultcode = null;
$ret = gs_boi_update_extension('m01', $host, $ext, $user, $sip_pwd, $pin, $firstname, $lastname, $email, $soap_faultcode);
var_export($ret);
echo "\n";